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。 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;
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即可正常完成打印。
独立模式–多通道DMA模式:
采集多路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
多重ADC交替采集
三重模式-单通道-交替采集
目的: 提高采样率 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);
主循环中添加如下代码:
printf("ADC1_L : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[0]*(3.3/4096));
printf("ADC2_H : %f V\r\n",(float)(ADC_ConverBuff[0]>>16)*(3.3/4096));
printf("ADC3_L : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[1]*(3.3/4096));
printf("ADC1_L : %f V\r\n",(float)(ADC_ConverBuff[1]>>16)*(3.3/4096));
printf("ADC2_H : %f V\r\n",(float)(uint16_t)ADC_ConverBuff[2]*(3.3/4096));
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模式、多重采样。根据不同的应用场景,采取不同的采样策略。
|