蓝桥杯嵌入式开发经验分享(7.ADC的配置)

作者:马一飞                                                         QQ:791729359          

在学习过程中有什么问题可以联系

(原本资料是以网盘的方式公开提供给任何蓝桥杯爱好者进行下载的,但是最近临近蓝桥杯考试,遇到了很多伸手党,我无偿给爱好者们解答学习上的问题,回复得比较慢居然还有同学来说我这样那样,所以决定不再随意提供自己写的源码和资料。博主已经开始参加工作了,也不是闲着没事干盯着电脑手机为你们服务。记住,不要成为伸手党,要自己多动手实现。)

        大家都已经学到嵌入式了,那么就应该清楚什么叫ADC。ADC就是模数转换,把模拟的电压信号,转化为我们控制器所能识别的数字信号,这就叫ADC。

        那么我就来讲解CT117E开发板的ADC是怎么配置的。我们先观察一下CT117E开发板上的外设资源,我们能看到,在LED旁边有一个可变电阻器,那个可变电阻器就是拿来做ADC检测实验的。

        其次,我们再找到电路图变阻器所对应的引脚。

蓝桥杯嵌入式开发经验分享(7.ADC的配置)_第1张图片

        我们能看到这个可变电阻的另一端连接的是PB0引脚,同时我们查看下stm32f103rbt6的数据手册,发现PB0引脚可复用成ADC_IN8

        我们可以通过软件把PB0设置成ADC输入引脚,就可以采集PB0引脚上的电压数据了。

        那么我们开始对这个引脚进行编程,我们当然要先对PB0引脚进行初始化设置为模拟输入,同时还要吧PB时钟和ADC1时钟使能。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_ADC1,ENABLE);

RCC_ADCCLKConfig(RCC_PCLK2_Div6);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

        RCC_ADCCLKConfig(RCC_PCLK2_Div6);  这条语句的作用实际上就是对ADC时钟进行6分频,实际上我们不添加这条语句也可以,因为ADC时钟过快的话,可能会导致测得的AD值不准确,但是我们的蓝桥杯比赛倒不会影响,我的个人是习惯加上分频系数。(这个函数在RCC库函数里可以找到原型)

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1,&ADC_InitStructure);

        在配置好引脚之后,我们就可以开始对ADC进行配置了,我们在蓝桥杯的比赛中,只需要开启独立模式就OK了,我们并不需要用到连续转换模式,因此我们要把连续转换模式关闭,数据右对齐。 我们对stm32的ADC还要有一个概念,stm32的ADC分为规则组和注入组,具体两个类别有什么不同可以看看正点原子官方关于ADC的视频。但是我们对于蓝桥杯所用的ADC就比较简单,大家只需要按照我上面那样配置就可以了。

        在配置好ADC后我们还需要对ADC进行一个校准,具体的校准过程也比较简单。

ADC_Cmd(ADC1, ENABLE);
		
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus( ADC1));
ADC_StartCalibration( ADC1);
while(ADC_GetCalibrationStatus(ADC1));

        先复位校正,再开启校正。            有一点是需要注意的,我们在对ADC校准的前,必须把ADC使能ADC_Cmd(ADC1, ENABLE); 否则将卡在校准处程序卡死

        ADC1初始化完毕,那我们应该如何读取AD值呢?

u16 Get_Adc(u8 channel)
{
		u16 temp;
		ADC_RegularChannelConfig(ADC1, channel, 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;
}

我们先使用规则组通道初始化这个库函数来对ADC通道配置

第一个入口参数为选的配置的ADC,第二个入口参数为选择配置的通道,第三个入口参数则配置ADC编号(例如使用ADC1,那么就写1),第四个入口参数则代表单次采样的时钟周期数。

蓝桥杯嵌入式开发经验分享(7.ADC的配置)_第2张图片

我们就直接选择最大的周期(239周期),因为周期数越大,采样出来的信号就约准确,蓝桥杯比赛中并没有对速度的要求,因此我们确保采样准确。

 

而后我们就可以通过程序软件启动AD转换。

我们开启转换后,我们通过EOC标志位来判断转换是否完成。

我们查看stm32中文参考手册(第170页)

        当AD转换完成后,EOC标志位会置1,当我们AD转换未完成时,我们就一直等待,直到ADC采样结束后才读取AD数据。

采样结束后就可以通过获取ADC数据库函数对数据进行读取,在读取前我们还得知道,stm32f103rbt6的ADC是精度是12位了(也就是0~4096),因此我们读出来的AD值数据是12位的,用通俗的话来讲就是把3.3V分成4096份。

        然后返回AD值,那么我们一个ADC采样函数就写好了,我们可以对PB0引脚进行AD采样。

在主函数中:

蓝桥杯嵌入式开发经验分享(7.ADC的配置)_第3张图片

我们用定时器先设定每500ms读取一次AD值。 我们事先知道PB0引脚对应的是第8通道,我们直接Get_Adc(8)即可获取PB0的AD值。

我们再把获取出来的AD值经过公式换算成电压值,显示到我们的LCD显示屏上。

 

我们把程序烧录到开发板里看看。

蓝桥杯嵌入式开发经验分享(7.ADC的配置)_第4张图片蓝桥杯嵌入式开发经验分享(7.ADC的配置)_第5张图片

        转动可变电阻,我们发现ADC的值随着我们的转动而改变,那么我们这个ADC采样程序是没有问题了。

                                                                                                                                (以上仅属于个人观点)

 

 

你可能感兴趣的:(蓝桥杯)