SPI外设简介
8位数据帧:即一次向DR寄存器当中发送8个Bit的数据
16位数据帧:即一次可以向DR寄存器发送16Bit的数据,也就是两个字节的数据,当然这两个字节也是分开来发送的。
时钟频率:一个SCK时钟交换一个Bit,所以时钟频率一般体现的是传输速度,单位是Hz或者bit/s。在这里的时钟频率就是fPCLK/分频系数,PCLK(Peripheral Clock)即外设时钟。APB2的外设时钟为72MHz,APB1的外设时钟为36MHz。SPI1挂载在了APB2,SPI2挂载在了APB1。所以同样的配置SPI1的频率要比SPI2大一倍。
多主机模型、主或从操作:我们学习上目前先只需要进行了解SPI做主机的情况就可以了。
可精简为半双工/单工通信:这些是为了照顾特殊情况而设定的,了解即可
支持DMA:可以让DMA来为我们自动搬运数据。
兼容I2S协议:I2S协议是一种数字音频信号传输的专用协议,应用于
SPI硬件框图
我们可以将这整张图分为两个部分:第一个部分就是左上角,即数据寄存器和移位寄存器打配合的过程,类似于串口、I2C那里的设计思路,是为了实现连续的数据流,一个个数据前仆后继的一个效果。
剩下的那一个部分就是一些控制逻辑,寄存器的哪些位控制哪些部分,会产生哪些效果,可以通过手册寄存器的描述来了解。
第一部分:MOSI和MISO是交叉的,这里是用来主从模式的转换的,如上所述,SPI可以做主机也可以做从机。stm32作主机上面的交叉就不会用到,如果stm32做从机的话,那么MOSI会变为SI从机输入,走输入移位寄存器的那一条路径,相应的,MISO变为SO从机输出将会走输出的那一条路。当然接收缓冲区实际上就是RDR数据寄存器,发送数据寄存器实际上就是TDR数据寄存器,这两个都是数据寄存器DR,TDR和RDR占用同一个地址和串口一样。当我们发送数据时数据从TDR转移到移位寄存器的时候会只一个状态寄存器TXE为1,表示发送数据寄存器为空,当移位寄存器移位完成之后,接收也就完成了,这时移位寄存器的数据会转入到接收缓冲区RDR,这个时刻会置状态寄存器的RXNE为1,表示接收寄存器非空,当检查到RXNE为1的时候要尽快地将数据寄存器当中地数据读出来,在下一个数据到来之前读出RDR就可以实现连续接收了。如果没有及时读出,那么下一个数据会覆盖掉这个数据,就不能够实现连续地数据流了。
第二部分:波特率发生器,他就是用来产生SCK时钟的,其内部就是一个分频器,总线的时钟经过分频之后就会输出到SCK的引脚。在右边的SPI_CR1寄存器的BR2、BR1、BR0用来控制分频系数。LSB FIRST决定高位先行还是低位先行。SPE时SPI的使能,也就是SPI_Cmd函数配置的位。MSTR配置主从模式,1位主模式,0为从模式。CPOL和CPHA用来选择SPI的四种模式。上面SPI_SR寄存器中TXE表示发送寄存器空,RXNE表示接收寄存器非空,当发送接收数据的时候需要关注这两位。再上面的SPI_CR2寄存器就是一些使能位,由中断使能DMA使能等。在整张图的左下角有一个NSS就是SS从机选择前面的N表示低电平有效,但是与我们平时解除的SS并不相同,这里的NSS时配合前面的多主机模型,所以整个NSS我们不会用到,我们使用的SS引脚只需要使用GPIO口来模拟就可以了,因为SS引脚比较简单,只需要高低电平就可以了,而且多从机的情况下,SS还会有多个。
SPI基本结构(初始化部分)
这里的数据控制器可以看作是一个管理员控制着所有电路的运行,SS引脚我们选择使用GPIO来进行模拟,模拟式一主多从模式下GPIO口来模拟是最佳选择
运行控制部分
该模式过程非常的复杂,也并不容易进行封装,所以在实际过程中如果对性能的要求并没有极致的追求,我们更倾向于使用下面的传输方式。
输出的流程和现象
这个时序图是按照SPI模式3来进行的,下降沿移出,上升沿移入,输出的流程是低位先行的模式,但是一般的SPI使用高位先行的模式使用的较多。这个busy是当有数据传输时busy置1。
输入的流程和现象
MISO\MOSI的输入数据、RXNE接收数据寄存器非空标志、接收缓存器读出SPI_DR(RDR)。在读出RDR数据的时候要及时否则会被下一个数据覆盖掉。
连续数据流对于软件的配合要求较高,在每个标志位产生之后,数据都要及时的处理,配合的好时钟可以连续不间断地的产生,每个字节之间没有任何的空隙,传输效率是最高的。
非连续传输的好处就是,容易封装,好理解,好用,但是会损失一点性能,在这里只画出了发送部分的波形。
在该时序当中配置的还是SPI模式3。这里与连续传输的区别就是当TXE置1的时候我不会立即就将数据移入到TDR而是一直等待,等待一个字节时序结束之后,RXNE会置1,当RXNE置1之后我们先将我们的数据读出来,之后再写入下一个字节的数据即 : 软件等待TXE置1,但是较晚写入数据。总结一下步骤就是:第一步等待TXE置1,第二步写入发送的数据到TDR,第三步等待RXNE为1,第四步读取RDR接收的数据,之后一直重复着四步。
缺点就是在SCK频率非常高的时候等待数据的间隙就会拖后腿比较严重了,影响数据传输的效率。如果想要提高效率可以选择使用主模式全双工连续传输,或者DMA转运来提高效率