STM32的ADC模数转换_蓝桥杯ADC测量实验

ADC简介

ADC原理

  • 逐次逼近法

    ADC具体如何工作在STM8系列中已有详细介绍,不再赘述

  • 开发板电压采集电路原理

    蓝桥杯开发板上的电位器结构如下:一个10k的电阻体,两头连接VDD与GND,电位器的电刷连接到STM32的ADC引脚上,调节电刷位置就让能让引脚获得不同的分压值,这个分压值的范围是0-3.3V

ADC的初始化配置

  • ADC的引脚配置

    开发板上引脚PB15经过J11连接到电位器R37(即开发板上标注电压采集1的电位器),PB12则经J12连接到R38

    将PB12/15这两个引脚配置为ADC_IN模式:PB12为ADC1_IN11,PB15为ADC2_IN15,两者分别使用两个ADC通道

  • ADC的参数配置
    1. 在CubeMX中左边栏的Analog中找到ADC1和ADC2,分别选中它们
    2. 在右侧窗口启用相应通道:ADC1的IN11配置IN11 Single-ended,ADC2勾选IN15 Single-ended
    3. 其他参数默认即可

ADC的使用

ADC的函数

  • 启动ADC函数HAL_ADC_Start
    void HAL_ADC_Start(ADC_HandleTypeDef *hadc)
    /*
    内部的参数是ADC的句柄,即指向ADC_HandleTypeDef结构体的指针,结构体包含了ADC的配置信息
    在使用ADC1时,应该写&hadc1,同理ADC2的句柄是&hadc2
    */
    
  • 获取ADC值HAL_ADC_GetValue
    uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
    //该函数将返回参数对应ADC获取的值,注意ADC值还不是实际电压值
    
  • ADC的使用

    虽然在库函数中已有上述两个使用ADC的函数,但为了方便使用,在adc.c中,我们再将这两个函数封装为一个直接调用ADC获取当前电压值的函数,记得在adc.h中声明此函数

    /* USER CODE BEGIN 1 这部分在adc.c文件的末尾*/
    uint16_t getADC2(void)
    {
    	uint16_t adc=0;//储存adc值的变量
    	HAL_ADC_Start(&hadc2);//启动ADC转换的函数,使用adc2的句柄
    	adc=HAL_ADC_GetValue(&hadc2);//获取AD值
    	return adc;//返回获取值
    }
    uint16_t getADC1(void)
    {
    	uint16_t adc=0;
    	HAL_ADC_Start(&hadc1);//将句柄改为ADC1,调用ADC1
    	adc=HAL_ADC_GetValue(&hadc1);
    	return adc;
    }
    /* USER CODE END 1 */
    
  • ADC校准函数HAL_ADCEx_Calibration_Start

    adc.c中的ADC初始化部分后加上校准函数,如果不加校准函数ADC检测值会有误差,电压值最大只能到3.25V

    /* USER CODE BEGIN ADC1_Init 2 */
    HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
    /* USER CODE END ADC1_Init 2 */
    
    /* USER CODE BEGIN ADC2_Init 2 */
    HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
    /* USER CODE END ADC2_Init 2 */
    
  • 计算实际电源值

    本型号STM32的ADC默认精度是12位,也即将3.3V的电压分为212=4096份

    double Volt_R37;//由于有小数部分,需要使用double型变量
    //在输出时使用%lf,可限定其输出小数点位数,如%.2lf表示输出两位小数
    
    Volt_R37=getADC2()*3.3/4096;
    Volt_R38=getADC1()*3.3/4096;
    

代码实现

  • 在LCD上显示测得电压值
    void Lcd_Proc(void)
    {
    Volt_R37=getADC2()*3.3/4096;
    Volt_R38=getADC1()*3.3/4096;
    if(lcd_page==0)
    {
    	LCD_DisplayStringLine(Line0,(uint8_t*)"    Hello World!    ");
    	sprintf(buf,"Volt_R37:%.2lfV",Volt_R37);
    	LCD_DisplayStringLine(Line3,(uint8_t*)buf);
    	sprintf(buf,"Volt_R38:%.2lfV",Volt_R38);
    	LCD_DisplayStringLine(Line4,(uint8_t*)buf);
    }
    
posted @ 2025-07-22 21:53  无术师  阅读(237)  评论(0)    收藏  举报