【STM32 CubeMX】串口编程DMA


前言

在嵌入式系统中,串口通信是一项至关重要的功能,它允许单片机与外部设备进行数据交换,如传感器、显示器或其他设备。然而,在高速数据传输的场景下,传统的串口通信方式可能会使CPU过于繁忙,从而影响系统的性能。为了解决这一问题,STM32系列微控制器提供了DMA(直接内存访问)技术,可以在不占用CPU资源的情况下实现高速的数据传输。本文将介绍如何利用STM32 CubeMX配置串口通信并使用DMA进行数据传输。


一、DMA方式

1.1 DMA是什么

想象一下你在单片机中需要把一堆数据从一个地方搬到另一个地方,比如从内存搬到外设(比如串口或者存储器)。传统的方式是由CPU来亲自操持每一个数据的传输,就像你亲自搬运每一件家具一样。

而DMA就像是单片机中的一支专业的搬家队伍。你可以告诉这支队伍从哪里搬到哪里,然后它们就可以自动完成这个任务,而不需要CPU一直牵头指挥。这样,CPU就可以专注于处理其他的事务,而不用为每个数据传输都忙碌起来。

所以,单片机中的DMA就是一种让数据在不需要CPU持续参与的情况下,在内存和外设之间自动传输的技术,使得单片机能更高效地完成一些数据搬运的任务。简而言之,就是让单片机变得更聪明、更省力。

比如下面这个图,如果我们使用普通的发送RAM里面的buf,那么cpu就要一位一位的取buf,放到串口发送寄存器中,那么就非常耗费时间,那么这时DMA就出现了,他可以直接让cpu把RAM里面的buf放到DMA,然后DMA自动把buf放到发送寄存器里,放到寄存器这

### 使用 STM32CubeMX 配置 UART/USART DMA 接收模式 #### 1. 初始化项目并选择设备 启动 STM32CubeMX 并创建新工程,选择目标微控制器型号。对于本案例,默认选择了支持多个串口STM32F407ZGT6 设备[^2]。 #### 2. 配置时钟树与时钟源 进入 "Clock Configuration" 页面调整系统时钟频率至所需值,确保满足应用需求的同时不影响外设性能。 #### 3. 设置 USART 或 UART 外设参数 转到 “Pinout & Configuration” 标签页找到要使用的 USART/UART 单元(例如 USART1),点击右侧齿轮图标展开设置选项卡: - **Mode**: 启用 TX 和 RX 功能; - **Baud Rate**: 输入期望波特率数值; - **Word Length / Stop Bits / Parity Check**: 根据实际通讯协议设定字符长度、停止位数以及奇偶校验方式; - **Hardware Flow Control**: 如果不需要硬件流控,则保持默认关闭状态; #### 4. 开启 DMA 控制器功能 同样在此页面内定位到 DMA 控制器模块,勾选对应于所选 USART 的接收通道资源分配开关。这一步骤非常重要,因为只有当 DMA 被激活后才能实现高效的数据搬运操作[^1]。 #### 5. 定义中断服务程序 为了及时响应接收到的新数据,在 NVIC 中使能相应的全局中断请求,并指定优先级级别。这样每当有新的字节到达缓冲区时就会触发一次ISR处理事件[^4]。 #### 6. 生成功能框架代码 完成上述配置之后保存项目文件并通过工具链生成功能模板代码。此时可以在 `main.c` 文件里看到已经自动生成好的初始化语句和回调函数原型声明。 #### 7. 编写应用程序逻辑 接下来就是编写具体的业务逻辑部分了。下面给出一段简单的例子来展示如何利用 HAL 库接口读取通过 DMA 方式传入的数据帧: ```c #include "main.h" UART_HandleTypeDef huart1; DMA_HandleTypeDef hdma_usart1_rx; /* Buffer to store received data */ #define BUFFER_SIZE 64 uint8_t rxBuffer[BUFFER_SIZE]; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_USART1_UART_Init(void); int main(void) { /* Reset of all peripherals, Initializes the Flash interface and Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); // Enable DMA controller MX_USART1_UART_Init();// Set up USART parameters // Start receiving with DMA HAL_UART_Receive_DMA(&huart1, rxBuffer, BUFFER_SIZE); while (1){ // Main loop can be used for other tasks or kept empty. } } // Callback function called when reception is complete void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1){ // Process received buffer here... // Restart DMA transfer after processing current batch HAL_UART_Receive_DMA(&huart1, rxBuffer, BUFFER_SIZE); } } ``` 这段代码展示了基本的应用场景:首先调用了 `HAL_UART_Receive_DMA()` 函数开启连续不断的自动填充过程;一旦整个数组被填满即刻激发对应的完成通知机制——即执行 `HAL_UART_RxCpltCallback()` 方法来进行后续处置工作,比如解析消息内容或是转发给上层协议栈等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人才程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值