STM32CubMX自学笔记(九)---ADC+DMA数模转换实验

STM32CubMX自学笔记(九)—ADC+DMA数模转换实验

ADC初始化结构体讲解,

库函数介绍

1、配置分辨率,转换模拟量的时间大小。配置的是控制寄存器1位。
2、扫描模式针对多通道,单通道的时候disable,多通道的时候enable。
3、连续转换还是单次转换,采集完成一个点就不采集了。采集完一个点继续采集,那么就配置成连续转换。
4、外部触发,高低电平,上升沿、下降沿、或者二者皆可。一般用软件自动触发,
5、规则数据寄存器,数据是怎么放的?左对齐还是右对齐。
6、ADC转换的通道,规则通道配置的规则序列寄存器,16个配置。注入序列寄存器,最多有四个通道。
ADC_CommonInitTypeDef初始化结构体
1、只需要配置一次,模式选择,双重模式或者三重模式。
2、分频,看APB2的总线的时钟然后配置,最大为84M ,最大是32M。不能是2分频。最好是4分频,针对F407。
3、DMA 双重或者多重的时候才需要配置。

常用的库函数

紧接着配置规则通道的转换顺序。
1、使用哪一个ADC。
2、使用哪一个通道。
3、通道的转换顺序。
4、配置采样时间。
紧接着是 使能ADC、软件触发转换。
单重ADC 的DMA传输。 ADC DMA的请求,ADC_DMACmd。

独立模式单通道采集

模数转换之后,将数据放在ADC_DR寄存器,产生一个中断,在中断中将采集到的数据放到sram中,在中断中将SRAM中的数据读取走。
例程讲解:
1、开启时钟,使能GPIO
2、初始化ADC的结构体。
(1)ADC_Common结构体初始化
1、独立模式
2、分频因子选择二分频,最高还是36M,所以还是36M。即使是APB2是84M
3、两个ADC采样的延时时间,是双重或者三重的时候才配置。
(2)ADC_Init结构体初始化
1、配置为12位ADC
2、失能扫描模式
3、软件触发
4、数据右对齐
5、转换通道1个
(3)配置通道的转换顺序(具体ADC,具体通道,通道数目,采样周期56),ADC中断配置,失能ADC转换。
(4)配置中断,1是中断号,2是中断服务函数,判断是否是结束转换中断,返回值赋值给一个外部变量。然后清除中断标志位。全局变量是从ADC_DR寄存器中采集的,再定义一个局部变量,把数字量转换成模拟量。
独立模式-多通道采集-使用DMA:
1、ADC_DR寄存器的低十六位。
2、使用DMA请求不需要产生中断,产生DMA数据,直接传输到变量里面。
编程要点:
1、初始化ADC的多个GPIO
2、配置ADC初始化结构体、DMA初始化结构体
3、配置通道的转换顺序、使能DMA请求、使能DMA、打开ADC、触发ADC开始转换。
4、编写main函数。

库函数DMA控制器配置

ADC使用的是DMA2的控制器的流0 通道0。
注意:配置ADCGPIO的时候配置成AIN。模拟输入。
ADC的两个结构体的初始化

章节—双重-多通道-规则同步
1、初始化ADC的GPIO多通道
2、配置ADC初始化结构体
3、配置通道的转换顺序,配置DMA(是否三个ADC的DMA都要配置?)、触发ADC的转换(主ADC触发即可)
双重ADC是数据传输的时候是把数据放到中转的ADDR寄存器里面,再把里面的数值放到变量里面。

CubMx工程配置

基本配置
1、时钟配置
2、这里选择的时钟源是HSI高速内部时钟,配置为168MHz,经过分频之后得到APB2时钟为42MHz。
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第1张图片ADC的具体参数。
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第2张图片
1、首先配置配置设置成独立模式。
2、ADC的配置成4分频,因为ADC的最高频率为36MHz,ADC最稳定的工作频率是30MHz,而APB2总线上的时钟频率最高为84Mhz,因此配置为4分频最后的结果是21MHz符合要求。
3、 转换周期 = 采样周期+存储时间 = 3 + 12 = 15周期 = 1/21M*15 = 0.47us>0.41us
采样时间:最少为3个周期
4、对齐模式选择为右对齐。
5、扫描转换模式不使能(多通道采集ADC时,才需要使能)
6、开启连续转换
7、非连续转换不使能
8、DMA请求不使能
9、结束中断标志设置为每完成一次中断就发出一个标志位
10、规则通道数目1个
11、规则通道由软件触发
12、转换完成标志 不使能
13、等级为1
14、注入转换模式的个数为 0 个
15、不使能看门狗。

至此,可以完成最简单的ADC采样配置。

ADC的具体参数。

代码

开启ADC接收完成中断:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
     
	/*获取结果*/
	ADC_ConvertValue = HAL_ADC_GetValue(&hadc1);
}

在adc.c的c文件中开启ADC的中断

HAL_ADC_Start_IT(&hadc1);

在主函数中编写如下代码:

float ADC_Vol;

在main函数中编写如下代码:

  uint8_t buff[128] = {
     0};

		ADC_Vol =(float) ADC_ConvertValue/4096*(float)3.3; // 读取转换的AD值
		printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertValue); 
		printf("\r\n The current AD value = %f V \r\n",ADC_Vol);  
		HAL_Delay(500);

实验现象:

STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第3张图片

接上串口调试助手之后,PB0接上3.3V电压可以看到打印如下信息。

注意:一开始打印乱码是因为外部时钟没有配置好,后来修改成HSI即可正常完成打印。

独立模式–多通道DMA模式:

采集多路ADC的输入
配置DMA模式。
配置ADC1的通道4、5、6、7。

STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第4张图片

下面来看具体参数配置:

STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第5张图片

多通道DMA采样的配置的不同点:
1、使能扫描转换模式
2、开启DMA请求
3、开启规则转换通道数为4
4、配置规则转换的顺序。
紧接着配置DMA:
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第6张图片

开启ADC1,配置为循环模式,一个字节32位,字宽配置为半字16位。
代码:
首先定义一个数组,存放DMA存储的数据。

uint16_t ADC_ConvertedValue[4];

其次使能ADC并且开启ADC的DMA功能:

__HAL_ADC_ENABLE(&hadc1);
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_ConvertedValue,4);

最后打印出不同通道的ADC数值:

		printf("PA4 = %fV\r\n",(float)(ADC_ConvertedValue[0]/4096.0*(float)3.3));
		printf("PA5 = %fV\r\n",(float)(ADC_ConvertedValue[1]/4096.0*(float)3.3));
		printf("PA6 = %fV\r\n",(float)(ADC_ConvertedValue[2]/4096.0*(float)3.3));
		printf("PA7 = %fV\r\n",(float)(ADC_ConvertedValue[3]/4096.0*(float)3.3));
		printf("\r\n");
		HAL_Delay(1000);

实验效果如图:
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第7张图片
PA4接着的是0V 其他引脚接着的是3.3V

多重ADC交替采集

三重模式-单通道-交替采集

目的: 提高采样率
1、初始化ADC的GPIO
2、配置ADC初始化结构体(三个ADC)
3、配置通道转换顺序、配置DMA(是否三个ADC都需要配置)、触发ADC开始转换
DMA配置主通道的流控制器
一个ADC的采样速率最快是2.4MHz,而三个ADC同时采样可以达到7.2MHz。使用3个ADC采集同一个通道。配置PC2。
实验工程配置:
ADC1配置:
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第8张图片ADC2配置:
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第9张图片
ADC3配置:
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第10张图片DMA配置细节。
STM32CubMX自学笔记(九)---ADC+DMA数模转换实验_第11张图片

实验代码

在main.c添加如下代码

uint16_t ADC_ConverBuff[3000];

紧接着开启ADC三个通道,分别是3、2、1,顺序不可颠倒

HAL_ADC_Start(&hadc3);
	HAL_ADC_Start(&hadc2);
	HAL_ADC_Start(&hadc1);
	HAL_ADCEx_MultiModeStart_DMA(&hadc1,(uint32_t *)ADC_ConverBuff,3000);

主循环中添加如下代码:

//ADC1
		printf("ADC1_L : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[0]*(3.3/4096));
		//ADC2
		printf("ADC2_H : %f V\r\n",(float)(ADC_ConverBuff[0]>>16)*(3.3/4096));
		//ADC3
		printf("ADC3_L : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[1]*(3.3/4096));
		//ADC1
		printf("ADC1_L : %f V\r\n",(float)(ADC_ConverBuff[1]>>16)*(3.3/4096));
		//ADC2
		printf("ADC2_H : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[2]*(3.3/4096));
		//ADC3
		printf("ADC3_L : %f V\r\n",(float)(ADC_ConverBuff[2]>>16)*(3.3/4096));
		printf("\r\n");
		HAL_Delay(1000);

结语

ADC实验总共分为两大部分,首先介绍了库函数实现ADC采样,紧接着,又通过HAL库的CUBmx配置实现ADC采样。分为单通道独立模式、单通道DMA模式、多通道DMA模式、多重采样。根据不同的应用场景,采取不同的采样策略。

你可能感兴趣的:(stm32,单片机,物联网)