cancel
Showing results for 
Search instead for 
Did you mean: 

STM32l073 Adc Vrefint and adc_channel0 not working second measurement

Flebr.461
Associate

Hi i 'm using nucleo board. Ihave a simple program that measure Vref int ( Vdda voltage ) then measure ADC channel 0. it works fine the first time. I'm using HAL function. Setiing of ADC NOT CONTINOUS MODE, Config Channel Adc Start , PollFor conversion Get result Vrefint , Stop ADC. Now second step, Config Channel Adc Start , PollFor conversion Get result ADC0 , Stop ADC. then i loop, ANd here tthis second loop give a bad value on Vrefint ( 1500 lsb first loop, 980 second iteration). If i don(t select channel0 it continusly measure properly, it seems that select adc0 channel between two Vrefint conversion corrupt the measurement.

Is it something special to do in between? shoul i not stop adc in between and use sequence mode to make acquisition of the two channel in one shoot ?

Here my adc config

hadc.Instance = ADC1;
        hadc.Init.OversamplingMode = DISABLE;
        hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;                //dif
        hadc.Init.Resolution = ADC_RESOLUTION_12B;
        hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;               //estimate for 0.5lsb error @4mhz, Rsource= 60kohm
        hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
        hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
        hadc.Init.DiscontinuousConvMode = ENABLE;
        hadc.Init.ContinuousConvMode = DISABLE;
        hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
        hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;                //not defined
        hadc.Init.DMAContinuousRequests = DISABLE;
        hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
        hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;                      //not defined
        hadc.Init.LowPowerAutoWait = DISABLE;
        hadc.Init.LowPowerFrequencyMode = ENABLE;
        hadc.Init.LowPowerAutoPowerOff = DISABLE;

Here the code

if (HAL_ADC_Init(&hadc) != HAL_OK)
        {
 
        }
 
        if(HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK){
 
        }
 
//******************************MESURE TENSION REFERENCE INTERN *************************************************
 
        sConfig.Channel = ADC_CHANNEL_VREFINT;
 
        if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { }
 
        if(HAL_ADC_Start(&hadc) != HAL_OK){ }
 
        HAL_ADC_PollForConversion(&hadc, 3000);
 
        if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC) {
 
          uint32_t uwADCxConvertedValue = HAL_ADC_GetValue(&hadc);
          codeADC_VDDA = uwADCxConvertedValue;
          Vdda = 3*( (float)*VREFINT_CAL / (float)uwADCxConvertedValue);
        }
 
        HAL_ADC_Stop(&hadc);
 
//******************************MESURE TENSION BATTERIE *************************************************
 
        /**Configure for the selected ADC regular channel to be converted.
         */
          sConfig.Channel = ADC_CHANNEL_0;
 
        if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)  { }
 
        if (HAL_ADC_Start(&hadc) != HAL_OK) {  }
 
        HAL_ADC_PollForConversion(&hadc, 3000);
 
        if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC) {
          uint32_t uwADCxConvertedValue = HAL_ADC_GetValue(&hadc);
          codeADC_VBAT = uwADCxConvertedValue;
          BatteryVoltage = ((float) uwADCxConvertedValue / 4095) * 3.3 * 2.5;   //2.5: R11,R12 resistor bridge ratio
        }
 
        HAL_ADC_Stop(&hadc);

3 REPLIES 3
Robmar
Senior III

Another ignored customer with a valid questions.

ONadr.1
Senior III

I had a similar problem with the STM32F401. Once I measured the Ref voltage, further measurements from the other analog inputs were meaningless. The problem was that calling HAL_ADC_ConfigChannel for the Ref channel set the ADC_CCR_TSVREFE bit and no longer reset it. I had to reset it after finishing the Vref measurement. This caused errors in other measurements. Maybe there is something similar with the MCU you are using.

 

	 tmpAdc = ADC_COMMON_REGISTER(hadc);	//get register adresses
	 for(i=0U; i<numOfSamples; i++){
		 if (HAL_ADC_Start(hadc) != HAL_OK)
		 {
			return outVal;
		 }
		 if (HAL_ADC_PollForConversion(hadc, 1) != HAL_OK)
		 {
			return outVal;
		 }
		 adcVal+=HAL_ADC_GetValue(hadc);		//precteni vysledku konverze
	 }
	 tmpAdc->CCR &= ~ADC_CCR_TSVREFE;	//clear ADC_CCR_TSVREFE

 

Tinnagit
Senior II

I recommend that if you use software trigger and it's a single time sampling which it's may sampling in noise so The value mat be very swing.

there are some feature like as oversampling that it's help you to filtered noise and you will got some value more clear than single sampling.