先上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的值:
如果ContinuousConvMode=DISABLE,DiscontinuousConvMode=ENABLE,则轮询读ADC能读到ADC1_IN4、内部温度传感器和内部参考电压VREFINT的值:
如果ContinuousConvMode=ENABLE,DiscontinuousConvMode=DISABLE,则轮询读ADC能读到ADC1_IN4、内部温度传感器和内部参考电压VREFINT的值,用此模式时,HAL_ADC_Start()只要调用一次即可,但是轮询读出的ADC通道并不是规律的:
原因应该是ADC配置成连续采样模式,而我 这边取ADC值的时间间隔太长而前面的值被覆盖了,此模式应该配合DMA 使用。
而ContinuousConvMode=ENABLE,DiscontinuousConvMode=ENABLE则ST在参考手册中是明文禁止这样使用的。