What causes one of my ADC channels to work incorrectly?
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:
I 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();
}
}
....