STM32Cube学习篇:深入理解ADC的单通道采集、多通道采集、轮询、中断和DMA三种方式

目录

1.ADC简介

2.ADC单通道电压采集

3.ADC多通道电压采集


1.ADC简介

以STM32F103系列为例,有 3 个 ADC,精度为 12 位,每个 ADC 最多有 16 个外部通道。ADC 的模式非常多,功能非常强大。一般ADC的精度为12为,也就是把3.3V电压分为4096份。

STM32F103VET6 ADC 通道如上图所示

2.ADC单通道电压采集

单次转换:

  • 轮询方式
  • 利用STM32Cube MX软件对ADC进行基本配置:

    基本配置完成后,调用HAL库函数开始工作:

    uint32_t ADC_Value;
    
    static void adc1_Demo(void)
    {
    
      HAL_ADC_Start(&hadc1);
      if(HAL_OK == HAL_ADC_PollForConversion(&hadc1,100))
        ADC_Value =HAL_ADC_GetValue(&hadc1);
      printf("ADC:%f\r\n",(float)ADC_Value / 4096 * 3.3);         //串口打印
    }
    
    
    int main()
    {
        while(1)
        {
             adc1_Demo();
        }
    }
  • 中断方式
  • 在Cube MX配置中开启中断:

    编写中断回调函数获取采集电压值:

    uint32_t ADC_Value;
    
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
    {
      ADC_Value =HAL_ADC_GetValue(&hadc1);
    }
    
    static void adc1_Demo2(void)
    {
      HAL_ADC_Start_IT(&hadc1);
      printf("ADC:%f\r\n",(float)ADC_Value / 4096 * 3.3);         //串口打印
    }
    
    int main()
    {
        while(1)
        {
            adc1_Demo2();
        }
    }
  • DMA方式
  •  因为采用单次转化方式,所以需要不断调用HAL_ADC_Start_DMA()。

    uint32_t ADC_Value;
    
    static void adc1_Demo3(void)
    {
      HAL_ADC_Start_DMA(&hadc1,&ADC_Value,1);
      printf("ADC:%f\r\n",(float)ADC_Value / 4096 * 3.3);         //串口打印
    }
    
    int main()
    {
        while(1)
        {
            adc1_Demo3();
        }
    }

    3.ADC多通道电压采集

    单次转换:

  • 轮询方式
  • 增加通道:

    uint32_t ADC_Value[2];
    static void adc1_Demo(void)
    {
      HAL_ADC_Start(&hadc1);
      if(HAL_OK == HAL_ADC_PollForConversion(&hadc1,100))
        ADC_Value[0] =HAL_ADC_GetValue(&hadc1);
      if(HAL_OK == HAL_ADC_PollForConversion(&hadc1,100))
        ADC_Value[1] =HAL_ADC_GetValue(&hadc1);
    
      printf("ADC_IN1:%f\r\n",(float)ADC_Value[0] / 4096 * 3.3);         //串口打印
      printf("ADC_IN2:%f\r\n",(float)ADC_Value[1] / 4096 * 3.3);         //串口打印
    }
    
    
    int main()
    {
        while(1)
        {
             adc1_Demo();
        }
    }
  • 中断方式
  • 多通道中断采集也是跟单通道一样,开启中断,在回调函数HAL_ADC_ConvCpltCallback()获取电压数据

    uint32_t ADC_Value[2];
    
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
    {
      static i =0;
      if(i > 1)
        i = 0;
      ADC_Value[i] =HAL_ADC_GetValue(&hadc1);
      i++;
    }
    
    static void adc1_Demo2(void)
    {
      HAL_ADC_Start_IT(&hadc1);
      printf("ADC_IN1:%f\r\n",(float)ADC_Value[0] / 4096 * 3.3);         //串口打印
      printf("ADC_IN2:%f\r\n",(float)ADC_Value[1] / 4096 * 3.3);         //串口打印
    }
    
    int main()
    {
        while(1)
        {
            adc1_Demo2();
        }
    }
  • DMA方式
  • 多通道DMA方式,则需配置连续采集模式。所以只需调用一次HAL_Start_DMA()即可。

    uint32_t ADC_Value[2];
    
    int main()
    {
        HAL_ADC_Start_DMA(&hadc1,ADC_Value,2);
    
        while(1)
        {
             printf("ADC_IN1:%d\r\n",(float)ADC_Value[0] / 4096 *3.3);
             printf("ADC_IN2:%d\r\n",(float)ADC_Value[1] / 4096 *3.3);
        }
    }

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32Cube学习篇:深入理解ADC的单通道采集、多通道采集、轮询、中断和DMA三种方式

    发表评论