2021-03-02 10:03 AM
I am having trouble getting the ADC to work right in basic polled operation. I am polling two channels which provide voltages via resistor dividers. I have measured the voltages at the ADC inputs and they are correct so I do not believe the divider impedances are too high.
I get an ADC result that does not vary much. For example I get around 420 counts (out of 4096) with 0.9V at the input. With that voltage I should see ~1100 counts. And the result does not seem to vary with voltage...
Here is my setup, I would appreciate any advice.
static void MX_ADC_Init(void)
{
/* USER CODE BEGIN ADC_Init 0 */
/* USER CODE END ADC_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC_Init 1 */
/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc.Init.LowPowerAutoWait = ENABLE;
hadc.Init.LowPowerFrequencyMode = ENABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */
/* USER CODE END ADC_Init 2 */
}
This is called periodically:
uint16_t adcGetVolt(void)
{
volatile float V = 0;
// Get ADC value
adcConfig.Channel = ADC_CHANNEL_2;
HAL_ADC_ConfigChannel(&hadc, &adcConfig);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
sampleValue = HAL_ADC_GetValue(&hadc);
V = ((((float)sampleValue/4096.0f) * 3.30f) / VOLT_DIVIDER_MULTIPLIER);//.0697
volts_average = V;
return((uint16_t)((volts_average*10.0f) + 0.5f));
}
Alway returns ~420 counts
and also:
int16_t read_temperature(void)
{
float v, i, r, temperature_low, temperature_high, temperature, delta;
int char_index;
int16_t temp, temp_single;
// bool no_thermistor = false;
adcConfig.Channel = ADC_CHANNEL_0;
HAL_ADC_ConfigChannel(&hadc, &adcConfig);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
sampleValue2 = HAL_ADC_GetValue(&hadc);
Also always returns ~420 counts
2021-03-02 12:29 PM
I have VDDA tied to 3.3V so that is the reference for the ADC correct?
Anyone know of an ADC (simple polling) for the L0 series? I cannot find any in the import examples in STM32CUBE ide...
2021-03-03 01:34 AM
my aracnosense tells me the problem is here:
V = ((((float)sampleValue/4096.0f) * 3.30f) / VOLT_DIVIDER_MULTIPLIER);//.0697
you can start your debugg session and screen your sampleValue variable and see if its good.
2021-03-03 05:27 AM
I would attach a potentiometer to the ADC input and vary the input between 0...3.3V.
Take care to keep the input impedance low enough, I would not exceed 10k Ohm.
> my aracnosense tells me the problem is here: ...
That could be true.
The C type promotion rules are confusing at times.
And there are floats and integers involved.
I would split up the combined calculation in multiple expressions first, and check the proper result of each operation.
2021-03-03 02:02 PM
Which pin and which STM32 exactly?
Read out and check/post content of ADC and relevant GPIO registers content, at the moment when you read out the converted result.
JW