STM32-ADC_DMA

一、ADC

1、ADC简介

  1. ADC(Analog-Digital Converter)模拟-数字转换器
  2. ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
  3. 输入电压范围:03.3V,转换结果范围:04095(线性转换)

2、ADC基本结构

  • AD转换器:进行AD转换的地方
  • 触发控制:软件触发和硬件触发
  • EOC:转换完的标志
  • AD数据寄存器:存放AD转换的结果
  • 模拟看门狗:监测AD转换结果范围(超出阈值,会向NVIC申请中断,ADC_ITConfig)
  • 开关控制:用于给ADC上电的(类似于库函数中,ADC_Cmd函数)
示例图片

ADC_DMA

3、配置流程

  1. 开始ADC的外设时钟RCC
  2. 配置GPIO初始化结构体
  3. 配置输入通道
  4. 配置ADC初始化结构体
  5. 给ADC上电
  6. 校准固定流程(转换结束标志)
  7. 触发转换(获取ADC的转换的值,AD_GetValue)

二、DMA

1、DMA简介

  • DMA:Direct Memory Access,直接存储器存取
  • DMA可以提供外设存储器或者存储器存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源(协助CPU完成数据转运的工作
  • 外设—DMA—>存储器(硬件触发) 和 存储器—DMA—>存储器(软件触发)
  • 12个独立可配置的通道(数据转运的路径,转运一次占用一个通道): DMA1(7个通道), DMA2(5个通道)
  • 每个通道都支持软件触发特定的硬件触发

2、存储器映像

类型 起始地址 存储器 用途
ROM 0x0800 0000 程序存储器Flash 存储C语言编译后的程序代码 (文件)
0x1FFF F000 系统存储器 存储BootLoader,用于串口下载
0x1FFF F800 选项字节 存储一些独立于程序代码的配置参数
RAM 0x2000 0000 运行内存SRAM 存储运行过程中的临时变量
0x4000 0000 外设寄存器 存储各个外设的配置参数
0xE000 0000 内核外设寄存器 存储内核各个外设的配置参数

3、DMA基本结构

  • 起始地址:决定了数据从哪里来到哪里去
  • 数据宽度:制定了一次转运要按多大的数据宽度(字节Byte ,半字Half Word,字Word)来进行传输
  • 地址是否自增:转运一次挪个坑
  • 传输计数器:决定了数据传输的次数(自减)
  • 开关控制:DMA_Cmd使能
示例图片

4、配置流程(数组转运+DMA)

  1. 开启DMA外设时钟RCC
  2. 配置DMA初始化结构体DMA_InitTypeDef
    • 指定双方的存储器地址
    • 指定双方的传输数据宽度
    • 指定双方传输的时候,地址是否自增
  3. DMA使能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//传输数组的定义
uint8_t DateA[]={0X01,0X02,0X03,0X04};
uint8_t DateB[]={0,0,0,0};

void DMA_InitConfig(uint32_t AddrA,uint32_t AddrB,uint16_t size)
{
//DMA1结构体初始化
DMA_InitTypeDef DMA_InitStructure;
//指定传输方起始地址
DMA_InitStructure.DMA_PeripheralBaseAddr=AddrA;
//指定传输方传输位数
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
//指定传输方地址是否自增
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;

//指定接收方起始地址
DMA_InitStructure.DMA_MemoryBaseAddr=AddrB;
//指定接收方传输位数
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
//指定接收方地址是否自增
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;

//指定传输方向
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;

//指定传输数据大小(传输计数器)
DMA_InitStructure.DMA_BufferSize=size;
//是否使用自动重装
DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
//指定触发方式
DMA_InitStructure.DMA_M2M=DMA_M2M_Enable;
//指定传输通道优先级
DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;

//初始化DMA1的通道1
DMA_Init(DMA1_Channel1,&DMA_InitStructure);

//开关控制
DMA_Cmd(DMA1_Channel1, ENABLE);
}

int main(void)
{
//1、开启DMA1的外设时钟RCC
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

//2、初始化DMA1结构体
DMA_InitConfig((uint32_t)DateA,(uint32_t)DateB,4);

//3、查看转移结果
for(int i=0;i<4;i++)
{
printf("DateA[%d]=%d\n",i,DateA[i]);
printf("DateB[%d]=%d\n",i,DateB[i]);
}

while (1)
{

}
}