news 2026/6/8 22:11:07

串口空闲中断使能到串口空闲中断建立需要多长时间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
串口空闲中断使能到串口空闲中断建立需要多长时间

最近在用DMA+串口空闲中断时,发现第一次发送有问题。见下图:

问了很多人,搜索网上,很少有人知道。为什么延时90us,DAM+串口发送就没有问题,原来是空闲中断使用了“HAL_UART_DMAStop(&g_uart1_handle);//停止串口DMA”导致的。

解决办法,就是再使能串口中断前,等待串口空闲中断标志建立,然后清除它。

void usart_init(uint32_t baudrate) { g_uart1_handle.Instance = USART_UX; /* USART1 */ g_uart1_handle.Init.BaudRate = baudrate; /* 波特率 */ g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; /* 字长为8位数据格式 */ g_uart1_handle.Init.StopBits = UART_STOPBITS_1; /* 一个停止位 */ g_uart1_handle.Init.Parity = UART_PARITY_NONE; /* 无奇偶校验位 */ g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 无硬件流控 */ g_uart1_handle.Init.Mode = UART_MODE_TX_RX; /* 收发模式 */ g_uart1_handle.Init.OverSampling = UART_OVERSAMPLING_16; g_uart1_handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; g_uart1_handle.Init.ClockPrescaler = UART_PRESCALER_DIV1; g_uart1_handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&g_uart1_handle);/* HAL_UART_Init()会使能UART1 */ HAL_UARTEx_SetTxFifoThreshold(&g_uart1_handle, UART_TXFIFO_THRESHOLD_1_8); HAL_UARTEx_SetRxFifoThreshold(&g_uart1_handle, UART_RXFIFO_THRESHOLD_1_8); HAL_UARTEx_DisableFifoMode(&g_uart1_handle); __HAL_UART_DISABLE_IT(&g_uart1_handle, UART_IT_RXNE); //必须关闭RXNE中断,否则会与IDLE冲突 // __HAL_UART_DISABLE_IT(&g_uart1_handle, UART_IT_IDLE); //不使能空闲中断 __HAL_UART_ENABLE_IT(&g_uart1_handle, UART_IT_IDLE); //使能空闲中断 delay_us(10000000/baudrate); //在使能串口中断前,需要延时,目的是等待串口空闲中断标志建立 //串口一帧数据:起始位1位+8位+停止位1位,8+1+1=10 //串口空闲中断的判定是: //当串口开始接收数据后,检测到1字节数据的时间内没有数据发送,则认为串口空闲了。 __HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_IDLE); //通过读"串口空闲中断标志位",就可以清除这个中断标志位; __HAL_UART_DISABLE_IT(&g_uart1_handle, UART_IT_TXE); //不使能发送缓存为空而产生的中断 __HAL_UART_DISABLE_IT(&g_uart1_handle, UART_IT_TC); //不使能发送完成中断 __HAL_UART_CLEAR_FLAG(&g_uart1_handle, UART_CLEAR_TCF);// 清除发送完成标志 __HAL_UART_ENABLE_IT(&g_uart1_handle, UART_IT_TC); //使能发送完成中断 SCB_CleanInvalidateDCache();// 清理缓存 /* 在使用 DMA(直接内存访问)传输数据时,可能会出现缓存与存储器数据不一致的情况。 调用此函数可以在 DMA 操作前后清理和无效化缓存,确保数据一致性。 */ dma_init_RX(DMA2_Stream1);//初始化DMA串口接收 dma_init_TX(DMA2_Stream7);//初始化DMA串口发送 HAL_UART_DMAStop(&g_uart1_handle);//关闭串口DMA __HAL_DMA_CLEAR_FLAG(&hdma_uart1_tx_handle, DMA_FLAG_TCIF3_7); //清除DMA2_Stream7传输完成标志 HAL_UART_Receive_DMA(&g_uart1_handle, g_rx_buffer, USART_REC_LEN); //数据处理完成后,再调用DMA接收 memset(g_rx_buffer, 0,USART_REC_LEN); //清0 g_usart_rx_sta=0; g_usart_Receive_Complete_Flag=0; g_usart_deal_rx_buf_len=0; g_usart_Send_Complete_Flag=0; HAL_NVIC_EnableIRQ(USART_UX_IRQn); /* 使能USART1中断通道 */ HAL_NVIC_SetPriority(USART_UX_IRQn, 3, 3); /* 抢占优先级3,子优先级3 */ }

通过上面修改,调用usart_init(115200);就可以直接发送数据了,第一次发送就正常了。

10000000/115200=86.80555555555556us
这就是延时90us的原因,80us就不行
串口一帧数据:起始位1位+8位+停止位1位,8+1+1=10
这个问题,网上很少有人知道。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/8 22:11:03

Redis基础介绍与SpringDataRedis的基础使用

这是一份面向初学者的 Redis 基础学习文档,涵盖了 Redis 核心数据结构、Spring Data Redis 框架、RedisTemplate 的快速入门、序列化机制以及 StringRedisTemplate 的使用。 Redis 基础学习文档 1. Redis 简介与常见数据结构 Redis(REmote DIctionary …

作者头像 李华
网站建设 2026/6/8 22:07:52

颠覆性开源OCR解决方案:3个实战场景深度解析Umi-OCR的架构优势

颠覆性开源OCR解决方案:3个实战场景深度解析Umi-OCR的架构优势 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置…

作者头像 李华
网站建设 2026/6/8 22:00:30

微信装逼神器步数修改步数教程无需下载软件版

弥夏刷步是一套面向用户自助使用的运动步数管理系统,核心目标是让用户更方便地管理 Zepp Life 运动账号,并将步数同步到微信运动与支付宝等平台。程序整体采用网页端操作方式,用户无需复杂配置,登录后即完成账号管理、步数提交、自…

作者头像 李华
网站建设 2026/6/8 21:55:12

BLE芯片功耗优化实战:从KW47数据解读到电池寿命精准估算

1. 项目概述如果你正在设计一款基于蓝牙低功耗(BLE)的物联网设备,比如智能门锁、可穿戴手环或者资产追踪标签,那么“续航”这个词一定是你产品规格书里最敏感、也最头疼的指标之一。客户总希望设备能“用得更久”,而电…

作者头像 李华
网站建设 2026/6/8 21:51:36

cmux:专为 AI Agent 和多任务设计的 macOS 终端

一句话定位: cmux 是基于 Ghostty 渲染引擎构建的原生 macOS 终端应用,核心卖点是垂直标签页管理、Agent 通知提醒环、内置浏览器、分屏面板和 CLI/socket 可编程 API。它不是 Ghostty 的 fork,而是一个独立的应用层。 目前仅支持 macOS 14.…

作者头像 李华