STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解

先上ADC配置函数:

/* ADC init function */
void MX_ADC_Init(void)
{
  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
    */
  hadc.Instance = ADC1;
  hadc.Init.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

 ADC配置了3个规则通道,即ADC1_IN4、内部温度传感器和内部参考电压VREFINT。

if(BSP_CheckTimer(3)) //200ms loop
{
  HAL_ADC_Start(&hadc);
  HAL_ADC_PollForConversion(&hadc, 100);
  while(!HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC));
  adc_temp = HAL_ADC_GetValue(&hadc);
  t_printf("adc_temp = %d\r\n",adc_temp);
}

程序采用轮询的方式采样ADC,200ms采样一次。

ContinuousConvMode即连续采样模式

DiscontinuousConvMode即非连续采样模式

如果ContinuousConvMode=DISABLE,DiscontinuousConvMode=DISABLE,则轮询读ADC只能读到ADC1_IN4的值:

STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解_第1张图片

如果ContinuousConvMode=DISABLE,DiscontinuousConvMode=ENABLE,则轮询读ADC能读到ADC1_IN4、内部温度传感器和内部参考电压VREFINT的值:

STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解_第2张图片

如果ContinuousConvMode=ENABLE,DiscontinuousConvMode=DISABLE,则轮询读ADC能读到ADC1_IN4、内部温度传感器和内部参考电压VREFINT的值,用此模式时,HAL_ADC_Start()只要调用一次即可,但是轮询读出的ADC通道并不是规律的:

STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解_第3张图片

原因应该是ADC配置成连续采样模式,而我 这边取ADC值的时间间隔太长而前面的值被覆盖了,此模式应该配合DMA 使用。

而ContinuousConvMode=ENABLE,DiscontinuousConvMode=ENABLE则ST在参考手册中是明文禁止这样使用的。

STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解_第4张图片

你可能感兴趣的:(STM32L051的ADC的ContinuousConvMode和DiscontinuousConvMode的理解)