ADC就是模数转换,咱们要将电压大小的模拟量,通过采样量化为数字量获得一个数字的电压值。
通过查看原理图,咱们发现R37是一个滑动变阻器,而咱们能够经过软件把PB0设置成ADC输入引脚,就能够采集PB0引脚上的电压数据了
步骤以下:
1.使能时钟
这里咱们须要使能GPIOB和ADC1上的时钟,而且因为STM32的ADC最大转换速率为1Mhz,也就是转换时间为1us,不要让ADC的时钟超过14M,因此咱们须要对系统时钟进行分频。web
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6);
2.初始化GPIO,ADC
而后咱们对GPIO和ADC进行初始化svg
/* Configure PB.0 (ADC Channel 8) as analog input -------------------------*/ 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);
这里咱们把GPIO的模式设置为模拟输入函数
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的模式设置为独立模式,ADC_ScanConvMode是设置是否连续扫描,其实这里也能够设置为连续扫描。ADC_ContinuousConvMode是设置是否连续转换,这里选否。
咱们把硬件编译关上,让数据向右对齐,设置序列规则长度为1。
3.使能ADC并校准
而后咱们ADC还须要一个重校准的步骤学习
/* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1));
咱们先要使能ADC,这很关键,若是不先使能的话,后面的操做将没法执行。
而后咱们须要重启校准,记住咱们每次进行校准以后须要等待校准结束。这里是经过获取校准状态来判断是否校准是否结束的。
4.编写函数读取ADC值
我以为编写函数读取ADC的这个步骤是,配置ADC中比较关键的,由于其余的步骤咱们能够借鉴官方给咱们的固件库的代码,惟有这个是须要咱们从无到有打上去的,因此咱们要理解这个思路。ui
U16 Getadc(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; }
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
是用来配置通道的环境的一个函数,第一个入口参数为选的配置的ADC,第二个入口参数为选择配置的通道,第三个入口参数则配置ADC编号(例如使用ADC1,那么就写1),第四个入口参数则表明单次采样的时钟周期数。
然后咱们就能够经过软件去启动咱们的AD转换了
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
转换开启后咱们能够根据标志位EOC判断转换是否完成
这里能够得知咱们须要等待EOC从0变到1才能执行下一步,因此咱们就用while去判断EOC是否为0,是0的时候等待,不为0的时候跳出
而后这时候咱们就能够读取AD的值了,咱们用这个函数:
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
能够得到AD的值而后把它赋给Temp,而后返回Temp便可es5