SPI从机DMA通信调试总结

  • 时间:
  • 来源:互联网
  • 文章标签:

目录

1.硬件方案

2.SPI通信问题

3.DMA超时检测机制

4.半双工通信

5.从机部分代码


1.硬件方案

由于项目中单片机的串口资源不够,所以使用SPI来代替串口,通信双方分别是Hi3516EV300和STM32L051,前者作为SPI主机,后者作为SPI从机。硬件连接关系如下图所示。

SPI主从机硬件连接关系

SPI通信需要由主机发起,也就是由主机产生CLK,从机被动应答,那么当从机需要主动发送数据的时候怎么办呢?办法就是用额外的引脚来告知主机来取数据,这个引脚在上图就是NOTIFY引脚。当NOTIFY引脚被从机拉高时,主机便产生CLK,这样从机就可以把数据发送出去了。

2.SPI通信问题

SPI是一种全双工的同步的通信总线,也就是说主机在发送数据的时候也在接收数据,反之亦然,主机在接收数据时候也在发送数据,从机亦是如此。这就意味着当从机向主机发送数据的时候,主机会返回一些无用的数据,例如0xFF,从机会收到0xFF,对从机来说,这些0xFF都是垃圾数据,这也是全双工通信的一个小缺点。

SPI通信我们选择了1Mbps,但实测STM32L0使用SPI单字节接收中断时,却无法承受这么高的速率,必须在字节与字节之间加一定的延时,如果不加延时的话,STM32L0会发生SPI ORE错误,即中断在处理当前字节的时候,下一个字节已经到来额,单片机来不及处理。这个延时我们取的是1ms,实际处理一个字节应该用不了1ms,这里的1ms是保守值。

发1个字节需要1ms,这也太蛋疼了!竟然比串口还慢!这显然是无法接受的。那么有没有办法去掉这1ms呢?答案是必然的,那就是用DMA。STM32L0只是无法处理过快的中断,硬件上还是支持1Mbps的速率的,否则单字节接收都接收不了才对。在STM32的HAL库中,有对SPI外设速率的相关注解。我们配置STM32L0的Fpclk为32MHz,查表可知中断方式下最大支持的频率为2MHz,DMA方式下最大支持的频率为16MHz。

STM32HAL库对SPI速率的注解

使用DMA方式也有蛋疼的地方:

①. 接收:STM32的SPI不像UART一样有IDLE中断,STM32的UART+DMA可以实现用DMA接收不定长的数据,但是SPI不行啊!接收长度没有达到DMA指定的大小时是不会触发接收完成中断的。

②. 发送:例如从机需要发送10个字节,设置了DMA的size为10,也就意味着从机在此时只能接收10个字节的数据,如果主机发送了更多的数据,那么从机就GG了。

上面两个问题,最后分别使用了DMA超时检测机制、半双工通信方式解决。

3.DMA超时检测机制

第2章提到了STM32的SPI没有IDLE中断,硬件上不支持那我们可以用软件去实现!

通信协议上的规定的一帧数据不会超过256字节,那我们就设置DMA接收大小为256字节,这也就意味着主机发送一帧数据时从机不会产生DMA接收完成中断,但我们可以随时查询到DMA当前接收了多少个字节的数据,如果这个大小维持了一段都没有改变,那我们就可以认为数据已经接收完成了,这不就是软件实现IDLE检测机制吗?SPI IDLE机制大致的流程图如下。

SPI DMA方式IDLE机制流程图

实际使用中,软件定时器的超时时间我们设为了1ms,因为在1Mbps的速率下,1ms内理论上可传输的数据量是131Byte,这个检测频率已经远远满足需要了。

4.半双工通信

第2章提到了在全双工方式下,不方便设置DMA的大小,因为全双工方式下,发送大小和接收大小强关联了。既然如此,我们使用半双工方式不就解决问题了吗?更何况主从机同时交互数据概率还是很小的,一般都是一问一答的形式(也不是完全没有同时交互的情况)。

这里指的半双工是指软件上的半双工,实际上硬件还是全双工的。也就是说主机发送的时候,接收到的任何数据都认为是垃圾数据,直接丢弃,从机亦然。这就涉及到主从机如何知道自己处于何种状态呢?

对于主机而言,在发送数据前需要判断一下NOTIFY引脚的状态,如果引脚为高电平,就说明从机当前在发送数据,主机在接收数据,此时主机不可发送数据,需要延时等待一会儿再尝试发送。

对于从机而言,在发送数据前需要判断一下当前是否在接收数据,如果DMA已接收的数据量不为0,就说明主机在发送数据,需要延时等待一会儿再尝试发送。从机需要发送多少数据量就把DMA大小设置为多大,这样发送成功后就会触发发送完成中断。另外需要注意,只要从机没有发送数据,就应该把DMA接收大小设置为256字节(256是本项目的情况,其他项目需要根据实际情况设置),以此来保证能接收主机随时可能发来的数据。

从机判断主机是否在发送的方法,目前用的是判断DMA已接收的数据量不为0。一开始用的方法是将CS引脚设为输入,根据CS引脚是否为低电平判断主机是否在发送,但这种方式会导致接收的数据错位,看来对于从机而言,CS引脚还必须复用为SPI的CS功能呢。

软件上半双工的好处在于主机和从机都可以直接丢弃垃圾数据,不会对接收缓冲区造成影响,提高协议解析的效率;缺点在于不能同时交互数据,不过这点缺点相对于优点来说已经不值一提了。

最后实测的SPI通信波形如下,从机发送20字节,用时235uS,主机每4字节处理一下数据,所以每4字节间有点小延时;主机发送17字节的情况,用时174us。

从机发送时的波形

 

主机发送时的波形

5.从机部分代码

待补充

本文链接http://www.taodudu.cc/news/show-83116.html