【嵌入式】STM32实现SPI双机通信的一些细节(3)问题汇总
Q1:从机移位寄存器已全部为主机数据时,是否需要主机时钟信号驱动来将数据移送至接收缓冲区?
背景
主机:初始化时只使能接收中断,需要被发送的数据准备好后,使能发送中断,立即发送;
从机:初始化时使能发送、接收中断,此时会立刻触发一次发送中断,在发送中断中执行 SPI_I2S_SendData(User_SPI, SPI_Slave.response);按照我的理解,从机的时钟由主机控制,因此虽然执行了这个函数,也只是将数据放入发送缓冲区等待主机发送;
主要流程:
- 主机首先执行帧创建函数,将需要发送的数据准备好;
- 调用发送函数,实际上就是使能发送中断;
- 发送中断被立刻触发,将帧数据发送出去,从机响应;
问题描述
当从机的移位寄存器已经全部为主机的数据时,是否需要主机的时钟信号驱动移位寄存器将数据移送至接收缓冲区?
为了调试程序,我在主机发送中断里的SPI_I2S_SendData处打了一个断点,当主机发出第一个字节时会再次触发该中断,但此时并没有触发从机的接收中断。
啊!!!!!!我傻了。昨天还反复告诉自己发送中断是在数据从发送缓冲区移入移位寄存器时触发,这触发的时候移位寄存器还没动呐!当然不会触发从机的中断啊!又是一次在写博客的时候发现了问题,看来以后真得坚持总结。回过头来,想了一下自己刚刚提的问题,移位寄存器移出至接收缓冲区需要主机的SCLK驱动么?应该是不需要的吧?当完成第一个字节的数据交换后,
从上图可以看到,在主从机交换数据到当前字节的最后一位时,RXNE标志位在SCLK下降沿到来之前就被置位了,按照我自己的理解是,这代表着最后一位数据一交换就会自动将数据移至接收缓冲区并触发中断,哪怕此时SCLK的下降沿没有来。这个目前看也无法设计一个比较好的方案验证它。
Q2:接收中断与下一个发送中断
背景
SPI全双工通信本质上是数据的交换,例如:主机在向从机写数据的同时,也会读取从机的数据,这就要求从机本身要发送相应的数据给主机。何不利用这一个字节做些事情呢?这是我设计双机通信的时候考虑的一个内容。
还是以主机向从机写数据为例(发送一个完整的数据帧,其中包含帧信息以及实际需写的数据):从机接收主机的帧数据进行解包阶段返回给从机FEED字节,当接收到最后一个字节即校验和后,如果当前帧有效,返回ACK字节,无效则返回FAIL字节。这三个字节具体是什么内容是完全根据自己的想法设计的,选择几个不太容易遇到的字节即可例如0XFE,0XEE等等。
重点:
主机和从机的首个待发送字节一旦放入移位寄存器进行交换,就会触发SPI发送中断,从而将下一个字节放入发送缓冲区;当数据交换完成后再触发首个字节的接收中断。如下图:
(这里有一个我的假设,6中的下一轮发送中断一定在5中的接收中断之后触发,这个需要验证一下才能知道,因为它们是属于同一个中断,所以后触发的会等到前一个执行完成后才会执行后一个中断。这意味着什么?意味着我可以在接收中断中修改从机的参数,进而影响从机下一个发送中断中所要返回的响应字节 它的重要性在于,可用来设计从机接收到主机的完整帧后的响应机制。如下图(手写更方便……)
从上面手写的示意图中可以看到一个非常重要的机制:主机的发送中断中,将SUM放入发