ADC:模拟数字转换器,ADC可以将引脚上变化的模拟电压转换为内存中储存的数字变量,建立起模拟电路道数字电路的桥梁。ADC输入电压范围0~3.3v,转换结果为0到4095.
基本原理:
ADC首先接收输入的模拟信号,并将其与参考电压进行比较。参考电压通常是ADC的工作电压范围的一部分,用来确定模拟输入信号的大小。ADC会将比较器的输出初始化为0,并根据比较结果决定下一步要比较的信号范围。:ADC从最高有效位(Most Significant Bit,MSB)开始,根据比较器的输出逐位逼近输入信号的数字表示。具体步骤如下:
-
首先,ADC将待转换的模拟信号的MSB置为1,然后与当前的逼近值进行比较。
-
如果比较结果显示输入信号的这一位大于逼近值,ADC会将这一位设为1,并继续下一位。
-
如果比较结果显示输入信号的这一位小于逼近值,ADC会将这一位设为0,并继续下一位。
1.配置流程
如上图ADC的基本结构所示,在使用ADC数模转换的过程中首先需要打开,然后需要使用的外设有GPIO。在使用过程中需要配置GPIO的结构,使其符合ADC工作的要求,在配置好GPIO口后,配置AD转换器要选着使用规则组还是注入组。然后在进行触发控制,与AD数据寄存器的配置。中断看门狗依照自己需求配置。
-
规则组:规则组是ADC的主要工作模式,用于常规的模拟信号转换。在规则组中,ADC按照预定义的规则序列进行模拟信号的转换。每次启动转换时,ADC会依次转换规则组中每个通道的模拟信号,并将结果存储在规则组的结果寄存器中。
-
注入组:注入组是ADC的另一种工作模式,用于需要高优先级和即时响应的模拟信号转换。在注入组中,ADC可以在规则组转换期间插入对注入组中通道的转换。这意味着,当有高优先级的信号需要立即转换时,可以触发注入组的转换,而不必等待规则组转换完成。
初始化AD函数
void AD_Init(void)
{
//第一步,打开RCC时钟,分别打开GPIO和ADC时钟
//打开GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//打开ADC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
//将RCC时钟分频输入进ADC比较模块中
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
//第二步配置GPIO模式
GPIO_InitTypeDef GPIO_InitStruct;
//选择此模式使GPIO口不受其他电压影响
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//第三步,配置ADC
//ADC规则通道配置,选择ADC1外设,使用0通道,放在1的次序,选择55个周期
//ADC结构配置
ADC_InitTypeDef ADC_InitStructure; //定义结构体变量
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent ;
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right ;
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_NbrOfChannel=1;
ADC_InitStructure.ADC_ScanConvMode=DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
//ADC结构体初始化
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
//校准设置
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
}
获取值函数
int AD_GetValue(int Channel)
{
ADC_RegularChannelConfig(ADC1,Channel,1,ADC_SampleTime_55Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发AD转换一次
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //等待EOC标志位,即等待AD转换结束
return ADC_GetConversionValue(ADC1); //读数据寄存器,得到AD转换的结果
}