首页 > 编程知识 正文

stm32的adc系统的功能特性,stm32自带的adc

时间:2023-05-06 06:11:59 阅读:194027 作者:4024

         AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。

        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:

        Adc_init()

{

__HAL_RCC_ADC1_CLK_ENABLE();
    AdcHandle.Instance = ADC1;
 
  AdcHandle.Init.OversamplingMode      = DISABLE;
  
  AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
  AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
  AdcHandle.Init.LowPowerFrequencyMode = ENABLE;
  AdcHandle.Init.LowPowerAutoWait      = DISABLE;
    
  AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
  AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;
  AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;
  AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.ContinuousConvMode    = ENABLE;
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;
  AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
  AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
  AdcHandle.Init.DMAContinuousRequests = DISABLE;

    HAL_ADC_Init(&AdcHandle);
    HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);

}

//配置ADC初始化

void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef                 GPIO_InitStruct;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO clock ****************************************/
  __HAL_RCC_GPIOA_CLK_ENABLE();
  /* ADC1 Periph clock enable */
  __HAL_RCC_ADC1_CLK_ENABLE();
  
  /*##- 2- Configure peripheral GPIO #########################################*/
  /* ADC3 Channel8 GPIO pin configuration */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

//初始化ADC引脚PA0,开启时钟

void get_voltage(void)
{
          bsp_adc_init();
          HAL_ADCEx_EnableVREFINT();
          HAL_ADC_Stop(&AdcHandle);
          AdcHandle.Instance->CHSELR=0;
          sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值
           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
            HAL_ADC_Start(&AdcHandle);
            HAL_ADC_PollForConversion(&AdcHandle, 10);    
            /* Check if the continous conversion of regular channel is finished */
            if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
            {
                /*##-6- Get the converted value of regular channel  ########################*/
                uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
            }
            
            vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压
            HAL_ADCEx_DisableVREFINT();
            HAL_ADC_Stop(&AdcHandle);
            AdcHandle.Instance->CHSELR=0;
            sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压
          HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
            HAL_ADC_Start(&AdcHandle);
            HAL_ADC_PollForConversion(&AdcHandle, 10);    
            /* Check if the continous conversion of regular channel is finished */
            if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
            {
                /*##-6- Get the converted value of regular channel  ########################*/
                uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
            }
              //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值
            temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;
             //得到浮点型电压值            是乘了1000倍的            
            HAL_ADC_Stop(&AdcHandle);
            //HAL_ADCEx_DisableVREFINT();
            __HAL_RCC_ADC1_CLK_DISABLE();
   }
 } 

  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0,在下篇博客将分析对检测到电压值的处理。

      

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。