最近几天的电子设计中发现了一些从未遇到的问题。这次做的是无线通信相关的,方案上想采取的是利用两块STM32的串口进行通信,只不过中间的线改成了天线。由于硬件电路不是我设计的,所以也不知道存在什么问题。在他们没提供完整的硬件电路的时候,我采取了两单片机串口直连的方式进行调试,这时出现了一些奇怪的问题。这次直接使用了正点原子的串口接收协议,而发送函数直接采用ST标准库所提供的函数
for (t = 0; t < 6; t++) { USART_SendData(USART1, send[t]); //向串口1发送数据 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET) ; //等待发送结束 }
这里的send[]是我自己定义的符合原子接收协议数据帧,一帧6个字节。
经过反复的测试,我发现在我每次重启后发送第一帧数据时,都会出现错误,由于手边有个CH340,所以顺手把它的RX端接到发送端的TX口上,通过电脑的串口查看了收到的信息,发现第一帧的第一个字节的数据丢失了。在查找STM32的参考手册的串口部分后发现了里面注明了TE位被激活后将发送一个空闲帧。由于发送完成后USART_SR寄存器的TC位会被硬件置1,由软件序列清除该位(先读USART_SR,然后写入USART_DR)。TC 位也可以通过写入0来清零。所以其实按原来的代码第一帧数据没有发送出去,可以在前面加如下语句即可清除TC位。
USART_ClearFlag(USART1, USART_FLAG_TC);
这样问题就算解决了,拔掉CH340的线,继续两机通信,结果问题仍然存在!!但是一旦插上CH340后,接收端就不抽风了,这样就不能用电脑串口直接观察。因此采取了Keil的硬件调试功能直接查看接收端存储接收信息的数组,发现第一条信息前会有一大堆的0。尝试在串口初始化和发送第一条信息之间延时,发现0会越来越多,找队友讨论了一波,我怀疑是硬件电路上的问题,他偏说是我软件问题!互撕后他表示发现不了问题,我在网上查找了一些帖子后发现有网友说上拉电阻能解决,我尝试了一下把接收端RX拉到3.3V,结果奇迹粗线了!!第一帧数据前只剩下了1个0。结合前面在手册中找到的注意事项,想必这就是那一帧空闲帧。但是为什么接CH340时就没有这一帧呢,是在哪里被处理掉了吗。机智的yellowko用电压表测了CH340的TX和RX脚电压,嘿嘿嘿,居然都是5V。那么把RX脚上拉到5V,问题成功解决!!
总结
本次遇到STM32串口直接通信第一帧数据错误的解决方案
1.初始化串口后第一次发信息时要先把USART_SR寄存器的TC位清零,
2.将接收端RX脚上拉到5V
本作品由yellowko采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。