stm32F103C8T6标准库串口接收之空闲中断接收不定长数据4

发布时间:2026/10/1 8:01:38

stm32F103C8T6标准库串口接收之空闲中断接收不定长数据4 这里写目录标题1.问题描述举个例子2.开启空闲中断3.空闲中断代码4.实验现象1.问题描述在上一节中通过上位机发送数据以回车结束本章节学习一种特殊的结尾方式——空闲中断空闲中断串口检测到「一帧数据传输完毕总线上持续一段时间没有新字节」就触发空闲中断。空闲中断不是只要没数据就一直触发。是接收完一串连续字节之后总线空闲一段时间触发一次中断代表这一整包接收完成。举个例子上位机一次性发送ABC123发完之后不再发任何字符。收到 A、B、C、1、2、3依次进入接收中断存入数组全部 6 个字符发完串口线上安静一段时间 →触发空闲中断在空闲中断里标记数据包收完可以去解析这串数据了重点坑点空闲中断一包数据只会触发一次不是一直检测空闲。2.开启空闲中断/** * brief 配置 DEBUG 串口模式 * param 无 * retval 无 */voidDEBUG_USART_MODEConfig(void){USART_InitTypeDef usart_InitStruct{0};/* 开启 DEBUG 相关的GPIO外设/端口时钟 */DEBUG_APBXCLKCMD(DEBUG_USARTX_CLK_PORT,ENABLE);//开启 端口时钟/* 配置串口的工作参数 *///波特率配置:115200usart_InitStruct.USART_BaudRateDEBUG_BAUDRATE;//硬件流控开关配置:无usart_InitStruct.USART_HardwareFlowControlUSART_HardwareFlowControl_None;//配置工作模式:发送模式和接收模式usart_InitStruct.USART_ModeUSART_Mode_Tx|USART_Mode_Rx;//校验:无校验位usart_InitStruct.USART_ParityUSART_Parity_No;//停止位:1个停止位usart_InitStruct.USART_StopBitsUSART_StopBits_1;//数据帧长度:8位usart_InitStruct.USART_WordLengthUSART_WordLength_8b;USART_Init(DEBUG_USARTX,usart_InitStruct);/* 开启串口数据接收中断 */USART_ITConfig(DEBUG_USARTX,USART_IT_RXNE,ENABLE);/* 开启串口数据空闲中断 */USART_ITConfig(DEBUG_USARTX,USART_IT_IDLE,ENABLE);}在这个配置DEBUG模式代码中最后一行代码/* 开启串口数据空闲中断 */USART_ITConfig(DEBUG_USARTX,USART_IT_IDLE,ENABLE);开启串口数据空闲中断开关在数据手册中控制寄存器CR1中当IDLEIE设置1就是开启空闲中断IDLEIE设置0就是关闭空闲中断。3.空闲中断代码/** * brief DEBUG 串口中断 回调函数 * param 无 * retval 无 */voidDEBUG_IRQHANDLER(void){uint8_tdata_tempNULL;/* 数据回显 */if(USART_GetITStatus(DEBUG_USARTX,USART_IT_RXNE)SET){//读取数据寄存器读取后对应的寄存器会被复位data_tempUSART_ReceiveData(DEBUG_USARTX);/*如果此次接收到了指定\n*/if(data_temp\n){debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}/*当存储数据的数组没有满 并且 是空闲状态可以接收*/if((debug_receive.lenDEBUG_BUFFER_SIZE-1)(debug_receive.read_flag0)){debug_receive.buffer[debug_receive.len]data_temp;debug_receive.len;}/*满数据包*/if(debug_receive.lenDEBUG_BUFFER_SIZE-1){debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}// USART_SenByte(DEBUG_USARTX, data_temp);USART_ClearITPendingBit(DEBUG_USARTX,USART_IT_RXNE);//清除接收标志位}}在原本代码中数据结束就通过发送数据在末尾打一个回车标志着结束代码如下/*如果此次接收到了指定\n*/if(data_temp\n){debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}data_temp是读取的数据当如果当前读取的数据是换行就添加结束标志现在将这部分代码进行修改如下if(USART_GetITStatus(DEBUG_USARTX,USART_IT_IDLE)SET){/* 根据手册实际描述读取获取USART_ITIDLE、数据寄存器的数据读取后对应的寄存器会被复位 用这样方式清除IDLE 清除标志位过程 1.获取中断状态USART_GetITStatus() 2.读取数据寄存器数据USART_ReceiveData() 最终将DEBUG_USARTX标志位清除 */USART_ReceiveData(DEBUG_USARTX);debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}完整代码完整代码/** * brief DEBUG 串口中断 回调函数 * param 无 * retval 无 */voidDEBUG_IRQHANDLER(void){uint8_tdata_tempNULL;/* 数据回显 */if(USART_GetITStatus(DEBUG_USARTX,USART_IT_RXNE)SET){//读取数据寄存器读取后对应的寄存器会被复位data_tempUSART_ReceiveData(DEBUG_USARTX);/*当存储数据的数组没有满 并且 是空闲状态可以接收*/if((debug_receive.lenDEBUG_BUFFER_SIZE-1)(debug_receive.read_flag0)){debug_receive.buffer[debug_receive.len]data_temp;debug_receive.len;}/*满数据包*/if(debug_receive.lenDEBUG_BUFFER_SIZE-1){debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}// USART_SenByte(DEBUG_USARTX, data_temp);USART_ClearITPendingBit(DEBUG_USARTX,USART_IT_RXNE);//清除接收标志位}/* 串口检测到「一帧数据传输完毕总线上持续一段时间没有新字节」就触发空闲中断 用来做数据结束 */// 检测空闲中断if(USART_GetITStatus(DEBUG_USARTX,USART_IT_IDLE)SET){/* 根据手册实际描述读取获取USART_ITIDLE、数据寄存器的数据读取后对应的寄存器会被复位 用这样方式清除IDLE 清除标志位过程 1.获取中断状态USART_GetITStatus() 2.读取数据寄存器数据USART_ReceiveData() 最终将DEBUG_USARTX标志位清除 */USART_ReceiveData(DEBUG_USARTX);debug_receive.buffer[debug_receive.len]\0;debug_receive.read_flag1;}}接着需要了解的是不管USART_IT_RXNE还是USART_IT_IDLE只要触发了中断都会进入串口中断回调函数里面。清除空闲中断标志位原本USART_IT_RXNE触发中断清除该标志位只需要读取数据寄存器就会自动清除还有一种手动清除函数如下USART_ClearITPendingBit(DEBUG_USARTX,USART_IT_RXNE);//清除接收标志位可以看到清除标志位参数说明只能清除USART_IT_CTS、USART_IT_LBD、USART_IT_TC、USART_IT_RXNE这四种但是如果要清除IDLE标志位需要两个函数USART_GetITStatus()和USART_ReceiveData()一个是获取串口状态函数一个是读取数据的函数那么标志位会自动清除。在CR1寄存器中IDLE能读能写上面说了由软件清除在SR寄存器中IDLE只能读但是如果要清零先读SR然后读DRCR1是中断看的寄存器4.实验现象原本是通过发送数据时候在数据末尾打一个回车通过换行方式结束此次数据发送现在通过空闲中断方式检测当我发送了一串数据后连续一段时间没有发送数据就触发空闲中断用在此次数据发送是否结束了一种中断方式
延伸阅读

更多相关文章

2026/10/1 8:01:38

海口定制柜维修与换件怎么判定:按部位与装配关系分 4 类

柜体维修这件事,最怕的是"凭经验判断"。同一处缝隙不均,有人拆开重装,有人只调两颗铰链。判断标准其实可以写清楚:看损坏落在哪个部位、以及这个部位与其他构件是什么关系。 海口全屋定制哪家好,落到技术层面…

2026/10/1 8:51:39

TensorFlow 2.3花卉识别实战:CNN、迁移学习与OpenCV部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 8:51:39

Ubuntu全盘备份恢复指南:tar、Timeshift与Systemback对比详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 8:51:39

Unity手游iOS Deep Link唤醒全流程:URL Scheme与Universal Links落地实践

许多做手游的朋友都遇到过这个需求:运营给用户发了一条带参数的分享链接,用户在微信或Safari里点了链接,游戏没安装就跳转到App Store,安装了就自动打开游戏,并且精准进入活动页面、带上邀请码、恢复上次的登录态。这就…

2026/10/1 8:51:39

AI日报实战:Agent开发、Claude与Gemini使用及vLLM部署指南

1. 从一份日报说起:AI 圈的信息密度正在失控 做 AI 方向的人最近应该都有同一种体感:一天不刷消息,第二天就跟不上节奏了。模型版本号在跳,Agent 框架在冒,推理引擎的镜像 tag 一天一个样,昨天还能跑通的部…

2026/10/1 8:46:39

如何用3条命令快速跑起来AIHOT?面向新手的Docker完整部署教程

如何用3条命令快速跑起来AIHOT?面向新手的Docker完整部署教程 【免费下载链接】AIHOT 一个自己找热点、自己写日报的网站框架。把信源和精选标准换成你的,它就是你的行业热点站。 项目地址: https://gitcode.com/gh_mirrors/ai/AIHOT AIHOT 是一个…

2026/10/1 5:21:14

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/29 21:48:03

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 7:00:49

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑