模数转换器,将模拟信号转换为数字信号。转换原理主要为逐次逼近型、双积分型、电压频率转换型三种。而本ADC呢是逐次逼近型的模拟数字转换器。
STM32F4系列一般都有3个ADC,这些ADC可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F4的ADC是12位逐次逼近型的模拟数字转换器。
编程要注意这些寄存器的设置,如果不是特别清楚最好参考一下手册上的资料。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure, GPIO_Mode = GPIO_Mode_AN;//模拟输入模式
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
typedef struct
{
unit32_t ADC_Mode; //ADC模式选择
unit32_t ADC_Prescaler; //ADC分频系数
unit32_t ADC_DMAAccessMode;//ADC DMA模式配置
unit32_t ADC_TwoSamplingDelay; //ADC采样延迟
}ADC_CommonInitTypedef;
void ADC_Init(ADC_TypeDef* ADC×, ADC_InitTypeDef* ADC_InitStruct);
typedef struct
{
unit32_t ADC_Resolution; //ADC分辨率选择
FunctionalState ADC_ScanConvMode;//ADC扫描模式选择
FunctionalState ADC_ContinuousConvMode;//ADC连续转换模式选择
unit32_t ADC_ExternalTriConvEdge;//外部触发极性
unit32_t ADC_ExternalTrigConv;//ADC外部触发选择
unit32_t ADC_DataAlign;//ADC数据对齐方式
unit8_t ADC_NbrOfConversion;//ADC规则序列长度
}ADC_InitTypeDef;
void ADC_Cmd(ADC_TypeDef* ADC×, FunctionalState NewState);
ADC_Cmd(ADC1_ENABLE);//开启AD转换器
void ADC_RegularChannelConfig(ADC_TypeDef* ADC×, unit8_t ADC_Channel, unit8_t Rank, unit8_t ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
设置好规则序列通道及采样周期,接下来就要开启转换,由于我们采用的是软件触发,库函数
void ADC_SoftwareStartConv(ADC_TypeDef* ADC×);
开启转换之后,就可以获取ADC转换结果数据,调用的库函数是:
unit16_t ADC_GetConversionValue(ADC_TypeDef* ADC×);
例如我们要判断 ADC1 的转换是否结束,方法是:
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//等待转换结束
本章所要实现的功能是:通过 ADC1 通道5采样外部电压值,将采样的AD值和转换后的电压值通过串口打印出来,同时 D1 指示灯闪烁,提示系统正常运行。程序框架如下:
void ADC×_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
ADC_CommonInitTypeDef ADC_CommonInitSructure;//定义ADC配置结构体变量
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//管脚设置PA5
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空
GPIO_Init(GPIOA, &GPIO_InitStructure;//初始化结构体
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;
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初始化
}
u16 Get_ADC_Value(u8 ch, u8 times)
{
u32 temp_val = 0;
u8 t;
ADC_RegularChannelConfig(ADC1, ch, 1, 480Cycles);
ADC_SoftwareStartConv(ADC1);
fot(t = 0; t < times; t++)
{
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//等待转换结束
temp_val += ADC_GetConversionValue(ADC1);
}
return temp_val/times;
}