SPI主从模式的学习总结
基于两块STM32F103C8T6,CubeIDE平台,分别配置SPI2主模式与SPI2从模式进行通信。仅使用SPI中断,未使用DMA,后续学习DMA之后再进行总结。
一、SPI主模式配置
SPI主模式配置以及使用比较简单,先看看我在CubeIDE中SPI主模式的配置:
1.在RCC中打开外部高低速的晶体/陶瓷振荡源;
2.将始终设置成最高,72MHz;
3.进行SPI主模式配置,配置内容中最重要的是时钟极性和时钟相位,注意:SPI从模式的配置要和主模式完全一致;
4.使能SPI中断;
5.配置PB12作为片选信号端口;
6.打开USART1串口,方便打印数据进行观看;
7.同样打开USART1中断;
8.进行printf()函数映射到USART1串口上;
- 在Src和Inc文件夹中添加’retarget.c‘和retarget.h’文件;
- 'syscalls.c’文件和’retarget.c’文件存在冲突,将’syscalls.c’从构建中排除;
- 在main()函数的while(1)之前需要添加两句代码,将printf()映射到USART1和开启USART1接收中断
9.使用到的变量
10.main()函数中做的三件事情:初始化完毕打印、1s周期将TxData1[8]中的数据发送出去、发送完毕打印发送和接收的数据;
需要注意的是,SPI发送和接收函数都是使用一个函数’HAL_SPI_TransmitReceive()',因为SPI数据传输的本质是主从SPI的数据存储寄存器的数据进行交换。
到此SPI的主模式配置完毕。
二、SPI从模式配置
SPI从模式比较复杂,从SPI无法主动发数据给主SPI,只能等待主SPI将片选信号使能时,主SPI给从SPI发送数据时(数据交换),从SPI才会将数据存储寄存器中的数据发送(数据交换)出去。因此从SPI可以通过出发接收中断之后,进行数据的传输。
1.与SPI主模式一样,在RCC中打开外部高低速的晶体/陶瓷振荡源;将始终设置成最高,72MHz;
2.进行SPI从模式配置,SPI从模式的配置要和主模式完全一致;
3.打开SPI中断;
4.将PB12引脚配置成SPI2_NSS;
5.和SPI主模式配置一样,打开USART1串口,方便打印数据进行观看;同样打开USART1中断;进行printf()函数映射到USART1串口上;
6.在mian()函数中放一条函数开启SPI接收中断;
7.使用到的变量
8.SPI中断回调函数做三件事:将接收中断标志置位、将要发送的数据放入SPI数据存储寄存器、接收主SPI发送来的数据;
9.main()函数做两件事:初始化完成打印、当接收中断标志置位时将它清除,并打印将要发送的数据和接收到的数据;
到此SPI的从模式配置完毕。
三、通信效果
由实际实际通信效果可以看出,SPI从机收到的数据和SPI主机发送的数据是同步的,但是SPI从机发送的数据和SPI主机接收到的数据并不同步。SPI主机第一次发送时接收到的数据是’0’,这可能是第一次发送时SPI从机并没来得及将刚放入数据存储寄存器的’8’发送出去(数据交换),而是在下次才发出去(数据交换)。
四、经验总结
在SPI主模式、从模式配置的过程中遇到了很多问题,这些问题会配置以及数据收发正确性。进行一些遇到问题的经验总结:
1.在程序中尽量少用printf()函数。printf()函数非常耗时,例如我之前在SPI从模式的接收中断中去打印接收和发送的数据,这是接收和发送的数据就会出现问题。因此我增加一个接收中断标志位,在中断中只是置位,在主循环中去打印;也正是因为printf()函数耗时长,消耗大,我才将SPI主模式发送周期改成1s,之前使用100ms时几乎都会数据错乱。
2.主SPI的时钟频率不要太快。有的设备对SPI通信频率是有限制的,我在之前产生收发数据异常时也将SPI主模式中的频率改小了,最后数据收发正常也不知是不是这个点原因,或者是多方面的原因。
3.有一个说法不知正不正确,之前数据不对是时候在一篇博客看到说SPI主模式使用第一个跳变沿采样,SPI从模式采用第二个跳变沿采样,博主说原因是SPI主模式采样快,SPI从机在接收到SPI主机时钟之后需要一点时间稳定,因此采样速度会慢一些,因此将SPI从模式采样周期设置为第二个跳变沿。这个说法不知是否正确,但是在以后的调试过程中可以尝试一下。
4.下面这两个函数,开启USART1和SPI2接收中断的函数在main()初始化的时候必须加上,这样才能进入中断。
5.HAL_SPI_TransmitReceive_IT(),之前在SPI从模式的接收中断用了此函数,但是数据一直不对,所有最后用了寄存器和HAL_SPI_Receive_IT()函数。因此对于HAL_SPI_TransmitReceive_IT()还可以多去研究尝试。
这次SPI主从模式配置之后的数据护发只是多个数据一个一个去收发的,并未直接一口气接收多个数据并进行数据解析之类的工作。但是先做好一个一个字节的数据之后再去研究报文帧的数据就比较容易了!
2022.9.9更新:例程代码下载(欢迎大家指正!)