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

2023-12-03 10:52

本文主要是介绍误用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/
感谢大佬分享,如果作者介意,请联系本人删除,谢谢!

这篇关于误用STM32串口发送标志位 “USART_FLAG_TXE” “USART_FLAG_TC”造成的BUG的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/449172

相关文章

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

使用Python的requests库来发送HTTP请求的操作指南

《使用Python的requests库来发送HTTP请求的操作指南》使用Python的requests库发送HTTP请求是非常简单和直观的,requests库提供了丰富的API,可以发送各种类型的HT... 目录前言1. 安装 requests 库2. 发送 GET 请求3. 发送 POST 请求4. 发送

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件