cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303xB inconstant wrong ADC measurements

JorgeAACosta
Associate II

I'm using the ADC to measure power grid voltage and current at 10 kHz. For most of the time the results are coherent. however, sometimes I detected some strange values colected by the ADC, differing from the measures made with an osciloscope in the analog input at the same moment.

I started to measure the Vrefint channel and got an similar problem, but not always simoutaneously, measuring values close to 4095 during some periods ( ~ 5 to 30 minutes), but around 1500 most of the time. Mesured 3.3 V on Vref pins during all the time the error occurs.

I'm using the folowing code generated by cube MX:

void MX_ADC1_Init(void)

{

 ADC_MultiModeTypeDef multimode = {0};

 ADC_ChannelConfTypeDef sConfig = {0};

 /** Common config

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

 hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 4;

 hadc1.Init.DMAContinuousRequests = DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc1.Init.LowPowerAutoWait = DISABLE;

 hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure the ADC multi-mode

 */

 multimode.Mode = ADC_MODE_INDEPENDENT;

 if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_1;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SingleDiff = ADC_SINGLE_ENDED;

 sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;

 sConfig.OffsetNumber = ADC_OFFSET_NONE;

 sConfig.Offset = 0;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_2;

 sConfig.Rank = ADC_REGULAR_RANK_2;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_3;

 sConfig.Rank = ADC_REGULAR_RANK_3;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_VREFINT;

 sConfig.Rank = ADC_REGULAR_RANK_4;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

}

6 REPLIES 6
raptorhal2
Lead

Perhaps the 10KHz is too close to being able to sample and process the data.

If sampling slower is not an option to try, can you reduce the sampletimecycles on channels 1 to 3?

Cheers, Hal

raptorhal2
Lead

Is the ADC calibrated during initialization?

Cheers, Hal

yes, it's calibrated.

thanks for your attention

I'm runing in 72 MHz. I already tested this, the time spent whith this process is ok.

Actualy I started the project with 20 cycles, but it's working similarly whith both configurations.

thanks for the attention.

raptorhal2
Lead

And is the ADC enabled before calibration?

If yes, run an example from the cube library and get a peer review of your code if you can.

Cheers, Hal

I'm folowing this order:

while(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK);

HAL_TIM_Base_Start(&htim2);

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc, ADC_CONVERSIONS);

The timer is generating events to triger the ADC.