cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H77 ADC1 random readings

A K_2
Associate

We generated ADC code for STM32H755 using CubeMx. ADC1 is setup a single channel, one shot conversion. We are using internal Vref at 2.5V. We are reading 0.9V as a test and the DR keeps changing randomly. What are we doing wrong? Thanks!

// adc.c generated by CubeMx

/* ADC1 init function */

void MX_ADC1_Init(void)

{

 ADC_MultiModeTypeDef multimode = {0};

 ADC_ChannelConfTypeDef sConfig = {0};

 /** Common config */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;

 hadc1.Init.Resolution = ADC_RESOLUTION_16B;

 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc1.Init.LowPowerAutoWait = DISABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;

 hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;

 hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;

 hadc1.Init.OversamplingMode = DISABLE;

 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_5;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;

 sConfig.SingleDiff = ADC_SINGLE_ENDED;

 sConfig.OffsetNumber = ADC_OFFSET_NONE;

 sConfig.Offset = 0;

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

 {

  Error_Handler();

 }

}

// Application code

// Enable Vref at 2.5V

VREFBUF->CSR = 0x00000001;

while((VREFBUF->CSR & 0x8) == 0) {};

MX_ADC1_Init();

#define A2D_TIMEOUT (2000) // 2 seconds

//----------------------------------------------------------------------------------------------------------------------------------

static Bool bat_ReadA2D( Bool Stop, ADC_HandleTypeDef *Hadc, UInt16 *Value )

{  Bool success = FALSE;

  HAL_StatusTypeDef stat;

  stat = HAL_ADC_Start( Hadc );

  if ( stat != HAL_OK ) { printf( "Start ADC Failed, Err:%d", stat ); return FALSE; }

  stat = HAL_ADC_PollForConversion( Hadc, A2D_TIMEOUT );

  if ( stat != HAL_OK ) { printf( "ADC Read Failed, Err:%d", stat ); goto StopProcess; }

  success = TRUE;

  *Value = HAL_ADC_GetValue( Hadc );

  if ( !Stop ) return success; 

   

 StopProcess:

  stat = HAL_ADC_Stop( Hadc );

  if ( stat != HAL_OK ) { printf( "ADC Stop Failed, Err:%d", stat ); }

 return success;

}

2 REPLIES 2
TDK
Guru

Did you initialize the pin in analog mode? Should be in HAL_ADC_MspInit.

Is VREFBUF initialized?

What values/range of DR are you getting?

If you feel a post has answered your question, please click "Accept as Solution".
Yes, PB1/ADC channel 5 is setup as analog pin. Values change between 0x2F00 to 0x8F00. Tried slowing ADC clock and calibration but did not help.