究其原因,是复位并配置好串口后,串口收到的第一个字节有可能不是一帧(18个字节)中的第一个字节,而DMA只管18个字节中断一次,所以就会出错。出错的概率大约为2/14,14%。
解决的方法就是让串口接收到的第一个字节是一帧中的第一个字节,可以算好时间后让接收机和STM32同时上电,保证接收数据正确。但在调试过程中,难免会经常复位,所以最好能在代码里面解决这个问题。
由于Dbus的数据中不包含帧头或帧尾之类的标识信息,所以不能通过识别标识信息的方法来解决这个问题。笔者解决这个问题的思路大致为:首先开启串口的接收中断,当串口收到第一个字节的时候进入中断服务函数,在中断服务函数里面重置串口(重置后不会再进入串口接收中断),延时3ms,延时结束的时候肯定就是在两帧信息的间隔里面,然后再配置并开启DMA,这样DMA传输的第一个字节必然就是一帧的首字节。经笔者的测试,这种方法效果良好: