DSP相关笔记_7:LaunchXL-F28379D的简单教程系列(五)SPI简单使用_1
注:
1)这是本人关于Ti的C2000系列的学习笔记,所用工具有官方的开发软件CCS10.3.1版本,帮助文库以及函数库软件controlSUITE。硬件部分LaunchXL-F28379D和逻辑分析仪一台。
2)需要之前的LAUNCHXL教程的,请各位自己查找这里就不占位置了
这里上一下外围的引脚图,它的具体实现的外设需要查表

正文:
询问了看我博客的小伙伴今天就来给大家,扯扯LaunchPad-F28379D的SPI简单使用,不要觉得low,简单使用只是为了学习期间的将犯错的范围变小;而不是以来就是超频时钟+SPI高速模式+DMA通道+中断服务,到时候犯错也不知道错在哪里。
这篇文章的目标:熟悉最简单的SPI硬件架构,通过寄存器和部分函数库的方式完成对SPI配置与使用,做到主机模式向外发送数据。
首先做点简单的SPI科普:这里以类比SCI为例,SCI发送数据只需要TX与RX,TX只能是发,而RX只能是收,并且双方是一对一的关系,而SPI是一种高速数据通信总线,因此就不会是一对一,就需要有一个信号知道向谁发数据也就是线选CS,当选项选择了通信的对象之后短时间看起来就是一对一通信了,那么就会有发送、接收的数据线分别是SOMI与SIMO(也可以写成MISO和MOSI),而SPI这种通信方式是有主机从机之分,其中只有主机才能产生时钟信号,而从机通过主机产生的时钟信号才能正常收发,因此就会有一根时钟线CLK。这里只是简单介绍一下,因为我不想网上随便抄点东西写上去没意思,虽然可能说得不好或者错误,不如直接说说自己理解提供一种观点。如果想具体了解可以自己百度或者看一下其他博主写的文章。
注:SOMI:从机模式下发送,主机模式下接收。SIMO:从机模式下接收,主机模式下发送。
现在,老规矩上结构图:
其实可能第一次一时半会看不懂,但是其实这个有很多我们都不用到,在这篇文章中,比如我们来一次删减。
这篇文章用到就是上面这张图,没有太多冗余的东西了。因为也不会涉及中断、FIFO,因此我们只会用到这点东西。
在SPI通信的过程需要注意的地方有:数据格式,它有四种,是由CLKPOLARTI和CLK_PHASE决定的,如下图:
会发现看着很没用意思,它直观表达的就是根据时钟信号来判决数据的电平,而四种格式就是在不同位置对数据进行电平判断,
这图就很直观,这图我随便找到的哈哈哈,主要是有个概念,由于我们这会只是简单使用也就是说如果是两个机器通信那么它们的数据格式必须一致,但现实往往因为各种因素还有可能不一致都能实现。
然后还需要注意的就是传输的速率SPIBRR,也就是波特率,在非高数模式下,且不超频LaunchPad最大12.5Mhz,最后就是数据的长度SPICHAR一般就是16位和8位用得多。
所以很简单就没了,然后就是和以前一样的GPIO复用,官方例子给的SPIA的寄存器版,那我给一个SPIB的函数库版。
先找的我们的引脚,复用的表图如下:
对应具体引脚连上逻分,因为只是作为主机发送所以我们也只是通过逻分(已经把逻分解码格式与LaunchPad对应)看一下就行了。
首先GPIO初始化函数:
void InitSpibGpio2(void)//函数库版
{
//SPIB_SIMO
GPIO_SetupPinOptions(63,GPIO_OUTPUT,GPIO_ASYNC||GPIO_PULLUP);
GPIO_SetupPinMux(63,GPIO_MUX_CPU1,15);
//SPIB_SOMI
GPIO_SetupPinOptions(64,GPIO_INPUT,GPIO_ASYNC||GPIO_PULLUP);
GPIO_SetupPinMux(64,GPIO_MUX_CPU1,15);
//SPIB_CLK
GPIO_SetupPinOptions(65,GPIO_OUTPUT,GPIO_ASYNC||GPIO_PULLUP);
GPIO_SetupPinMux(65,GPIO_MUX_CPU1,15);
//SPIB_CS
GPIO_SetupPinOptions(66,GPIO_OUTPUT,GPIO_ASYNC||GPIO_PULLUP);
GPIO_SetupPinMux(66,GPIO_MUX_CPU1,15);
}
寄存器版大家可以根据官方给的SPIA的GPIO函数改就行了。
其次就是SPIB初始化函数:
void InitSpib(void)
{
//初始化需要将SPISWRESET设为0
SpibRegs.SPICCR.bit.SPISWRESET = 0;
//数据格式1
SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
//数据长度
SpibRegs.SPICCR.bit.SPICHAR = (7-1);
SpibRegs.SPICCR.bit.SPILBK = 0;
//主机模式
SpibRegs.SPICTL.bit.MASTER_SLAVE = 1;
//开启传输
SpibRegs.SPICTL.bit.TALK = 1;
//数据格式2
SpibRegs.SPICTL.bit.CLK_PHASE = 0;
//不启动中断
SpibRegs.SPICTL.bit.SPIINTENA = 0;
//传输速率
//其中500E3代表实际速度500Khz
#define SPI_BRR ((200E6 / 4) / 500E3) - 1
SpibRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;
SpibRegs.SPIPRI.bit.FREE = 1;
//初始化结束需要将SPISWRESET设为1
SpibRegs.SPICCR.bit.SPISWRESET = 1;
}
传输函数:
void spiB_xmit(Uint16 a)
{
SpibRegs.SPITXBUF = a;
}
主函数部分
void main(void)
{
Uint16 sdata; // send data
//老规矩下面一啪啦
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
InitSpibGpio2();
InitSpib();
sdata = 0xaa;
for(;;)
{
spi_xmit(sdata);
}
}
结果如下:
这章大概内容就这样,有一些细节像代码中的 SpibRegs.SPICCR.bit.SPILBK = 0; SpibRegs.SPIPRI.bit.FREE = 1;这些没有解释,大家可以去自己看一下寄存器的说明就知道了。