cancel
Showing results for 
Search instead for 
Did you mean: 

What causes one of my ADC channels to work incorrectly?

BStei.3
Associate

I'm having an issue reading one of the channels on an ADC. It is working for one channel but not the other, even though the settings are the same. I am verifying what the expected value should be based on an oscilloscope measurement taken right off of the pin. What are some of the things I should look out for?

For some more details:

I am using an STM32F303RBT6, and ADC 4. Channel 4 is working, channel 3 is not. I have tried swapping their rank, but that seemed to have no effect.

They are configured like this:

0693W00000WL2lJQAT.pngI have tried both a polling approach and a DMA approach. Currently I'm focusing on the polling approach since it is more basic and I was seeing frequent crashes with the DMA approach. Polling approach based from controllerstech (can't add link)

Code to poll for ADC:

....
void ADC_Select_Channel(uint32_t ch) {
	ADC_ChannelConfTypeDef sConfig = {0};
	  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
	  */
	  sConfig.Channel = ch;
	  sConfig.Rank = 1;
	  sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;
	  if (HAL_ADC_ConfigChannel(&hadc4, &sConfig) != HAL_OK)
	  {
	    Error_Handler();
	  }
}
....
 
 
while(1)
{
...
        ADC_Select_Channel(3);
        HAL_ADC_Start(&hadc4);
        HAL_ADC_PollForConversion(&hadc4, 1000);
        uint32_t charge_voltage_adc = HAL_ADC_GetValue(&hadc4);
        HAL_ADC_Stop(&hadc4);
 
        ADC_Select_Channel(4);
        HAL_ADC_Start(&hadc4);
        HAL_ADC_PollForConversion(&hadc4, 1000);
        uint32_t battery_voltage_adc = HAL_ADC_GetValue(&hadc4);
        HAL_ADC_Stop(&hadc4);
...
}
 
 
....
static void MX_ADC4_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  hadc4.Instance = ADC4;
  hadc4.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc4.Init.Resolution = ADC_RESOLUTION_12B;
  hadc4.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc4.Init.ContinuousConvMode = ENABLE;
  hadc4.Init.DiscontinuousConvMode = DISABLE;
  hadc4.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc4.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc4.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc4.Init.NbrOfConversion = 1;
  hadc4.Init.DMAContinuousRequests = DISABLE;
  hadc4.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc4.Init.LowPowerAutoWait = DISABLE;
  hadc4.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  if (HAL_ADC_Init(&hadc4) != HAL_OK)
  {
    Error_Handler();
  }
}
....

3 REPLIES 3
S.Ma
Principal

Test with a single pin single channel.

Apply Gnd then Vdd and check adc values for each pin. Check pin configuration and schematics for both. Adc calibration? Sample amd hold time identical with same analog input ?

BStei.3
Associate

I tried the single pin on the single channel, but still getting an incorrect result. It is reading ~480, so 480/4096*3.3= 0.39 volts when the oscilloscope reads 3.13 volts. I am running the calibration for this ADC on startup. What do you mean by hold time?

S.Ma
Principal

Max out the sample time, apply vdd to the pin and if still reading 480 whilr on the scope the level is non glitchy, either the adc frequency or programmed register values are wrong. In debug mode, run then stop the code, check in digital io modd if you read a 1 when vdd, and 0 when gnd applied to the pin. Basic hw check first.