了解STM32 ADC模拟数字转换器工作原理和应用
ADC(Analog-Digital Converter)模拟-数字转换器
将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。
STM32为12为逐次逼近型ADC,1us的转换时间。
输入电压为0~3.3V,转换结果范围为0~4095。
一共有18个输入通道,可测量16个外部和2个内部信号源。
有规则组和注入组连个转换单元(一次性启动一个组转换多个值)。
模拟看门狗自动检测输入电压范围。
ADC框图
输入通道
规则通道(最多16个通道,称为序列1~16)转换模式
单次转换,非扫描模式
组中16个序列只有第一个序列选中的通道有效,触发转换,转换完成后EOC标志位置1。
换通道转换可以在转换前更换通道。
连续转换,非扫描模式
还是一个通道,一次转换后不会停止,会自动进行下一次danc
单次转换,扫描模式
设置几个序列(1~16)有效,每次开始转换完一整个序列的通道数据。第二次从序列1开始
连续转换,扫描模式
在单次转换,扫描模式的基础上,一次转换完成后,立刻开始第二次的转换。
间断模式(在扫描模式的基础下)
每隔几个转换就暂停一次,需要再次触发才能继续。
扫描模式最好配合DMA进行使用防止数据被覆盖,只有ADC1和ADC3拥有DMA功能,由ADC2转化的数据可以通过双ADC模式,利用ADC1的DMA功能传输。
触发控制
数据对齐
转换结果为12位的数据,但是数据寄存器是16位的。一般采用右对齐,左对齐数据比实际大,直接读结果比实际大16倍。
左对齐可以取高八位减少精度。
转换时间
ADC配置
1.开启RCC时钟,包括ADC和GPIO时钟,ADCCLK分频器也需要配置
2.配置GPIO模拟输入模式
3.配置多路开关,把通道接入规则组列表
4.配置ADC转换器
5.开启ADC
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
/*设置ADC时钟*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0引脚初始化为模拟输入
/*规则组通道配置*/
//规则组序列1的位置,配置为通道0
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
/*ADC初始化*/
ADC_InitTypeDef ADC_InitStructure; //定义结构体变量
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //模式,选择独立模式,即单独使用ADC1
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐,选择右对齐
//外部触发,使用软件触发,不需要外部触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//连续转换,失能,每转换一次规则组序列后停止
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
//扫描模式,失能,只转换规则组的序列1这一个位置
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
ADC_InitStructure.ADC_NbrOfChannel = 1;
//将结构体变量交给ADC_Init,配置ADC1
ADC_Init(ADC1, &ADC_InitStructure);
/*ADC使能*/
ADC_Cmd(ADC1, ENABLE); //使能ADC1,ADC开始运行
/*ADC校准*/
ADC_ResetCalibration(ADC1); //固定流程,内部有电路会自动执行校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
之后软件触发AD转换
等待EOC标志位,即等待AD转换结束
读数据寄存器,得到AD转换的结果