探索TXE、TC、RXNE标志位在串口通信中的轮询与中断应用

浅谈一下STM32串口中断之TXE,TC,RXNE标志位

之前做一个项目,用到了串口中断,但是对TXE、TC和RXNE标志位的作用和使用方法不是很清楚,导致在调试过程中遇到了一些问题。通过查阅相关资料和实际操作,我对这三个标志位有了更深入的了解,因此决定写这篇博客,分享我的经验和心得。如果对您有所帮助,点点关注,不迷路哦

墨小羽ovo个人主页

前言

在STM32中,串口通信是一种常用的通信方式,而串口中断是一种高效的通信方式,它可以在数据发送或接收时自动触发中断,从而实现数据的实时处理。在串口中断中,TXE、TC和RXNE是三个非常重要的标志位,它们分别表示发送数据寄存器为空、发送完成和接收数据寄存器非空。本文将简要介绍这三个标志位的作用和使用方法。

写这篇博客的原因

1.串口发送数据的时候出现丢包,调试代码调试不出来
2.我区分不出来串口中断,发送一串字符串时候,是不是每次都触发中断,还是只触发一次中断,是发送完第一个字符就触发串口发送中断,还是发送完所有字符才触发中断。

1. 串口通信代码编写流程

在STM32中,串口通信的代码编写流程如下:
    1. 配置串口引脚和时钟。
    2. 配置串口参数,如波特率、数据位、停止位等。
    3. 配置串口中断,如发送中断、接收中断等。初始化NVIC
    4. 启动串口。
    5. 在中断服务程序中处理数据发送和接收。

在这里插入图片描述

1.1 FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) 和void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)

1.第一个函数用于获取串口标志位的状态,第二个函数 用于清除标志位
2.这两个函数是轮询的方式,即不断检查标志位的状态,直到标志位为1或者超时。这种方式虽然简单,但是效率较低,因此在实际应用中,通常会使用中断的方式来处理数据发送和接收。

1.2 USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)和void USART_ITClearPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)

1.函数用于使能或禁用串口中断,

2.第二个函数是清除中断标志位的

1.3 USART_SendData(USART_TypeDef* USARTx, uint16_t Data)

函数用于向串口发送数据,其中USARTx表示串口类型,Data表示要发送的数据。函数返回值为void类型,没有返回值。

1.4 USART_ReceiveData(USART_TypeDef* USARTx)

函数用于从串口接收数据,其中USARTx表示串口类型。函数返回值为uint16_t类型,表示接收到的数据。

2.发送接收示意图

在这里插入图片描述

2.1 发送示意图

在这里插入图片描述

个人理解:
1.当要发送一个字符时,数据A放入TDR后,发送到移位寄存器后,触发TXE标志位,然后发送完成,触发TC标志位。

2. TXE标志位

TXE标志位表示发送数据寄存器为空,即可以发送数据。当发送数据寄存器为空时,TXE标志位会被置1,此时可以发送数据。在发送数据时,需要先判断TXE标志位是否为1,如果为1,则可以将数据写入发送数据寄存器,否则需要等待TXE标志位为1。

2.1 轮询方式发送-TXE标志位的使用

在发送数据时,需要先判断TXE标志位是否为1,如果为1,则可以将数据写入发送数据寄存器,否则需要等待TXE标志位为1。例如,以下代码演示了如何使用TXE标志位发送数据:
(1)发送一个字符

USART_SendData(USART1, 'A');

(2)发送两个字符(错误示范)

USART_SendData(USART1, 'A');

USART_SendData(USART1, 'B');
原因:1.USART_SendData()函数只是将数据放在TDR寄存器中,
2.还没来得及发送到移位寄存器,就又往TDR寄存器中放数据,导致数据丢失

(3)发送多个字符(正确示范)

USART_SendData (USART1,"H');
while (USART_GetFlagstatus(USART1,USART_FLAG_TXE) == RESET);USART_SendData (USART1,'K');
while (USART_GetFlagStatus ( USART1,USART_FLAG_TXE) == RESET);USART_SendData (USART1,”G');
while (USART_GetFlagstatus( USART1,USART_FLAG_TXE) == RESET);

输出运行结果:
HKG
(4)发送字符串
在这里插入图片描述

1.发送字符串时,最后加一个TC标志位的判断

2.不然,当发送最后一个字符时候,TXE标志位变为1,而此时最后一个字符只是发送到了移位寄存器,还没来得及
发送出去,所以需要等待TC标志位为1,才能关闭串口发送
,不然会导致数据丢失

2.2 中断方式发送-TXE标志位的使用

补充:1.TXE:发送寄存器空中断,使能TXE后
,当TDR发送数据寄存器为空时,会触发中断,在中断服务程序中发送数据。
2.TXE在复位后,默认为1,即默认开启发送中断。所以如果没有真正发送数据,TXE中断都会
触发,影响程序运行,所以初始化时候需要关闭TXE中断。
3. 使用TXE中断,发送字符,都是在中断服务程序中发送的。
示例程序:
void USART_SendByte(USART_TypeDef* USARTx, uint8_t *Data)
{
pDataByte = Data;
USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); //使能发送中断
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
USART_SendData(USART1, *pDataByte);
pDataByte++;
if (*pDataByte == ‘\0’)
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //发送完毕,关闭发送中断
}
}
}

3. TC标志位

TC标志位表示发送完成,即数据已经发送完毕。当数据发送完毕时,TC标志位会被置1,此时可以关闭串口发送中断,或者进行其他操作。在发送数据时,需要先判断TC标志位是否为1,如果为1,则可以关闭串口发送中断,否则需要等待TC标志位为1。
在这里插入图片描述

理解:
1.使用TC标志位,需要先读SR寄存器,再写入DR寄存器,或者是通过写入’0’来清除。

3.1 轮询方式发送-TC标志位的使用

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData (USART1,"H');
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData (USART1,"k');
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData (USART1,"G');
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

运行结果:
HKG

3.2 中断方式发送-TC标志位的使用

1. 使用TC标志位,是发送一个字节后进入中断的,后续的发送都是在中断服务函数中进行的。

2.可以在初始化时候,USART_ITConfig(USART1, USART_IT_TC, ENABLE);使能TC中断

  USART_ITConfig(USART1, USART_IT_TC, ENABLE);//Tramsimssion Complete后,才产生中断. 开TC中断必须放在这里,否则还是会丢失第一字节

  USART_Cmd(USART1, ENABLE); //使能USART1

示例程序:
1.使用TC标志位,需要先读SR寄存器,再写入DR寄存器,或者是通过写入’0’来清除。

void USART_SendByte(USART_TypeDef* USARTx, uint8_t *Data)
{
    pDataByte = Data;
   USART_ClearFlag(USARTX,USART_FLAG_TC); //清除TC标志位
  USART_SendData(USART1, *(pDataByte++) ); //必须要++,不然会把第一个字符t发送两次
    
}

void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
    {
        USART_SendData(USART1, *pDataByte++);
        if (*pDataByte == '\0')
        {
             USART_ClearFlag(USART1, USART_FLAG_TC);//不然TC一直是set, TCIE也是打开的,导致会不停进入中断.
        }
    }
}

4. RXNE标志位

在这里插入图片描述

理解:
1.当接收到一个字符时,数据A放入RDR寄存器,然后触发RXNE标志位,然后读取RDR寄存器中的数据,最后清除RXNE标志位。
补充: 当接收移位寄存器从RX引脚接收到
一个字节的数据后,数据会自动存入RDR寄存器,并触发RXNE标志位。这时候RXNE等于1,说明数据可以读出来。
2.当接收缓冲区为空时,RXNE标志位为0,此时可以等待接收数据。

3.当接收缓冲区非空时,RXNE标志位为1,此时可以读取接收缓冲区中的数据。

4.1 轮询方式接收-RXNE标志位的使用

  1. 有了TXE的经验
    2.不断轮询获取
    RXNE标志位,当RXNE为1时,读取RDR寄存器中的数据,然后清除RXNE标志位。

示例程序:

uint8_t USART ReceiveByte(USART_TypeDef USARTx)
{
while(USART_GetF1agStatus(USARTx,USART_FLAG_RXNE)==RESET);
return (uint8_tfUSART_ReceiveData(USART1) ; 
)

4.2 中断方式接收-

RXNE标志位的使用

注意:

1.初始化完串口接收中断的代码后,当接收数据时候,硬件会自动将数据放入RDR寄存器中,然后触发RXNE标志位

2. 硬件会检测到接收数据,自动跳转到中断处理函数

接收1个字节触发一次接收中断

3.RXNE(Receive Data register not empty interrupt)- 每接受到一个字节产生中断,接受寄存器不为空时,产生中断 —读寄存器DR清零,也可软件手动清零

使用方法:

1. 开启中断,初始化NVIC

NVIC结构体

NVIC_InitTypeDef NVIC_InitStructure;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

2. 在中断服务函数中,读取RDR寄存器中的数据,然后清除RXNE标志位。

3. 在中断处理函数中,读取RXNE标志位,当RXNE==1时,说明接收到数据,可以读出数据了

void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
    uint16_t Data = USART_ReceiveData(USART1);
    // 处理接收到的数据
    USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    //可以把接收的数据再打印出来
    USART_SendData(USART1, Data);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
}

参考资料

海创电子-STM32F103入门篇,阶段-阶段二

STM32串口通信
keysking串口原理与中断模式收发

总结

TXE、TC和RXNE等标志位在串口通信中扮演着至关重要的角色,它们的状态直接决定了数据的发送和接收过程。通过深入了解轮询和中断两种模式的工作原理和应用场景,我们可以更加灵活地选择适合自己项目的通信方式,从而实现更高效、更可靠的串口通信。希望本教程能够对大家在物联网开发过程中有所帮助。最后呢,在编写博客的过程中,我尽量保持内容的准确性和完整性,但也难免会有疏漏或错误之处。欢迎各位读者指出其中的问题,帮助我不断进步。谢谢大家的阅读,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/783092.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python酷库之旅-第三方库Pandas(010)

目录 一、用法精讲 22、pandas.read_hdf函数 22-1、语法 22-2、参数 22-3、功能 22-4、返回值 22-5、说明 22-6、用法 22-6-1、数据准备 22-6-2、代码示例 22-6-3、结果输出 23、pandas.HDFStore.put方法 23-1、语法 23-2、参数 23-3、功能 23-4、返回值 23-5…

【数据分析】Pandas_DataFrame读写详解:案例解析(第24天)

系列文章目录 一、 读写文件数据 二、df查询数据操作 三、df增加列操作 四、df删除行列操作 五、df数据去重操作 六、df数据修改操作 文章目录 系列文章目录前言一、 读写文件数据1.1 读写excel文件1.2 读写csv文件1.3 读写mysql数据库 二、df查询数据操作2.1 查询df子集基本方…

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片

2.5 C#视觉程序开发实例1----CamManager实现模拟相机采集图片 1 目标效果视频 CamManager 2 CamManager读取本地文件时序 3 BD_Vision_Utility添加代码 3.0 导入链接库 BD_OperatorSets.dllSystem.Windows.Forms.dllOpencvSharp 3.1 导入VisionParam中创建的文件Util_FileO…

乡村振兴指数与其30个原始变量数据(Shp/Dta/Excel格式,2000-2022年)

数据简介:这份数据是我国各地级市乡村振兴指数与其30各原始变量数据并对其进行地图可视化表达。城镇化是当今中国社会经济发展的必由之路。当前我国城镇化处于发展的关键时期,但城镇化发展的加快却是一把双刃剑,为何要如此形容呢?因为当前城…

【04】微服务通信组件Feign

1、项目中接口的调用方式 1.1 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包,并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 URLConnectio…

科研绘图系列:R语言径向柱状图(Radial Bar Chart)

介绍 径向柱状图(Radial Bar Chart),又称为雷达图或蜘蛛网图(Spider Chart),是一种在极坐标系中绘制的柱状图。这种图表的特点是将数据点沿着一个或多个从中心向外延伸的轴来展示,这些轴通常围绕着一个中心点均匀分布。 特点: 极坐标系统:数据点不是在直角坐标系中展…

AI时代还需要产品经理吗?需要什么样的?

在人工智能技术迅速发展的今天,我们不禁要思考,产品经理这个角色是否仍然重要?AI时代是否还需要他们? 很明确的说,需要!为什么呢? 首先,我们必须认识到,AI虽然具有强大…

如何理解李彦宏说的“不要卷模型,要卷应用”

如何理解李彦宏说的“不要卷模型,要卷应用” “大家不要卷模型,要卷应用”这句话的意思是,呼吁行业不要把过多的精力和资源投入到模型的研发竞争中,而是应该更加注重基于模型的应用开发。 李彦宏提出这一观点的原因主要有以下几点…

容联云发布容犀大模型应用,重塑企业“营销服”|WAIC 2024

7月6日,在2024世界人工智能大会上,容联云成功举办主题为“数智聚合 产业向上”的生成式应用与大模型商业化实践论坛。 论坛上,容联云发布了容犀智能大模型应用升级,该系列应用包括容犀Agent Copilot、容犀Knowledge Copilot、容犀…

PHP星座微信小程序系统源码

🌟每日星运,尽在掌握!星座微信小程序,你的专属星空指南✨ 🌈 一、每日运势,精准推送 想知道今天的你运势如何?星座微信小程序来告诉你!🔮 每天醒来,打开小程…

排座椅【详细代码题解】

[NOIP2008 普及组] 排座椅 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的 D D D 对同学上课时…

(二)前端javascript中的数据结构之栈

栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。 栈是限定仅在表的一端进行插入和删除操作…

CnosDB:深入理解时序数据修复函数

CnosDB是一个专注于时序数据处理的数据库。CnosDB针对时序数据的特点设计并实现了三个强大的数据修复函数: timestamp_repair – 对时间戳列进行有效修复,支持插入、删除、不变等操作。value_repair – 对值列进行智能修复,根据时间戳间隔和…

【学习笔记】网络设备(华为交换机)基础知识2——常用设备管理命令

一、前期准备 提示:下面所有学习内容都是基于以下条件完成的 条件1.已经可以正常访问交换机的命令行接口 Console口本地访问教程参考 ① :使用第三方工具(secureCRT软件)通过console口本地访问访问交换机的详细操作过程 Telnet访…

静态路由配置注意事项及黑洞路由的使用

静态路由 1 . 定义 从管理员处学习到的数据转发路径,就称为静态路由。 2 . 路由表 Proto :协议( Protocol ) Direct — 直连链路Static — 静态路由RIP 、OSPF 等 — 动态路由 Pre : 优先级( Preference &#x…

防爆手机终端安全管理平台

防爆手机终端安全管理平台能够满足国家能源、化工企业对安全生产信息化运行需求,能够快速搭建起高效、快捷的移动终端管理平台,提高企业安全生产管理水平,保证企业的安全运行和可持续发展。#防爆手机 #终端安全 #移动安全 能源、化工等生产单…

windows机器免密登录linux主机

1. 正常连接需要输入密码 ssh root1.1.1.1 2. 在Windows上生成SSH密钥对(如果你还没有的话): ssh-keygen 3. scp将id_rsa.pub传输到对应的主机 4.对应机器上查看 5.从windows上免密登录

[数仓]四、离线数仓(Hive数仓系统-续)

第8章 数仓搭建-DWT层 8.1 访客主题 1)建表语句 DROP TABLE IF EXISTS dwt_visitor_topic; CREATE EXTERNAL TABLE dwt_visitor_topic (`mid_id` STRING COMMENT 设备id,`brand` STRING COMMENT 手机品牌,`model` STRING COMMENT 手机型号,`channel` ARRAY<STRING> C…

Vue笔记11-Composition API的优势

Options API存在的问题 使用传统Options API中&#xff0c;新增或者修改一个需求&#xff0c;就需要分别在data&#xff0c;methods&#xff0c;computed里修改&#xff0c;而这些选项分布在代码的各个地方&#xff0c;中间还穿插着其他Optional API&#xff0c;如果代码量上来…

AI自动生成PPT怎么用?看完这篇文章你就知道啦

小暑&#xff0c;作为夏季的第五个节气&#xff0c;标志着炎炎夏日的正式到来。在这个时节&#xff0c;阳光明媚&#xff0c;万物生长&#xff0c;人们的心情也随着气温的升高而变得热烈。 然而&#xff0c;对于许多职场人士来说&#xff0c;小暑的到来也意味着需要准备各种汇报…