当前位置: 首页 > news >正文

STM32 DMA直接存储器访问(寄存器与HAL库实现)

一、DMA介绍

直接存储器存取(direct memory access,DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。

简单描述,DMA充当了一个数据搬运工的角色。

DMA核心作用

  • 解放 CPU:传统数据传输需要 CPU 逐条指令搬运(如读取外设数据→写入内存),而 DMA 可独立完成传输,CPU 可同时执行其他任务。
  • 提高效率:DMA 传输速度快,尤其适合大量数据(如音频、图像)的连续传输,避免 CPU 因等待传输而阻塞。
  • 支持多种场景:可实现外设→内存、内存→外设、内存→内存的数据传输。

DMA搬运什么数据

存储器、外设

这里的外设指的是spi、usart、iic、adc 等基于APB1 、APB2或AHB时钟的外设,而这里的存储器包括
自身的闪存(flash)或者内存(SRAM)以及外设的存储设备都可以作为访问地源或者目的。

三种搬运方式:

  • 存储器→存储器(例如:复制某些特别大的数据buf)
  • 存储器→外设 (例如:将数据buf写入串口TDR寄存器)
  • 外设→存储器 (例如:将串口RDR寄存器写入数据buf)

1. DMA框图

在这里插入图片描述

2. stm32中DMA

STM32F103中有2个DMA控制器,有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

一个通道每次只能搬运一个外设的数据,如果同时有多个外设的 DMA 请求,则按照优先级进行响应。

要注意的是DMA2只存在于大容量产品和互联型产品中。
在这里插入图片描述
在这里插入图片描述

3. DMA优先级管理

优先级管理采用软件+硬件:

软件: 每个通道的优先级可以在DMA_CCRx寄存器中设置,有4个等级
最高级>高级>中级>低级

硬件: 如果2个请求,它们的软件优先级相同,则较低编号的通道比较高编号的通道有较高的优先权。
比如:如果软件优先级相同,通道2优先于通道4
在这里插入图片描述

二、实验:ROM到RAM

把ROM中的数据通过DMA传输到RAM,然后把数据通过printf发送到串口。

DMA传输不涉及外设,所以通道随便选。我们选DMA1的1通道。

注意DMA没有办法把数据从RAM传输到ROM(flash)。

1. ROM和RAM

STM32 的 ROM 主要用于存储程序代码、常量数据和固化的配置信息,其内容在断电后不会丢失。

  • Flash 存储器:STM32 中最核心的 ROM 类型,用于存储用户编写的程序代码(如main函数、中断服务程序等)、常量(如const修饰的变量)以及程序运行所需的固定数据。
    特点:可多次擦写(但擦写次数有限,通常数万次以上),掉电数据不丢失,访问速度较快。
  • 系统存储器(System Memory):一块特殊的 Flash 区域,由 ST 公司固化了Bootloader 程序(如 ISP 程序),用于通过串口、USB 等方式给单片机烧录程序。用户无法修改此区域内容。

STM32 的 RAM 用于存储程序运行时的临时数据,其内容在断电后会丢失,是程序运行的 “临时 workspace”。

  • SRAM(静态随机存取存储器):STM32 的 RAM 均为 SRAM,无需刷新电路,访问速度快,适合高速数据读写。

    特点:掉电数据丢失,读写速度远快于 Flash,容量通常小于 Flash

2. 寄存器实现

#include "dma.h"void DMA1_init()
{// 1. 开启时钟RCC->AHBENR |= RCC_AHBENR_DMA1EN;// 2. DMA相关配置// 2.1 DMA方向 存储器到存储器 ROM===>RAMDMA1_Channel1->CCR |= DMA_CCR1_MEM2MEM;DMA1_Channel1->CCR &= ~DMA_CCR1_DIR;// 2.2 数据宽度 8位DMA1_Channel1->CCR &= ~DMA_CCR1_MSIZE;DMA1_Channel1->CCR &= ~DMA_CCR1_PSIZE;// 2.3 地址自增DMA1_Channel1->CCR |= DMA_CCR1_MINC;DMA1_Channel1->CCR |= DMA_CCR1_PINC;// 2.4 传输完成中断DMA1_Channel1->CCR |= DMA_CCR1_TCIE;// 2.5 NVIC配置NVIC_SetPriorityGrouping(4);NVIC_SetPriority(DMA1_Channel1_IRQn, 1);NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}void DMA1_transmitData(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen)
{// 外设地址DMA1_Channel1->CPAR = srcAddr;// 存储器地址DMA1_Channel1->CMAR = destAddr;// 传输长度DMA1_Channel1->CNDTR = dataLen;// 开启通道DMA1_Channel1->CCR |= DMA_CCR1_EN;
}void DMA1_Channel1_IRQHandler(void)
{if (DMA1->ISR & DMA_ISR_TCIF1){// 清除中断标志位DMA1->IFCR |= DMA_IFCR_CTCIF1;// 关闭通道DMA1_Channel1->CCR &= ~DMA_CCR1_EN;is_finished = 1;}
}
#include "led.h"
#include "delay.h"
#include "usart.h"
#include "dma.h"const uint8_t src_data[4] = {10, 20, 30, 40};
uint8_t dest_data[4] = {0};
uint8_t is_finished = 0;int main(void)
{USART1_init();DMA1_init();printf("hello world!\r\n");DMA1_transmitData((uint32_t)src_data, (uint32_t)dest_data, 4);while (1){if (is_finished){is_finished = 0;for (uint8_t i = 0; i < 4; i++){printf("%d\t", dest_data[i]);}}}
}

3.HAL库实现

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */printf("hello\r\n");// 注册回调函数HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, HAL_DMA_XFER_CPLT_CB_ID, dma_compeleteCallback);HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t)src_data, (uint32_t)dest_data, 4);/* USER CODE END 2 */while (1){if (is_finished){is_finished = 0;for (uint8_t i = 0; i < 4; i++){printf("%d\t", dest_data[i]);}}}
}void dma_compeleteCallback(DMA_HandleTypeDef *_hdma)
{// 清除中断标志位,失能通道HAL_DMA_Abort_IT(&hdma_memtomem_dma1_channel1);is_finished = 1;
}
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (*pCallback)(DMA_HandleTypeDef *_hdma))
  • pCallback: 指向用户定义的回调函数的指针。回调函数的原型应为 void Callback(DMA_HandleTypeDef *_hdma)

三、实验:RAM到外设(串口)

把RAM中的数据直接传输到usart1的Tx引脚,然后数据被发送到电脑端。

由于不同的通道对应着不同的外设,查阅手册了解到应该选择DMA1的通道4

1. 寄存器实现

#include "dma.h"void DMA1_init()
{// 1. 开启时钟RCC->AHBENR |= RCC_AHBENR_DMA1EN;// 2. DMA相关配置// 2.1 DMA方向 存储器到外设 ROM===>USART1DMA1_Channel4->CCR |= DMA_CCR4_DIR; // 从存储器读// 2.2 数据宽度 8位DMA1_Channel4->CCR &= ~DMA_CCR4_MSIZE;DMA1_Channel4->CCR &= ~DMA_CCR4_PSIZE;// 2.3 地址自增// 外设(串口)不自增DMA1_Channel4->CCR |= DMA_CCR4_MINC;DMA1_Channel4->CCR &= ~DMA_CCR4_PINC;// 2.4 传输完成中断DMA1_Channel4->CCR |= DMA_CCR4_TCIE;// 2.5 NVIC配置NVIC_SetPriorityGrouping(4);NVIC_SetPriority(DMA1_Channel4_IRQn, 1);NVIC_EnableIRQ(DMA1_Channel4_IRQn);// 2.6 串口DMA使能发送USART1->CR3 |= USART_CR3_DMAT;
}// 源-存储器地址  目的-外设地址
void DMA1_transmitData(uint32_t srcAddr, uint32_t destAddr, uint16_t dataLen)
{// 外设地址DMA1_Channel4->CPAR = destAddr;// 存储器地址DMA1_Channel4->CMAR = srcAddr;// 传输长度DMA1_Channel4->CNDTR = dataLen;// 开启通道DMA1_Channel4->CCR |= DMA_CCR4_EN;
}void DMA1_Channel4_IRQHandler(void)
{if (DMA1->ISR & DMA_ISR_TCIF4){// 清除中断标志位DMA1->IFCR |= DMA_IFCR_CTCIF4;// 关闭通道DMA1_Channel4->CCR &= ~DMA_CCR4_EN;}
}
#include "led.h"
#include "delay.h"
#include "usart.h"
#include "dma.h"uint8_t src_data[]= {'a','b','c','d'};int main(void)
{USART1_init();DMA1_init();printf("hello world!\r\n");DMA1_transmitData((uint32_t)src_data, (uint32_t)&(USART1->DR), 4);while (1){}
}

在这里插入图片描述
值得注意的是实验现象中hello word后面回车换行符号不见了,原因是进行DMA传输时,没有对串口缓冲区进行判空操作,直接将数据刷新进去,导致原来的数据没有发送完就直接覆盖掉。

为处理这个现象,可以在进行DMA传输之前适当延时。

2. HAL库实现

使用STM32CubeMX生成的代码,有关DMA的配置在串口配置文件中。

uint8_t src_data[] = {'a', 'b', 'c', 'd','e'};int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Transmit_DMA(&huart1,src_data,5);/* USER CODE END 2 */while (1){}
}
http://www.dtcms.com/a/479617.html

相关文章:

  • 百度一下首页网页百度企业seo排名哪家好
  • 辽阳做网站做php网站需要什么软件开发
  • 植物大战僵尸融合版,支持手机+电脑,附修改器!
  • 做网站需要哪些工程师网站添加文章
  • 网站开发与app差距网页制作与设计属于什么专业
  • 网站代理浏览器0网络营销公司全网天下
  • 使用Reindex迁移Elasticsearch集群数据详解(下)
  • 成都百度推广账户优化网站建设关键字优化
  • 设计素材网站版权连云港网站建设sitall
  • 雪花算法生成id
  • 去哪个网站可以接单做ps等等苏州建网站公司
  • wordpress修改侧边栏wordpress优化数据库
  • 成都网站制什么网站容易收录
  • 首都医科大学网站建设做网站最少几个页面
  • 肿瘤微环境介导的免疫耐受在胃癌发生和治疗中的作用
  • Spring Cloud微服务篇面试题总结
  • 刚学完网站开发设计师学编程能自己做网站吗
  • 织梦网站建设选项卡教程asp 精品网站制作
  • 宝宝树以“奇迹2.0”重构营销范式:AI驱动母婴行业迈向全域智能
  • 网站规划设计的步骤上海公司建设网站
  • 网站建设和维护价格腾讯云建站多少钱
  • 坡头手机网站建设公司推广普通话的内容
  • 课后作业-2025-10-12
  • 行业资讯网站有哪些手机一键生成户型图
  • 做网站赚钱什么类型good work wordpress
  • 刚做的网站 搜不到取消wordpress邮箱认证
  • 哪些网上订餐的网站做的好wordpress不能放flv
  • qiankun、micro-app、wujie,2025年我们该选谁?
  • 怎么做子网站网页设计素材背景图片
  • 于 C++ 的虚函数多态 和 模板方法模式 的结合