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函数。
ADC使用的是DMA2的控制器的流0 通道0。
注意:配置ADCGPIO的时候配置成AIN。模拟输入。
ADC的两个结构体的初始化
章节—双重-多通道-规则同步
1、初始化ADC的GPIO多通道
2、配置ADC初始化结构体
3、配置通道的转换顺序,配置DMA(是否三个ADC的DMA都要配置?)、触发ADC的转换(主ADC触发即可)
双重ADC是数据传输的时候是把数据放到中转的ADDR寄存器里面,再把里面的数值放到变量里面。
基本配置
1、时钟配置
2、这里选择的时钟源是HSI高速内部时钟,配置为168MHz,经过分频之后得到APB2时钟为42MHz。
ADC的具体参数。
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);
实验现象:
接上串口调试助手之后,PB0接上3.3V电压可以看到打印如下信息。
注意:一开始打印乱码是因为外部时钟没有配置好,后来修改成HSI即可正常完成打印。
采集多路ADC的输入
配置DMA模式。
配置ADC1的通道4、5、6、7。
下面来看具体参数配置:
多通道DMA采样的配置的不同点:
1、使能扫描转换模式
2、开启DMA请求
3、开启规则转换通道数为4
4、配置规则转换的顺序。
紧接着配置DMA:
开启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);
实验效果如图:
PA4接着的是0V 其他引脚接着的是3.3V
目的: 提高采样率
1、初始化ADC的GPIO
2、配置ADC初始化结构体(三个ADC)
3、配置通道转换顺序、配置DMA(是否三个ADC都需要配置)、触发ADC开始转换
DMA配置主通道的流控制器
一个ADC的采样速率最快是2.4MHz,而三个ADC同时采样可以达到7.2MHz。使用3个ADC采集同一个通道。配置PC2。
实验工程配置:
ADC1配置:
ADC2配置:
ADC3配置:
DMA配置细节。
在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模式、多重采样。根据不同的应用场景,采取不同的采样策略。