误用STM32串口发送标志位 “USART_FLAG_TXE” & “USART_FLAG_TC”造成的BUG

当你使用串口发送数据时是否出现过这样的情况:
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和TXE的复位值均为1)
为什么? 因为清除TC需要:“读SR寄存器 & 写DR寄存器” 或者 “直接给TC赋值0”。上图中第一个字节只写了DR寄存器,没有读SR。如果可以再前面加入USART_ClearFlag(USARTx, uint16_t USART_FLAG_TC);
或者USART_GetFlagStatus(USART1,USART_FLAG_TC)读一下SR寄存器都可以。
解决方法:
在这里插入图片描述

2)上面介绍的特殊情况导致的发送失败

在这里插入图片描述
错误: 本来打算发送 0x30 ~ 0x39,却发现少了两个字节,这是因为上面的特殊情况,代码只将数据放到了发送缓冲区,而没有发送出去就掉电或待机了,这个时候其实最后两个字符是没有发送出去的。
结论: 当然一般情况下这种写法是准确的,特殊情况也很少发生,所以这是可取的。(我不相信那么巧合,正好发送过程中,正好停电)。

3).万无一失版本:

因为还是有很小的概率出现特殊情况的,这种方法可以避免!

在这里插入图片描述
亲测有效!
在这里插入图片描述
大总结:
有可能出现各种情况导致串口发送字符串失败,最重要的还是理解本文中的两个标志位,正确的写出函数,方法多种多样,我也是仅仅写了一点点自己的见解!希望童鞋们学习愉快!

本文全文摘抄自:https://www.codenong.com/cs105799846/
感谢大佬分享,如果作者介意,请联系本人删除,谢谢!

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-07 19:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-07 19:42:04       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-07 19:42:04       82 阅读
  4. Python语言-面向对象

    2023-12-07 19:42:04       91 阅读

热门阅读

  1. Pod 存活探针 livenessProbe

    2023-12-07 19:42:04       58 阅读
  2. sklearn 笔记:neighbors.NearestNeighbors 自定义metric

    2023-12-07 19:42:04       56 阅读
  3. 当内核有内存泄漏的时候

    2023-12-07 19:42:04       44 阅读
  4. 【Spark基础】-- 宽窄依赖

    2023-12-07 19:42:04       49 阅读
  5. 拥有一台服务器可以做些什么

    2023-12-07 19:42:04       65 阅读
  6. Spark SQL百万级数据批量读写入MySQL

    2023-12-07 19:42:04       62 阅读
  7. 什么问题适合使用卡方检验?

    2023-12-07 19:42:04       44 阅读
  8. qt 链表QList,QLinkedList的常见使用

    2023-12-07 19:42:04       59 阅读
  9. 英伟达显卡系列与架构、代表产品

    2023-12-07 19:42:04       60 阅读
  10. Ubuntu 配置打开文件限制

    2023-12-07 19:42:04       64 阅读
  11. Python批量图像处理--图片重命名、图片旋转

    2023-12-07 19:42:04       64 阅读
  12. CG 函数

    2023-12-07 19:42:04       56 阅读
  13. 解决分布式React前端在本地开发环境的跨域问题

    2023-12-07 19:42:04       60 阅读
  14. 关于业界大语言模型(LLM)开源的一些看法

    2023-12-07 19:42:04       51 阅读
  15. 供应链产品经理常用的ChatGPT通用提示词模板

    2023-12-07 19:42:04       56 阅读