CCS5.4+Proteus8的F28027实践课十、SPI

刚刚我们已经把SPI的理论知识部分讲完了,现在我们根据寄存器和时序图来写程序了。
首先,既然是SPI,肯定是复用了GPIO,我们先回顾下GPIO引脚说明:

从上面可以看到我们这次实践课需要复用GPIO16/GPIO17/GPIO18/GPIO19四个引脚。
然后我们来看下寄存器,这里我们只看总体寄存器结构,具体寄存器位大家自己下去了解,我们就不浪费章节了。

我们在上节课中提到过寄存器的初始化,不知道大家还有没有印象:
初始化SPI配置:
1、SPI SW RESET bit (SPICCR.7)清空,强制SPI处于复位状态;
2、初始化SPI的配置、模式、比特率和引脚;
3、SPI SW RESET bit (SPICCR.7)置1,将SPI从复位状态释放;
4、写数据到SPIDAT or SPITXBUF;
5、当传输完成后,也就是SPISTS.6 = 1,从SPIRXBUF读出有用数据;

看到这里,大家应该大概知道往哪个方向写了吧,来,我们先来一个简单的,不使用中断方式的回环测试,方便仿真,来一起摸索下SPI的初始化函数:

void InitSpi(void)
{
    EALLOW;
    SpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
    SpiaRegs.SPICCR.bit.SPILBK=1;     //loopback
    SpiaRegs.SPICCR.bit.SPICHAR=7;    //8 characters
    SpiaRegs.SPICTL.bit.MASTER_SLAVE=1; //master mode
    SpiaRegs.SPICTL.bit.TALK=1;         // enable transmission
    SpiaRegs.SPISTS.bit.BUFFULL_FLAG=0;
    SpiaRegs.SPISTS.bit.INT_FLAG=0;
    SpiaRegs.SPISTS.bit.OVERRUN_FLAG=0;
    SpiaRegs.SPIBRR=99;           // Baud rate初始化在一个低速的状态下
    SpiaRegs.SPIPRI.all=0x0010;
    SpiaRegs.SPICCR.bit.SPISWRESET=1;  // Enable SPI
    EDIS;
}

引脚初始化函数:

void InitSpiaGpio()
{

   EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

/* Configure SPI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

    EDIS;
}

初始化写完了,现在还剩两个最终要的函数,也就是读和写,这个可以根据时序图参考3线模式来写:
首先是写操作:

//---------------------------------------------------------------------------
// SPI_write:
//---------------------------------------------------------------------------
// This function is based on the TX BUF FULL FLAG's value
//if the value is 1,stating the a character is written to the SPI Transmit buffer SPITXBUF
//else if the value is 0,stating the shifting out of a previous character is complete
void SPI_write(unsigned int data)
{
    data=data<<8;             //transmission is right-justified
    while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG);       //the shifting out of a previous character is complete
    SpiaRegs.SPITXBUF=data;
}

因为我们没有使用中断了,所以直接判断TX BUF FULL FLAG的值,当为1时,说明还是写,为0说明已经完全写完了。
说完了写操作,那读就好理解了,直接贴程序

//---------------------------------------------------------------------------
// SPI_read:
//---------------------------------------------------------------------------
// This function is based on the INT_FLAG's value
//if the value is 1,stating a receive or transmit operation completes before the previous character has been read from the buffer
unsigned int SPI_read()
{
    unsigned int data;
    while(!SpiaRegs.SPISTS.bit.INT_FLAG);
    data=SpiaRegs.SPIRXBUF&0x00ff;
    return data;
}

好,函数都准备完成了,我们现在写程序测试下

void main(void)
{
    unsigned int temp;

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO:
// This example function is found in the DSP2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//   InitGpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2802x_DefaultIsr.c.
// This function is found in DSP2802x_PieVect.c.
   InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2802x_InitPeripherals.c
// InitPeripherals(); // Not required for this example

// Step 5. User specific code:

   InitSpiGpio();
   InitSpi();

   SPI_write(0x0055);
   temp = SPI_read();

   while(1);
}

主函数是不是非常简单,呵呵,下载调试下

成功,呵呵,真高兴,示例程序我等下马上上传到CSDN下载库和qq群。
又是一点了,洗洗睡了,周末部门去旅游,我会带上电脑,把SCI章节的理论知识先学习了,等我周末晚上回来,就马上把实践课补上。
F28027菜鸟交流qq群107691092

(0)

相关推荐

  • 船模制作——遥控模块 基于stm32和nrf24l01(固件库开发)

    目录 nrf24l01介绍 引脚图 引脚功能介绍 模式配置方法 官方宏 stm32配置 引脚映射 初始化函数 SPI模拟通信函数 nrf24l01配置函数 nrf24l01发射和接收 nrf24l01 ...

  • CCS5.4+Proteus8的F28027实践课一、延时函数控制LED流水灯

    又是十二点了,但是很兴奋,因为从这节课开始,我们将会进行F28027一系列的动手实践练习,深入了解一门技术的唯一办法就是多动手实践,多总结反思. 来来来,不扯了,直接开始了. 在正式开始写程序前,我们 ...

  • CCS5.4+Proteus8的F28027实践课二、定时器0控制LED流水灯

    刚游泳回来,看到昨晚那篇博客访问量比较高,对我是莫大的鼓励,所以马不停蹄的去找了相关的手册准备我们今天的课程. 今天我们要说的是用定时器0产生的定时中断让LED闪烁. 大家都是大部分都是工科出身,应该 ...

  • CCS5.4+Proteus8的F28027实践课三、外部中断0控制LED流水灯

    吃完回来了,跟老弟打了个电话,他正处于事业的迷茫期,希望他早点走出这个状态.好了,现在已经晚上八点过十分了,希望十点前能把外部中断这个主题讲完. 外部中断的概念我还是稍微说下吧,就是你映射的外部中断引 ...

  • CCS5.4+Proteus8的F28027实践课四、并行驱动LCD12864

    趁着时间早,晚上九点四十,我们整理下12864的驱动程序,争取也弄成一个跟TI提供的类似源文件,然后共享给大家. 既然是12864,那最重要的肯定是12864时序的解读,在大学时期,12864还玩的真 ...

  • CCS5.4+Proteus8的F28027实践课五、实验板焊接调试

    今天回来的比较晚,但还是简单的把面包板给焊接调试了下,昨天写的那个12864程序果然不行..只能等明晚再搞了.力争做到一天一更,每天学习进步一点,才不会虚的慌. 今天的主要目的是把面包板焊接出来,稍微 ...

  • CCS5.4+Proteus8的F28027实践课六、实验板焊接调试(12864部分)

    下班早早回家就是为了把昨天没做完的事情搞完,但等我把12864调完之后,好想找块豆腐撞死算了,RS引脚跳线不知道什么时候被我弄断了,我竟然一直没有检查板子,只顾着对着时序图和寄存器检查程序,哎,直接给 ...

  • CCS5.4+Proteus8的F28027实践课七、ADC

    吃完饭回来了,现在开始我们的ADC实践操作. 直奔主题我们,那就是ADC编程操作流程是怎么样的. 其实通过上节理论课的学习,大家心里都应该有了模糊的感觉,一般的步骤如下: 1.使能ADC模块时钟( P ...

  • CCS5.4+Proteus8的F28027实践课八、内置温度传感器

    上午发布的ADC解读部分访问好高,呵呵,我又受鼓舞了,再接再励,把温度传感器这部分弄完就去吃晚饭. 看了下手册,温度传感器东西还真的不多,寄存器就一个ADCCTL1.TEMPCONV,其他的操作跟刚才 ...

  • CCS5.4+Proteus8的F28027实践课九、比较器

    今天写的不顺畅,一个AD写了八个小时,然后一个温度传感器又卡了四个小时,哎,没人能一马平川,特别是搞技术,我们的目的不是走马观花式的学习,而是真正了解寄存器的操作,不要怕时间不够,就怕时间花了还吃不透 ...