【STM32CubeMX学习教程】——7.DMA+USART

该文章已生成可运行项目,


一、DMA基本概念

DMA(Direct Memory Access,直接存储器访问)是一种允许外设直接与存储器进行数据传输的技术,这样 CPU 不需要参与整个搬运过程,只需在开始和结束时配置和管理,大大提高了系统效率。
整个工作流程大体分为:

1.初始化配置阶段(CPU 参与)

  • CPU 告诉 DMA 控制器:
       - 数据从哪里来(源地址)
       - 要放到哪里去(目标地址)
       - 要搬多少数据(传输大小)
       - 传输方式(单次/循环/突发等)
  • 然后启动 DMA

2.传输阶段(CPU 不参与)

  • DMA 控制器接管总线的使用权,自动完成源地址 → 目标地址的数据传输。
  • CPU 可以同时执行其他任务(并行处理),不用被数据搬运“绑死”。

3.结束阶段(中断通知)

  • DMA 传输完成后,触发中断,通知 CPU:“数据搬运完成了,可以处理下一步了。”

二、DMA 的传输模式

  • 存储器到存储器(如大块内存拷贝)
  • 外设到存储器(如 ADC 采样结果写入内存)
  • 存储器到外设(如把内存中的数据送到串口发送寄存器)
  • 外设到外设(少见)

三、DMA 工作流程图

1.这个流程图展示了STM32中DMA最经典的工作方式:当一个外设需要交换数据时,它向DMA发出请求,DMA就像一位高效的搬运工,自动在总线上完成数据搬运,整个过程无需CPU核心参与。它涵盖了‘外设到存储器’、‘存储器到外设’和‘外设到外设’这三种模式。

外设如定时器, ADC等发出请求
DMA控制器接管
开始搬运数据
从外设到内存
或从内存到外设
搬运一次
剩余传输次数减1
次数减到0了吗?
产生传输完成中断
设置为循环模式了吗?
自动重载传输次数
停止传输, 等待下次使能

四、什么是 USART?

USART (Universal Synchronous/Asynchronous Receiver/Transmitter) 是一种串行通信接口,常用于微控制器与外部设备(如电脑、传感器、其他MCU等)之间的数据交换。

  • 异步模式 (UART): 最常用,不需要时钟线,依靠预先约定好的波特率进行通信。例如:RS-232, TTL串口。
  • 同步模式: 需要一条时钟线(SCLK)来同步数据。
  • 工作原理: 数据一位一位地顺序传输。发送时,CPU将数据写入发送数据寄存器(TDR),硬件会自动将数据移位发出。接收时,硬件将接收到的位流组合成字节,存入接收数据寄存器(RDR),并产生中断告知CPU。

五、为什么需要 USART + DMA?

将USART和DMA结合,主要是为了解决传统查询和纯中断方式的弊端:

1.查询方式:
CPU不断轮询USART的状态标志位(如TXE, RXNE),效率极低,CPU完全被阻塞,无法执行其他任务。

2.中断方式:
发送: 每发送完一个字节,产生一个中断,CPU需要响应中断并写入下一个字节。对于大量数据发送,中断频率非常高,CPU频繁进出中断上下文,开销很大。
接收: 每接收到一个字节,产生一个中断,CPU需要立刻读取数据寄存器,否则下一个数据可能会覆盖当前数据(Overrun Error)。如果CPU正在处理高优先级任务,可能导致数据丢失。

3.DMA方式 (USART + DMA):
发送: CPU只需一次性将要发送的数据数组地址、长度等信息配置给DMA,DMA就会自动地将内存中的数据逐个搬运到USART的发送数据寄存器中,直到发送完成才通知CPU。整个过程CPU几乎可以完全不管。
接收: CPU只需提前开辟一个接收缓冲区(数组),并将其地址和长度配置给DMA。此后,USART收到的每一个字节都会由DMA自动搬运到指定的内存数组中。只有当整个缓冲区接收满(或一半时,利用半传输中断)时,DMA才通知CPU来处理数据。极大降低了中断频率, 避免了数据丢失。

4.优点:
高效: 极大减少了CPU开销,让CPU可以专注于数据处理、算法等核心任务。
低功耗: CPU在数据传输期间可以进入睡眠模式,降低系统功耗。
高可靠性: 尤其对于高速数据流,DMA方式能更可靠地处理数据,避免因中断延迟导致的数据丢失。

五、STM32CubeMX DMA+USART配置

1.新建工程

1.双击打开桌面下载好的STM32CubeMX,点击File–>New Project,或直接点击ACCEE TO MCU SELECTOR

Alt
2.在左边搜索栏里输入使用的芯片型号,右边选中并开始创建

Alt

2.设置RCC时钟源

设置高/低速时钟源都由外部晶振产生。

Alt

3.设置串口参数

1.串口2参数设置

Alt
2.根据实际硬件电路修改GPIO口

Alt
3.使能串口2接收中断

Alt

3.设置DMA

1.添加DMA接口

ALT
2.选择要配置的接口可以选择只配置RX或者TX或两个都配置,根据自己需求来

ALT
3.下面DMA框中保持默认即可

ALT
到此USART+DMA参数配置结束,主要就是在串口功能的基础上添加DMA功能。

4.时钟配置

1.时钟源设置
默认时钟源是由内部RC振荡器产生,可通过图中按钮进行修改,外部晶振数值取决于实际电路板上的晶振大小.

Alt
提示:

  • 这里用到的芯片的最大时钟频率是100MHz,有的芯片最大只有72MHz,实际最大频率可通过查看芯片数据手册确定。

2.时钟频率设置

Alt
①PLLM—PLL输入时钟分频系数,根据自己需要的系统时钟频率来进行修改
②PLLN—主PLL倍频系数(自动计算)
③PLLP—主PLL分频系数(自动计算)
④SYSCLK—系统时钟
⑤HCLK—AHB总线时钟,由系统时钟SYSCLK 分频得到,一般不分频,等于系统时钟
⑥APB1/APB2 Prescaler—APB1/APB2总线的预分频系数,可根据需要修改

5.工程文件设置

1.工程设置
注:工程路径中不能有中文,否则会输出错误。
库文件要提前下载好,具体方法在 “【STM32CubeMX学习教程】——1.软件安装” 这一篇文章中有提到。

Alt

2.代码生成设置

Alt
3.点击右上角按钮生成代码,之后会出现下面的窗口,再点击打开工程即可在用keil查看工程代码。

Alt
4.编译成功
Alt

六、HAL库中常用的USART + DMA相关代码

1.启动DMA传输

uint8_t txBuffer[] = "Hello, World!\r\n";
HAL_UART_Transmit_DMA(&huart2, txBuffer, sizeof(txBuffer) - 1);//-1 排除空值终端

2.发送中断回调函数

//在传输完成回调函数中处理后续工作(可选)
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART2) {
        // 发送完成,可以点亮LED或者准备下一包数据
    }
}

3.启动DMA接收

// 1. 定义接收缓冲区
#define RX_BUFFER_SIZE 100
uint8_t rxBuffer[RX_BUFFER_SIZE];

HAL_UART_Receive_DMA(&huart2, rxBuffer, RX_BUFFER_SIZE);

4.接收中断回调函数

//处理接收完成中断(可选)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART2) {
        // 整个缓冲区接收满了
        // 处理数据,然后重新启动接收(因为DMA只触发一次)
        processData(rxBuffer, RX_BUFFER_SIZE);
        HAL_UART_Receive_DMA(&huart2, rxBuffer, RX_BUFFER_SIZE);
    }
}

以上就是本章的全部内容,如果对你有帮助,欢迎点赞支持,谢谢!

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

玥山山

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

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

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

打赏作者

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

抵扣说明:

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

余额充值