news 2026/4/20 18:47:34

STM32串口DMA通讯+源码+原理图+说明。 很多时候,单片机需要进行多机通讯,但是如果使用...

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32串口DMA通讯+源码+原理图+说明。 很多时候,单片机需要进行多机通讯,但是如果使用...

STM32串口DMA通讯+源码+原理图+说明。 很多时候,单片机需要进行多机通讯,但是如果使用以往的串口通讯,势必会占用CPU时间,影响单片机的实时性,如果才用.DMA的方式就行数据通讯,就可以很好的保证了实时性。

搞嵌入式的人都知道,串口这玩意儿就像吃饭喝水一样基础。不过当系统里挂了好几个设备要互相通讯的时候,传统的轮询方式能把CPU累成狗。最近在搞STM32的温控项目,三个下位机实时传数据,传统中断方式直接把主频72MHz的F103搞出了卡顿,这时候就得上DMA大法了。

先甩个原理图镇楼(用Fritzing简单画个示意):

[UART1TX→485芯片→总线][UART1RX←总线][DMA1Channel4配置成串口发送][DMA1Channel5负责接收]

关键代码咱们直接上干货。先看DMA初始化部分,这里用HAL库实现:

// DMA发送配置 hdma_usart1_tx.Instance = DMA1_Channel4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; // 单次传输 HAL_DMA_Init(&hdma_usart1_tx); // 串口DMA接收配置 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 启用空闲中断 HAL_UART_Receive_DMA(&huart1, rx_buffer, BUFFER_SIZE);

这段配置有几个骚操作:首先用内存地址自增实现连续发送,然后开启串口空闲中断来判定一帧数据接收完成。注意接收用的是循环模式,发送用单次模式——这可不是随便选的,发送完成需要重新装填数据,接收则需要持续监听。

数据搬运过程完全不用CPU插手,但总得知道什么时候传完吧?这时候得用传输完成中断:

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1){ // 这里可以搞个信号量通知任务 tx_complete_flag = 1; } } // 接收完成用空闲中断触发 void USART1_IRQHandler(void) { if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)){ __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_UART_DMAStop(&huart1); // 计算接收到的数据长度 received_len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 唤醒处理线程 osSemaphoreRelease(uart_sem); } HAL_UART_IRQHandler(&huart1); }

这里有个坑爹的地方:DMA传输计数器是递减的,所以实际接收数据长度=缓冲区总长度-当前计数值。之前在这翻过车,数据总是少收最后几个字节,调试半天才发现计数器的问题。

实际应用里还得注意内存对齐,比如下面这个发送函数:

void dma_send(uint8_t *data, uint16_t len) { while(!tx_complete_flag); // 等待上次发送完成 if(len > MAX_LEN) return; // 内存拷贝必须4字节对齐 memcpy(tx_buffer, data, len); SCB_CleanDCache_by_Addr((uint32_t*)tx_buffer, len); HAL_UART_Transmit_DMA(&huart1, tx_buffer, len); tx_complete_flag = 0; }

特别是用到D-Cache的时候,必须手动清理缓存,否则DMA搬运的可能是脏数据。这个坑在STM32H7系列上特别明显,F4系列偶尔也会中招。

实测效果:在115200波特率下连续传输1KB数据,传统中断方式CPU占用率高达35%,换成DMA后直接降到3%以下。要是上到460800波特率,中断方式直接卡成PPT,DMA还能稳如老狗。

最后甩个源码仓库地址(示例用,勿直接访问):

https://github.com/example/stm32uartdma_demo

搞这种多机通讯,记得在总线上加120Ω匹配电阻,不然数据错乱起来连逻辑分析仪都救不了你。下次有机会再唠唠怎么用DMA实现环形缓冲区+协议解析的骚操作。

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

超越商用API的轻量翻译模型|HY-MT1.5-1.8B实测分享

超越商用API的轻量翻译模型|HY-MT1.5-1.8B实测分享 1. 引言:为什么我们需要轻量级开源翻译模型? 在多语言内容爆发式增长的今天,高质量、低延迟的翻译能力已成为全球化应用的核心基础设施。尽管Google Translate、DeepL等商用AP…

作者头像 李华
网站建设 2026/4/18 18:30:42

移动端多模态AI实践|基于AutoGLM-Phone-9B实现高效本地推理

移动端多模态AI实践|基于AutoGLM-Phone-9B实现高效本地推理 随着大模型技术的快速发展,将多模态能力部署到移动端设备已成为智能应用的重要趋势。然而,受限于移动终端的算力、内存和功耗,如何在资源紧张的环境下实现高质量的本地…

作者头像 李华
网站建设 2026/4/18 19:11:11

没GPU怎么玩AI分类?万能分类器云端镜像2块钱搞定

没GPU怎么玩AI分类?万能分类器云端镜像2块钱搞定 引言:产品经理的AI分类验证困境 作为产品经理,当你灵光一闪想到"用AI分类器优化业务流程"时,兴奋之余马上会面临三大现实难题: 硬件门槛:公司…

作者头像 李华
网站建设 2026/4/20 12:13:49

AI分类模型效果对比:3大框架云端实测报告(含代码)

AI分类模型效果对比:3大框架云端实测报告(含代码) 引言 作为技术主管,你是否遇到过这样的困境:团队需要选择一个深度学习框架进行图像分类任务开发,但TensorFlow、PyTorch和PaddlePaddle各有优势&#xf…

作者头像 李华
网站建设 2026/4/17 23:13:55

2026武汉做网站TOP8:企业数字化解决方案推荐

2026武汉企业建站:数字化转型的核心选择逻辑2026年,武汉中小微企业数字化转型浪潮下,“建站”成为品牌展示、跨境获客、数字化升级的关键入口。据《武汉本地企业建站服务调研(2026)》显示,超70%企业存在“首…

作者头像 李华
网站建设 2026/4/18 15:11:08

如何快速实现PDF布局与公式识别?试试科哥开发的PDF-Extract-Kit镜像

如何快速实现PDF布局与公式识别?试试科哥开发的PDF-Extract-Kit镜像 1. 背景与痛点:传统PDF提取的三大难题 在科研、教育、出版和文档数字化等场景中,PDF文件是信息传递的核心载体。然而,传统的PDF内容提取方式长期面临三大挑战…

作者头像 李华