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