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

DMA直接存储器访问

1.DMA概述

高速数据总线, 可以不依赖MCU执行指令,之间将数据按照配置,从A端到B端。例如

int a = 10;
int b = 20;
a = b;

以上代码内容,都需要MCU执行整个过程,包括变量定义,数据赋值等操作,对应MCU而言在硬件端可以采用DMA模式进行优化。降低MCU的参与。

希望MCU只是用于处理业务逻辑,数据处理,数据阈值判断的,而数据搬运过程,不通过MCU执行,降低MCU压力,利用DMA高速数据中线进行点到点的数据搬运操作。

DMA解决的问题

  • 降低 MCU 参与数据搬运的赋值管理过程,降低 MCU 的执行压力

  • 利用 DMA 高速数据总线特征,提供数据的传递速度。

1.2DMA主要特征

1.3DMA框图

1.4DMA映射关系【重点】

1.4.1DMA1映射关系框图和表格

1.4.2DMA2映射关系框图和表格

1.5DMA开发流程概述

DMA是一个数据搬运通道,配置完成之后,不占用MCU资源,同时对于内存的消耗较小。DMA不占用内存。需要知道【数据源地址】和【数据目标地址】

  • 数据源需要配置和提供的内容
    • 数据源地址,存储器地址或者外设设备数据地址
    • 数据宽度/数宽,全字(4字节)半字(2字节)字节(1字节)
    • 数据增量,从指定内存地址提取数据之后,根据当前数宽跳转到下一个数据位置,需要告知增量范围。类似于数组作为函数的参数,需要提供地址和数据有效元素个数(size)/数组容量(capacity)
      • 例如ADC的注入转换通道。转换结果数据一共是4*16bit,每一个数据对2字节,总计四组数据,8个字节
      • 设置数据源地址ADC注入转化通道数据结果地址,数据宽度/数宽 设置为半字,数据增量设置为4,DMA可以将ADC注入通道的所有数据搬运到目标地址
    • 数据目标DEST
      • 数据源地址,存储器地址或者外设设备数据地址
      • 数据宽度/数宽,全字(4字节)半字(2字节)字节(1字节)
      • 数据增量,从指定内存地址提取数据之后,根据当前数宽跳转到下一个数据位置,需要告知增量范围。类似于数组作为函数的参数,需要提供地址和数据有效元素个数(size)/数组容量(capacity)

1.6DMA相关寄存器

1.6.1DMA中断相关寄存器

1.6.2DMA数据地址相关寄存器

1.6.3DMA_CCRx 寄存器【重点】

1.6.4DMA_CNDTRx 通道传输数据个数寄存器

1.7光敏传感器ADC数据利用DMA进行数据搬运

1.7.1原理图和寄存器分析

  • ADC 采样光敏传感器数据相关内容已完成开发。

  • 根据原理分析,和 DMA 映射关系分析,需要开启 DMA2 通道 5,根据当前数据情况完成开

  • DMA2 时钟使能 ==> AHBENR

  • DMA2 通道 5 对应源地址和目标地址处理

    • 源地址 src ==> ADC3_DR ADC3 的数据寄存器。

    • 目标地址 dst ==> 选择 u16 类型的变量作为当前数据的目标存储空间,需要提供当前变量的首地址作为 DMA 数据存储端的【目标地址】

  • DMA2_Channel5 配置

    • MEM2MEM [位14] ==> 当前数据是从 ADC 到内存,属于外设到内存,选择 0 外设到内存模式

    • PL [位 13:12] ==> 当前通道优先级,选择 11 最高,10 高, 01 中, 00 最低

    • MSZIE[位11:10] ==> 存储器数宽,对应当前用于作为存储目标的 u16 类型变量,对应数据类型占用内存空间为 2 字节,选择半字 ==> 01

    • PSZIE[位9:8] ==> 外设数据宽度,对应 ADC->DR ,考虑到 ADC 规则数据存储器为 2 个字节,当前设置为 半字 ==> 01

    • MINC[位7] ==> 存储器地址增量,当前数据不需要增量处理,==> 0

    • PINC[位6] ==> 外设地址增量,当前数据不需要增量处理,==> 0

    • CIRC[位5] ==> 循环模式打开,需要进行 ADC 数据连续采样 ==> 1

    • DIR[位4] ==> 当前操作是外设到内部存储器 ==> 0

    • EN[位0] ==> DMA 打开 ,需要 ==> 1

  • 0011 0101 0010 0001 ==> 0x3521

1.7.2 代码实现

其他代码实现参考上一篇ADCADC 模拟量转数字量-CSDN博客

#include "adc.h"
u16 adc_dma_value = 0;
void LSEN_Init(void)
{
/*
1.RCC 时钟使能,需要使能有 GPIOF 和 ADC3
因为当前光敏电阻对应 GPIO PF8 ,ADC 通道是 ADC3_IN6
*/
RCC->APB2ENR |= GPIOF_RCC_APB2_CLOCK_ENABLE | ADC3_RCC_APB2_CLOCK_ENABLE;
/*
2. GPIOF 对应 PF8 配置为【模拟输入模式】
对应 GPIOF->CRH [CNF8:MODE8]
*/
GPIOF->CRH &= ~(0x0F);
/*
3. ADC 配置
*/
/*
3.1 ADCCLK 对应 APB2 预分频倍数配置,对应寄存器是
RCC->CFGR, 设置预分配倍数位 6. ADCCLK 对应 12MHz
*/
RCC->CFGR &= ~(0x03 << 14);
RCC->CFGR |= (0x02 << 14);
/*
3.2 ADC 采用周期时间控制
Tconv = 采样时间 + 12.5个周期 官方 ADC 规定周期。
一般情况下采样周期越长,对应的 ADC 数据精度越高。
239.5 + 12.5 周期。
*/
ADC3->SMPR2 |= (0x07 << 18);
/*
3.3 ADC 工作通道配置
选择规则通道进行 ADC 转换,同时开放一个转换通道。
对应 ADC3_IN6
*/
ADC3->SQR1 &= ~(0x0F << 20); // ADC 规则通道开始一个转换通道
ADC3->SQR3 &= ~(0x1F); // 擦除 ADC3 规则转换通道第一个转换通道原本数据
ADC3->SQR3 |= (0x06); // 赋值 ADC3 规则转换通道第一个转换通道对应 ADC3_IN6
/*
3.4 ADC CR 配置
CR1
DUALMOD[3:0] [位19:16] 配置 ADC 独立模式 ==> 0000
SCAN [位8] 关闭 ADC 扫描模式 ==> 0
CR2
SWSTART [位22] 开启规则转换通道 ==> 1
EXTTRIG [位20] 规则转换通道外部触发方式开始 ==> 1
EXTSEL[2:0] [位19:17] 选择启动规则通道组转换的外部事件 ==> 111
明确为软件触发当前 ADC 转换。
ALIGN [位11] 转换结果数据对齐方式 ==> 0 右对齐
CONT [位1] 连续转换 ==> 1 连续转换模式
*/
ADC3->CR1 &= ~(0x0F << 16); // DUALMOD[3:0] [位19:16]
ADC3->CR1 &= ~(0x01 << 8); // SCAN [位8]
ADC3->CR2 &= ~(0xFFFFFFFF);
ADC3->CR2 |= (0x01 << 22); // SWSTART [位22]
ADC3->CR2 |= (0x01 << 20); // EXTTRIG [位20]
ADC3->CR2 |= (0x07 << 17); // EXTSEL[2:0] [位19:17]
ADC3->CR2 |= (0x01 << 1);
// 【DMA 模块开发补充内容】 ADC3 开启 DMA 支持
ADC3->CR2 |= (0x01 << 8);
/*
因为整个 ADC3->CR2 已经进行整体擦除操作,对应 ALIGN 无需再次赋值。
*/
/*
3.5 ADC 校准和开启
需要在 ADC 时钟,通道和其他相关配置完成之后,才可以开启校准。
ADC 自校准 + 重启过程
需要利用 ADC CR2 配置寄存器完成
RSTCAL [位3] 复位校准
CAL [位2] AD 校准
ADON [位0] AD 转换模块开启
*/
// 3.5.1 ADC 关闭掉电,重启
ADC3->CR2 &= ~(0x01); // ADC 关闭断电
Delay_ms(10); // 延时 10 ms
ADC3->CR2 |= 0x01; // ADC 打开
/*
3.5.2 ADC 开启复位校准
需要对 CR2 寄存器 RSTCAL 位赋值为 1,如果 复位校准完毕
硬件会将对应 RSTCAL 位置为 0.
1 ==> 开启复位校准
0 ==> 硬件复位校准结束
*/
ADC3->CR2 |= (0x01 << 3); // 开启复位校准
while (ADC3->CR2 & (0x01 << 3)); // 等待硬件将对应寄存器位置为 0,校准结束
Delay_ms(10); // 延时 10 ms
/*
3.5.3 ADC A/D 校准
需要对 CR2 寄存器 CAL 位赋值为 1,如果 复位校准完毕
硬件会将对应 CAL 位置为 0.
1 ==> 开启 A/D 校准开启
0 ==> 硬件 A/D 校准结束
*/
ADC3->CR2 |= (0x01 << 2); // 开启 A/D 校准
while (ADC3->CR2 & (0x01 << 2)); // 等待硬件将对应寄存器位置为 0,校准结束
ADC3->CR2 |= 0x01; // ADC 打开
/*
DMA 模块开发
1. 因为当前 ADC 模块为 ADC3。根据 MCU 框图分析,对应的 DMA 模块
为 DMA2,通道 Channel5
【时钟使能 DMA2】
*/
RCC->AHBENR |= DMA2_RCC_AHB_CLOCK_ENABLE; // (0x01 << 1);
// 2. 【DMA 模块开发补充内容】 Line:69
/*
3. 设置源地址和目标地址
DMA 外设地址 ==> ADC3->DR 转换完成数据寄存器
DMA 存储地址 ==> 当前 adc.c 中 adc_dma_value 变量地址
*/
DMA2_Channel5->CPAR = (u32)(&(ADC3->DR)); // DMA 外设地址 配置
DMA2_Channel5->CMAR = (u32)(&adc_dma_value); // DMA 存储器地址 配置
/*
4. DMA 每次搬运的数据数量,有且只有一路 ADC,对应数据为 2 字节,一个数据
*/
DMA2_Channel5->CNDTR = 1;
/*
5. DMA2_Channel5 核心配置 【重点】
- MEM2MEM [位14] ==> 当前数据是从 ADC 到内存,属于外设到内存,选择 0 外设到内存模
式
- PL [位 13:12] ==> 当前通道优先级,选择 11 最高,10 高, 01 中, 00 最低
- MSZIE[位11:10] ==> 存储器数宽,对应当前用于作为存储目标的 u16 类型变量,对应数
据类型
占用内存空间为 2 字节,选择半字 ==> 01
- PSZIE[位9:8] ==> 外设数据宽度,对应 ADC->DR ,考虑到 ADC 规则数据存储器为 2
个字节,
当前设置为 半字 ==> 01
- MINC[位7] ==> 存储器地址增量,当前数据不需要增量处理,==> 0
- PINC[位6] ==> 外设地址增量,当前数据不需要增量处理,==> 0
- CIRC[位5] ==> 循环模式打开,需要进行 ADC 数据连续采样 ==> 1
- DIR[位4] ==> 当前操作是外设到内部存储器 ==> 0
- EN[位0] ==> DMA 打开 ,需要 ==> 1
*/
DMA2_Channel5->CCR = 0;
/*
DMA2_Channel5->CCR &= ~(0x01 << 14); // MEM2MEM
DMA2_Channel5->CCR |= (0x03 << 12); // PL
DMA2_Channel5->CCR |= (0x01 << 10); // MSZIE
DMA2_Channel5->CCR |= (0x01 << 8); // PSZIE
DMA2_Channel5->CCR &= ~(0x01 << 7); // MINC
DMA2_Channel5->CCR &= ~(0x01 << 6); // PINC
DMA2_Channel5->CCR |= (0x01 << 5); // CIRC
DMA2_Channel5->CCR &= ~(0x01 << 4); // DIR
DMA2_Channel5->CCR |= 0x01; // EN
*/
DMA2_Channel5->CCR = 0x3521;
}
u16 LSEN_GetValue(void)
{
return adc_dma_value;
}

http://www.dtcms.com/a/512620.html

相关文章:

  • 电话销售怎么做 网站临沂森拓网络科技有限公司
  • 在网上招标做兼职的网站建设网站装配式建筑楼房
  • 360°客户视图:MDM/CDP如何驱动实时个性化服务?
  • JavaScript 与 React 工程化实践对比
  • 【完整源码+数据集+部署教程】【天线&其他】建筑损毁程度检测评估系统源码&数据集全套:改进yolo11-Parc
  • 24991-53-5,Amine-PEG-Amine的化学结构与反应活性
  • Java:创建、读取或更新 Excel 文档
  • 广州免费建站找哪家网站企业备案资料
  • (二)Flutter插件之Android插件开发
  • 贵港seo关键词整站优化ps如何做psd模板下载网站
  • 雄安做网站优化的公司企业官方网站的作用
  • 中国建设行业峰会官方网站营销公司有哪些
  • 用wireshark进行手机app抓包教程-2025最新
  • 建设网站应注意什么河北提供网站建设公司电话
  • Ubuntu22.04-Cuda12.1 安装 Detectron2
  • STM32电池管理系统(BMS):电量统计原理与实现
  • 海外免费网站推广有哪些wordpress编辑器 插件
  • Java 黑马程序员学习笔记(进阶篇20)
  • Google 推荐 ViewBinding 作为 DataBinding 的轻量级替代
  • AI体测设备哪家口碑好
  • 阿里云 企业 网站城市介绍网站模板
  • 株洲网站建设团队萧山区建设工程质量监督站网站
  • 【CTF | 比赛篇】Newstar ctf web
  • MySQL decimal类型+IN查询异常:为何非目标数据被检出?
  • 浙江荣盛建设集团网站wordpress自动排版
  • 网站界面设计工具怎样申请电子邮箱
  • 构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
  • 好用的外贸网站深圳网络推广培训学校
  • 第5章—STM32工程创建
  • 网站建设公司宣传标语用百度地图 做gis网站