你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL_UART_Transmit_DMA 异常

[复制链接]
patch1582 提问时间:2026-7-21 14:45 / 未解决

我想用 DMA 通过串口输出单个字符。 首先将 DMA 配置为普通单次模式,初始化代码如下: huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2);

hdma_usart2_tx.Instance = DMA1_Stream6; hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4; hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_tx.Init.Mode = DMA_NORMAL; hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; HAL_DMA_Init(&hdma_usart2_tx);

__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx); 主循环之外只添加了这段发送代码,while (1) 里只有 LED 闪烁逻辑: HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"b",1); 普通 DMA 模式下,串口只输出一次字符a,随后 LED 开始闪烁,字符b没有输出。 如果改成发送长字符串再加两个单字符: char testMessage[] = "test output of a longer string\r\n"; HAL_UART_Transmit_DMA(&huart2,(uint8_t)&testMessage,sizeof(testMessage)-1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t*)"b",1); 最终只能收到完整字符串,a和b依旧不会发送出来。 如果把 DMA 配置改成循环模式(DMA_CIRCULAR),其余初始化不变,再次执行单次发送代码:

HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"b",1); 串口会持续不断重复输出a,LED 同步闪烁,b不出现。 如果同样搭配长字符串一起发送:

char testMessage[] = "test output of a longer string\r\n"; HAL_UART_Transmit_DMA(&huart2,(uint8_t)&testMessage,sizeof(testMessage)-1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t*)"b",1); 字符串会无限循环重复发送,a和b依旧无输出。 查阅手册 UM1725《STM32F4xx HAL 驱动说明》846 页关于串口 DMA 的描述: Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxCpltCallback 为什么 DMA 模式只能发送一次数据,后续所有发送请求全部失效;循环 DMA 模式会无限重复第一条发送内容,后面的发送指令不生效? 麻烦各位帮忙解答一下。

收藏 评论3 发布时间:2026-7-21 14:45

举报

3个回答
DazzlingOkami 回答时间:5 小时前

你这还没有理解DMA异步传输的本质吧。

HAL_UART_Transmit_DMA开启传输后,函数就立即返回了,这时候数据实际上还在传输过程中你就开始启动下一次HAL_UART_Transmit_DMA,这必然会导致第二次乃至后续的传输都直接返回BUSY的错误。

正确的做法是每次开启下次传输时确保上一次的传输已经完成。可用配合DMA传输完成中断实现。

对于你每次传输单个字节的情况,使用中断传输比使用DMA要更好,当然这也需要处理传输完成同步的问题。

butterflyspring 回答时间:4 小时前
楼上说的没错,建议先看看手册,了解DMA工作原理先。


然后很多系列都有例程可以参考。
patch1582 回答时间:4 小时前

DazzlingOkami 发表于 2026-7-21 15:28
你这还没有理解DMA异步传输的本质吧。</p>
<p>HAL_UART_Transmit_DMA开启传输后,函数就立即返回了,这时候数 ...

[md]也就是说在下次传输前检测状态

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版