STM32 HAL库ADC采样(使用内部基准电压)

        当我们采用内部基准电压时,首先应了解下内部基准电压的用法,根据STM32L476参考手册我们得知:

解析:

VDDA:实际电压参考值,由上式计算得出,用来计算我们需要的采样电压值,下边会用到;

VREFINT_CAL:内部电压参考校准值,每个芯片都不一样,例如我的STM32L476则存在0x1FFF75AA—–0x1FFF75AB中,我们可以读出来:

#define VREFINT_CAL						(uint16_t)(*(__I uint16_t *)(0x1FFF75AA))

在数据手册中我们可以查到校准值的存储位置,如下图:

VERFINT_DATA:ADC转换后的实际VREFINT输出值,我们可以通过ADC的通道17读出来,该值在1.2V左右:

到这里我们就可以得到实时的参考电压值VDDA,既然确定了VDDA的值,我们便可以通过下式来计算我们实际测量的电压值:

解析:

VREFINT_CAL:固定值,我的芯片读出来是0x0681(上边有读取方法);

ADCx_DATA:ADC在通道X上测量的值(右对齐);

VREF_DATA:ADC转换后的实际VREFINT输出值,我们可以通过ADC的通道17读出来,该值在1.2V左右;

FULL_SCALE:ADC输出的最大数字值。例如12位分辨率,它将是212−1=4095或8位分辨率,28−1=255。

有了以上的基础,我们便可以通过配置CubeMX来产生我们需要的代码如下图:(大家可以根据自己的需求来选择相应的通道)

        配置为扫描模式,连续模式关闭,间断模式开启,间断分组为1,转换数设置为3,并配置每个RANK:

然后生成代码:

 /* ### - 2 - Start calibration ############################################ */
  if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
  {
    Error_Handler();
  }
  for(int i=0;i<3;i++)
		{  
			
			if(HAL_ADC_Start(&hadc1) != HAL_OK)//开始转换
			{
				/* Start Conversation Error */
				Error_Handler();
			}
			HAL_ADC_PollForConversion(&hadc1, 10);//等待常规组转换完成
  
			/* Check if the continous conversion of regular channel is finished */
			if ((HAL_ADC_GetState(&hadc1) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
			{
				/*##-6- Get the converted value of regular channel  ########################*/
				V1[i] = HAL_ADC_GetValue(&hadc1);
				
			}
		}
		HAL_ADC_Stop(&hadc1);
		VI1[0] = 3.0*VREFINT_CAL*V1[0]/V1[2]/4095;
		VI1[1] = 3.0*VREFINT_CAL*V1[1]/V1[2]/4095;
		HAL_Delay(2000);

这里V1[0]、V1[1]、就是我通道6,通道7的测量值,V1[2]就是内部参考电压值,故根据:

便可以计算的出自己所需要的值。

多通道DMA方式配置:配置为扫描模式,连续模式,使能DMA连续请求,其他保持不变

生成代码:

uint32_t ADC_ConvertedValue[3];//定义数组用来接收数据
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) !=  HAL_OK)//校准
		{ Error_Handler();}
		if (HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_ConvertedValue,3 ) != HAL_OK)//启用ADC,开始常规组的转换,并通过DMA传输结果。       
		{ Error_Handler();}
		  while(!(__HAL_DMA_GET_FLAG(&hdma_adc1,DMA_FLAG_TC1))){;}//等待DMA转换完成
	  __HAL_DMA_CLEAR_FLAG(&hdma_adc1,DMA_FLAG_TC1);//清楚DMA标志位
		//	HAL_Delay (10);
		HAL_ADC_Stop_DMA(&hadc1);//停止ADC常规组转换,禁用ADC DMA传输
		HAL_Delay(2000);

这里有几点需要特别注意:

在使用DMA时:1、需要先初始化DMA,再初始化ADC;

        2、在CubeMX配置Data Width为WORD时,数组ADC_ConvertedValue应该定义为uint32_t,否则配置Data Width为HALF WORD时,数组ADC_ConvertedValue应该定义为uint16_t.

作者:小白小菜。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 HAL库ADC采样(使用内部基准电压)

发表回复