2017-08-30 06:48 AM
Hello,
I work on a STM32L151CCU6 and I need your help.
I try to measure VDDA voltage in order to calculate a voltage divider on PA2 (single mode). My two ADC configuration functions are :
void MX_ADC_Init(void)
{ GPIO_InitTypeDef gpioInit1; GPIO_InitTypeDef gpioInit2; gpioInit1.Pin = PID_PIN; //PA2 gpioInit1.Mode = GPIO_MODE_ANALOG; gpioInit1.Pull = GPIO_NOPULL; HAL_GPIO_Init(PID_PORT, &gpioInit1); PA2 gpioInit2.Pin = PID_POWER_SUPPLY_PIN; //PB2 gpioInit2.Mode = GPIO_MODE_OUTPUT_PP; gpioInit2.Pull = GPIO_NOPULL; HAL_GPIO_Init(PID_POWER_SUPPLY_PORT, &gpioInit2); //PB2 __HAL_RCC_ADC1_CLK_ENABLE(); ADC_ChannelConfTypeDef sConfig;/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/ adc_identification.Instance = ADC1; adc_identification.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; adc_identification.Init.Resolution = ADC_RESOLUTION_12B; adc_identification.Init.DataAlign = ADC_DATAALIGN_RIGHT; adc_identification.Init.ScanConvMode = ADC_SCAN_DISABLE; adc_identification.Init.EOCSelection = ADC_EOC_SEQ_CONV; adc_identification.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE; adc_identification.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE; adc_identification.Init.ChannelsBank = ADC_CHANNELS_BANK_A; adc_identification.Init.ContinuousConvMode = DISABLE; adc_identification.Init.NbrOfConversion = 1; adc_identification.Init.DiscontinuousConvMode = DISABLE; adc_identification.Init.ExternalTrigConv = ADC_SOFTWARE_START; adc_identification.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; adc_identification.Init.DMAContinuousRequests = DISABLE; if (HAL_ADC_Init(&adc_identification) != HAL_OK) { while(1); }/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/ sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_384CYCLES; if (HAL_ADC_ConfigChannel(&adc_identification, &sConfig) != HAL_OK) { while(1); } ADC_Enable(&adc_identification);}and :
void MX_ADC_VDD_Init(void)
{ ADC_ChannelConfTypeDef sConfig; /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)*/VDD_measurement.Instance = ADC1;
VDD_measurement.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; VDD_measurement.Init.Resolution = ADC_RESOLUTION_12B; VDD_measurement.Init.DataAlign = ADC_DATAALIGN_RIGHT; VDD_measurement.Init.ScanConvMode = ADC_SCAN_DISABLE; VDD_measurement.Init.EOCSelection = ADC_EOC_SEQ_CONV; VDD_measurement.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE; VDD_measurement.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE; VDD_measurement.Init.ChannelsBank = ADC_CHANNELS_BANK_A; VDD_measurement.Init.ContinuousConvMode = DISABLE; VDD_measurement.Init.NbrOfConversion = 1; VDD_measurement.Init.DiscontinuousConvMode = DISABLE; VDD_measurement.Init.ExternalTrigConv = ADC_SOFTWARE_START; VDD_measurement.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; VDD_measurement.Init.DMAContinuousRequests = DISABLE; if (HAL_ADC_Init(&VDD_measurement) != HAL_OK) { while(1); }/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/ sConfig.Channel = ADC_CHANNEL_17; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES; if (HAL_ADC_ConfigChannel(&VDD_measurement, &sConfig) != HAL_OK) { while(1); } ADC_Enable(&VDD_measurement);}When I try to measure this two ADC channel, I find 0.
I use this function : HAL_ADC_GetValue(&VDD_measurement);
Does anyone know where is my problem?
Thanks,
Jérémy
2017-08-30 11:45 AM
Hello!
>>> I use this function : HAL_ADC_GetValue(&VDD_measurement);
This function gets converted value only.
Also your ADC_SAMPLETIME_4CYCLES is small. My suggestion is to increase it at least to ADC_SAMPLETIME_96CYCLES and after you have a success reading try to calculate the exact timing.
Try to use
uint32_t vdda;
#define VREFINT_CAL_ADDR ((uint16_t*) (0x1FF800F8U)) /* Internal voltage reference,
#define VREFINT_CAL_VREF ( 3000U) /* Analog voltage reference
HAL_ADC_Start(&VDD_measurement);
vdda=VREFINT_CAL_VREF*(*VREFINT_CAL_ADDR);//VDDA = 3 V x VREFINT_CAL / VREFINT_DATA
HAL_ADC_PollForConversion(&VDD_measurement, 1000);
vdda /=HAL_ADC_GetValue(&VDD_measurement);
The vdda value will be in millivolts.
Use the same way to read the PA2 Start, Wait, Read.
Regards
vf
2017-08-31 03:42 AM
Hello!
Thank you ! That is working well for VDDA but not for PA2.
I have changed the Init function like below:
void MX_ADC_Init(void)
{ GPIO_InitTypeDef gpioInit1; GPIO_InitTypeDef gpioInit2; gpioInit1.Pin = PID_PIN; //PA2 gpioInit1.Mode = GPIO_MODE_ANALOG; gpioInit1.Pull = GPIO_NOPULL; HAL_GPIO_Init(PID_PORT, &gpioInit1); gpioInit2.Pin = PID_POWER_SUPPLY_PIN; //PB2 gpioInit2.Mode = GPIO_MODE_OUTPUT_PP; gpioInit2.Pull = GPIO_NOPULL; HAL_GPIO_Init(PID_POWER_SUPPLY_PORT, &gpioInit2); __HAL_RCC_ADC1_CLK_ENABLE(); ADC_ChannelConfTypeDef sConfig;/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/ adc_identification.Instance = ADC1; adc_identification.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; adc_identification.Init.Resolution = ADC_RESOLUTION_12B; adc_identification.Init.DataAlign = ADC_DATAALIGN_RIGHT; adc_identification.Init.ScanConvMode = ADC_SCAN_DISABLE; adc_identification.Init.EOCSelection = ADC_EOC_SEQ_CONV; adc_identification.Init.LowPowerAutoWait = ADC_AUTOWAIT_UNTIL_DATA_READ; adc_identification.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE; adc_identification.Init.ChannelsBank = ADC_CHANNELS_BANK_A; adc_identification.Init.ContinuousConvMode = DISABLE; adc_identification.Init.NbrOfConversion = 1; adc_identification.Init.DiscontinuousConvMode = DISABLE; adc_identification.Init.ExternalTrigConv = ADC_SOFTWARE_START; adc_identification.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; adc_identification.Init.DMAContinuousRequests = DISABLE; if (HAL_ADC_Init(&adc_identification) != HAL_OK) { while(1); }/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/ sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES; if (HAL_ADC_ConfigChannel(&adc_identification, &sConfig) != HAL_OK) { while(1); } ADC_Enable(&adc_identification);}And I read the value of the voltage like :
void ADC_Measure(ADC_HandleTypeDef* hadc)
{ MX_ADC_Init(); //Init ADC ADC_PowerOnPin(); //Enable the 3.3V of the voltage divider ADC_Start(hadc); HAL_ADC_PollForConversion(hadc, 1000); ADC_Measure_ID =HAL_ADC_GetValue(hadc); ADC_PowerOffPin(); //Disable the 3.3V of the voltage divider ADC_Stop(hadc);}But I receive 0. I use exactly the same parameters in initialization as for VDD and the same measurement function too.
Any idea for this point?
Thank you for your help.
2017-09-04 01:22 AM
Hello,
Any ideas?
Thank you.
2017-09-04 10:11 AM
Hi
in GPIO initialization function the GPIO clock seems not enabled.
__HAL_RCC_GPIOX_CLK_ENABLE();