当你使用串口发送数据时是否出现这样的情况:
1.发送时第一个字节丢失。
2.发送时出现莫名的字节丢失。
3.各种情况字节丢失。
没错,我都遇到过,哈哈哈,
1.先了解一下串口发送的流程图(手动描绘,):
可以假象USART_FLAG_TXE是"弹仓",USART_FLAG_TC是"弹膛",对应"数据缓冲区"和"移位寄存器"!
数据缓冲区为空时:USART_FLAG_TXE=1
数据缓冲区为"空"并且"移位寄存器也发送数据到TX信号"后":USART_FLAG_TC=1
2.那么有必要更深入了解一下 “USART_FLAG_TXE” & “USART_FLAG_TC”:
USART_FLAG_TXE:表示数据缓冲区是否为空,为空时置1,表示可以写数据到数据缓冲区,有可能数据没有发送完。
USART_FLAG_TC:表示数据缓冲区的数据发送是否完成。如果最后一次发送到数据缓冲区的数据完成了从移位寄存器到
信号线TX时,才置1,表示数据发送完成,也就是说,这个标志位真正表示数据发送完成。
3.发送时的特殊情况:
1).发送字符串“过程中“,主机掉电
2).发送字符串“过程中“,从机掉电
2).发送字符串“过程中“,进入待机或停机
总结:这几种特殊情况都有可能使发送失败!那么如何避免呢?
4.各种案例
1)错误案例
看一下运行结果哪错了:
出现了错误:第一个字节丢失!
**原因:**发送第一个字节时,没有将TC标志位置0,跳过第一个字节,后面的字节又以非常迅猛的速度覆盖了之前的字节。
为什么?
因为清除TC需要:1.读SR寄存器 & 写DR寄存器 ;或者 2.直接给TC赋值0;上图中第一个字节只写了DR寄存器,没有读SR。如果可以再前面加入USART_ClearFlag(USARTx, uint16_t USART_FLAG_TC);
或者USART_GetFlagStatus(USART1,USART_FLAG_TC)读一下SR寄存器都可以。
解决方法:
2)上面介绍的特殊情况导致的发送失败
**错误:**本来打算发送 0x30 ~ 0x39,却发现少了两个字节,这是因为上面的特殊情况,代码只将数据放到了发送缓冲区,而没有发送出去就掉电或待机了,这个时候其实最后两个字符是没有发送出去的。
结论:当然一般情况下这种写法是准确的,特殊情况也很少发生,所以这是可取的。(我不相信那么巧合,正好发送过程中,正好停电,)
3).万无一失版本:
因为还是有很小的概率出现特殊情况的,这种方法可以避免!
亲测有效!
大总结:有可能出现各种情况导致串口发送字符串失败,最重要的还是理解本文中的两个标志位,正确的写出函数,方法多种多样,我也是仅仅写了一点点自己的见解!希望童鞋们学习愉快!