作者:闫永成 QQ:793805481
ADC是模数转换器即A/D转换器的简称,通常是指一个将模拟信号转变为数字信号的电子元件。通常的模数转换器是将一个输入电压信号转换为一个输出的数字信号。STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。下面,我们就直接讲解如何配置蓝桥杯嵌入式板子上的ADC。
板子上在LED下边有一个电位器(R37),电位器的另一端M PB0可以作为ADC的输入(PB0可复用为ADC_IN8),即调节电位器的位置可以输入不同的电压值(模拟量)。然后,我们就可以配置ADC了。
同样,需要添加adc.c和adc.h文件我们就不再过多介绍了,值得注意的一点是我们需要添加一个stm32f10x_adc.c文件进入工程,文件目录为CT117E-LCD\Libraries\STM32F10x_StdPeriph_Driver\src,然后再点击魔法棒把路径也包含进去。接下来,直接看程序部分:
ADC初始化
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
//开启ADC1时钟和GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入模式
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_InitStruct.ADC_ScanConvMode=DISABLE;//不开启扫描模式
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//不连续
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
ADC_InitStruct.ADC_NbrOfChannel=1;
ADC_Init(ADC1,&ADC_InitStruct);//ADC初始化的相关配置
ADC_Cmd(ADC1,ENABLE);//使能ADC
//ADC校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));//等待
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));//等待
}
1.配置GPIOB,把PB0设置为模拟输入。
2.ADC_Init(ADCx,&ADC_InitStruct)的功能是:根据ADC_InitStruct中指定的参数,初始化ADCx外设。蓝桥杯里边涉及的配置比较简单,只需要开启独立扫描模式,并不需要用到连续转换模式,我们要把连续转换模式关闭关闭即可,数据右对齐,还有就是关于规则通道和注入通道的配置,我们只需要记着向上面那样配置即可(想要更多的了解,可以看一下正点原子视频相关的讲解)。
3.ADC校准,在校准之前必须先要使能ADC,否则会失败。校准用到的函数在stm32f10x_adc.h文件里边可以找到,在这里我们先记住这几个函数,在文末的补充中,会介绍如何快速找到这些东西。
获得ADC转换值函数
u16 GET_Adc(void)
{
u16 temp;
ADC_RegularChannelConfig(ADC1,8,1,ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启转换
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);
temp=ADC_GetConversionValue(ADC1);//得到转换值
ADC_SoftwareStartConvCmd(ADC1,DISABLE);//一次转换完成后先关闭软件转换
return temp;
}
1.ADC_RegularChannelConfig(ADC1,8,1,ADC_SampleTime_239Cycles5)
的功能:为选定的ADCx规则通道配置它在定序器中的相应排名和它的采样时间,第一个入口参数为选的配置的ADC,第二个入口参数为选择配置的通道(我们能用的只有通道8),第三个入口参数则配置ADC编号(例如使用ADC1,那么就写1),第四个入口参数则代表单次采样的时钟周期数,直接选择最大的周期(239周期),因为周期数越大,采样出来的信号就约准确,蓝桥杯比赛中并没有对速度的要求,因此我们确保采样准确。
2.ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启转换
,开启转换后,我们通过EOC标志位来判断转换是否完成,当EOC标志位为1时表示转换完成,我们得到转换值返回即可。注意:ADC的精确位是12位,因此我们读出来的数据是12位数据,若要得到真正的电源值需要计算:GET_Adc()*3.3/4096(12位 即0~4095,4096份)。
调用
然后,就可以在LCD上显示获取的电压值了。
转动电位器,会显示不同的值。
补充:
12 位ADC逐次逼近型的模拟数字转换器工作原理
逐次逼近转换过程和用天平称物重非常相似。天平称重物过程是,从最重的砝码开始试放,与被称物体行进比较,若物体重于砝码,则该砝码保留,否则移去。再加上第二个次重砝码,由物体的重 量是否大于砝码的重量决定第二个砝码是留下还是移去。照此一直加到最小一个砝码为止。将所有留下的砝码重量相加,就得此物体的重量。仿照这一思路, 逐次比较型A/D转换器,就是将输入模拟信号与不同的参考电压作多次比较,使转换所得的数字量在数值上逐次逼近输入模拟量对应值。具体请点击这里
利用固件库模板快速编写程序
赛点资源包里边提供的固件库里边有一些基本的模板,相关的基本框架已经给出,在编写程序时是可以直接使用的,只需要修改部分引脚等,能帮助我们快速编写程序。例如本篇ADC的程序就可以参考下边的。
路径: 02.赛点资源数据包_嵌入式_2019\6-STM32固件库代码V3.5版\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\ADC\ADC1_DMA