STM32F4之ADC
一、写在前面
开发工具: KEIL
外设库版本: V1.8.0
使用芯片: STM32F407
二、ADC简介
对于ADC来说,通常关心这几个方面:
1.ADC的分辨率:对于STM32F4的最高分辨率为12位。
2.ADC的转换时间。
3.ADC的参考电压。
三、代码解析
该例子初始化了ADC1的PA5口,使用软件触发的方式完成ADC转换。
1.ADC初始化
static void AdcInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);/* 使能GPIOA时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* 使能ADC1时钟 */
/* 初始化IO口 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; /* 模拟输入 */
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /* 不带上下拉 */
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); /* ADC1复位 */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);/* 复位结束 */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;/* 独立模式 */
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;/* 两个采样阶段之间的延迟5个时钟 */
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; /* DMA失能 */
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;/* 预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz */
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;/* 12位模式 */
ADC_InitStructure.ADC_ScanConvMode = DISABLE;/* 非扫描模式 */
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;/* 关闭连续转换 */
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;/* 禁止触发检测,使用软件触发 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;/* 右对齐 */
ADC_InitStructure.ADC_NbrOfConversion = 1;/* 1个转换在规则序列中 也就是只转换规则序列1 */
ADC_Init(ADC1, &ADC_InitStructure);/* ADC初始化 */
/* 设置指定ADC的规则组通道,一个序列,采样时间 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles );/* ADC1,ADC通道,480个周期,提高采样时间可以提高精确度 */
ADC_Cmd(ADC1, ENABLE);/* 开启AD转换器 */
}
2.启动ADC转换
static uint16_t GetAdc(u8 ch)
{
ADC_SoftwareStartConv(ADC1); /* 使能指定的ADC1的软件转换启动功能 */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));/* 等待转换结束 */
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
ADC_ClearITPendingBit(ADC1, ADC_IT_OVR); /* 清除数据溢出位 */
return ADC_GetConversionValue(ADC1); /* 返回最近一次ADC1规则组的转换结果 */
}
四、小提示
在进行ADC转换时,ADC_SR的数据溢出标识位会被置位,需要使用ADC_ClearITPendingBit(ADC1, ADC_IT_OVR)清除溢出标识位,否则程序会卡死在等待结束转换处。