STM32 ADC转换

  简介

        STM32的ADC是12位逐次逼近型的模拟数字转换器,ADC模块读到的数据是12位的数据,是从0到4095(111111111111)的值,当把ADC引脚接了GND,读到的就是0,当把ADC引脚接了VDD,读到的就是4095。STM32最多支持18个通道,可最多测量16个外部和2个内部信号源,ADC的各通道可以单次,连续,扫描或者间断模式执行。

     STM32 ADC转换_第1张图片

     STM32 ADC转换_第2张图片

     STM32 ADC转换_第3张图片

ADC相关结构体和库函数

typedef struct
{
  uint32_t ADC_Mode;//ADC模式:配置ADC_CR1寄存器的位[19:16]  :DUALMODE[3:0]位
  FunctionalState ADC_ScanConvMode; //是否使用扫描模式。ADC_CR1位8:SCAN位 
  FunctionalState ADC_ContinuousConvMode; //单次转换OR连续转换:ADC_CR2的位1:CONT
  uint32_t ADC_ExternalTrigConv;  //触发方式:ADC_CR2的位[19:17] :EXTSEL[2:0]                
  uint32_t ADC_DataAlign;   //对齐方式:左对齐还是右对齐:ADC_CR2的位11:ALIGN         
  uint8_t ADC_NbrOfChannel;//规则通道序列长度:ADC_SQR1的位[23:20]: L[3:0]       
}ADC_InitTypeDef;
//初始化,配置ADC模式、单次连续扫描模式、外部触发方式、对齐方式、规则序列长度
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
{
    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数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);
}
void ADC_DeInit(ADC_TypeDef* ADCx);//恢复默认值
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//使能ADC
//使能或者失能指定的ADC的中断
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
//ADC使能软件转换
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
//设置ADC的规则组通道、转化顺序和采样时间,其中ADC_Channel指定了通过本函数来设置的ADC通道,
  可以是0~17,ADC_SampleTime设置了选中通道的ADC采样时间
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, 
uint8_t Rank, uint8_t ADC_SampleTime);
//获取最近一次ADCx规则组的转换结果
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
void ADC_ResetCalibration(ADC_TypeDef* ADCx);//重置指定的ADC的校准寄存器
//获取ADC重置校准寄存器的状态
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始指定ADC的校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取ADC的校准状态

ADC配置的一般步骤:

1、开启PA口时钟和ADC1时钟,设置PA1为模拟输入。调用函数:GPIO_Init();APB2PeriphClockCmd();

2、复位ADC1,同时设置ADC1分频因子。调用函数:ADC_DeInit(ADC1);RCC_ADCCLKConfig(RCC_PCLK2_Div6);

3、初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。调用函数:void ADC_Init();

4、使能ADC并校准。调用函数:ADC_Cmd();

5、配置规则通道参数。调用函数:ADC_RegularChannelConfig();

6、开启软件转换:ADC_SoftwareStartConvCmd(ADC1);

7、等待转换完成,读取ADC值。调用函数:ADC_GetConversionValue(ADC1)。

示例代码:

//初始化ADC,这里我们仅以规则通道为例,我们默认将开启通道0~3				   
void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;
        //使能ADC1通道时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );  
        //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); 
                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PA1 作为模拟通道输入引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	ADC_DeInit(ADC1);  //复位ADC1 
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
	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数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据指定的参数初始化外设ADCx的寄存器   
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	ADC_StartCalibration(ADC1);	 //开启AD校准
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
}				  
//获得ADC值,ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
   //设置指定ADC的规则组通道,一个序列,采样时间239.5周期
   ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);	//使能指定的ADC1的软件转换启动功能
   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
   return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}

 

你可能感兴趣的:(STM32)