我是靠谱客的博主 怕孤独黑猫,最近开发中收集的这篇文章主要介绍HAL库学习——ADC精度问题以及多通道采集,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、简介

      博主在使用ADC测量电池电压时,发现测出来的AD值转换为实际电压不匹配,偏差大,因此通过网上收集资料,最终得知ADC采集精度提升的方法。前半部分主要是涉及多通道电压值采集,CubeMx的配置以及代码实现,以采集ADC1通道0、通道8和内部基准电压为例。后半部分讲解使用内部基准电压计算精确度较高的电压值。

 

二、运行环境

  MCU: STM32L071CBT6

  配置工具:STM32CubeMx

  IDE:MDK5

 

三、CubeMx配置

时钟配置:

        使用RCC外部低速时钟。

ADC配置:

        开启ADC的通道0、通道8和内部电压通道。

         当使用多通道采集时,Discontinuous Conversion Mode(间断转换模式)要使能。

串口配置:

       博主所用的板子将LPUART1引出来当调试串口,用来打印ADC转换的AD值,以验证ADC转换成功,串口配置如下,波特率设为9600Bit/s,Word Length为8 Bit,其余设置不变。

 

四、代码实现

       上述配置完生成代码如下:

     

printf函数映射

#include <stdio.h>

//printf函数映射
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

       为了使ADC采集值更准确,在ADC初始化完后使用HAL库函数HAL_ADCEx_Calibration_Start做自校准。

MX_ADC_Init();
if (HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK)
{
  printf("校准失败rn");  
}

   采集数据并打印

  uint8_t i;
  uint16_t adValue[3];

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    for (i = 0; i < 3; i ++)
    {
      if (HAL_ADC_Start(&hadc) != HAL_OK)
      {
        printf("ADC开启失败rn");
      }
      
      if (HAL_ADC_PollForConversion(&hadc, 10) != HAL_OK)//等待转换完成,第二个参数表示超时时间,单位ms 
      {
        printf("ADC转换失败rn");
      }
      
      if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
      {
        adValue[i] = HAL_ADC_GetValue(&hadc);
        printf("通道[%d]:%drn", i, adValue[i]);
      }
    }

    
    HAL_ADC_Stop(&hadc);
    HAL_Delay(1000);
    
  }

串口助手输出如下

       通道[0]对应的为配置里的IN0,通道[1]对应的为配置里的IN8,通道[2]对应的为配置里的内部电压通道。由于通道[0]没有接任何输入电压,所以其采出来的AD值近乎为0,通道[1]通过外部做了1/2分压所以其采集出来的AD值为2326,通道[2]采集的是内部参考电压实际值,从数据手册可以得知内部参考电压的校准值存于地址0X1FF80078。

可将其值读出来:

uint16_t VREFINT_CAL;

VREFINT_CAL = *(__IO uint16_t *)(0X1FF80078);
printf("VREFINT_CAL:%drn",VREFINT_CAL);

VREFINT_CAL = 1674,该值是在25°C,输入电压为3V情况下得到得,实际板子供电电压并不是如此,因此得出来会有误差,但基本接近。通道1的电压是博主自己给的,通过万用表测量得实际电压为1.71V。而理论代入公式应为:

(通道[1]AD值 / 4096) * 3.3V = (2297 / 4096) * 3.3 = 1.85V

跟实际差太多。通过查阅资料得知,为了更准确的获得采集的电压,需要使用内部参考电压计算实际的供电电压,将电源相关的 ADC 测量值转换为绝对电压值。具体计算公式在参考手册中:

      VREFINT_CAL即为内部参考电压的校准值为1674,ADC_DATAx即为通道[1]测出来的AD值,VREFINT_DATA为内部参考电压实际值,即为通道[2]的值。所使用的单片机ADC分辨率为12位所以FULL_SCALE的值为4095。将上述值代入公式,用代码实现如下:

float realVol;

realVol = (float)(3 * VREFINT_CAL * adValue[1]) / (adValue[2] * 4095)
printf("V = %.4frn", realVol);

        最终得出的电压值在1.71V左右浮动,因此通过此方法可以测量出更精确的电压值。

最后

以上就是怕孤独黑猫为你收集整理的HAL库学习——ADC精度问题以及多通道采集的全部内容,希望文章能够帮你解决HAL库学习——ADC精度问题以及多通道采集所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部