Reputation: 3
I want to read the ADC values from the pins of the STM32F072C8U6 MCU. But the values I read are not consistent with the ones I measure with an oscilloscope, and sometimes I can read them, sometimes I cannot. I have tried to reconfigure the ADC initialization several times, but it is still unsuccessful. READ VOLTAGE
bool PM_ReadVoltage(const TestPointSpec *spec, float *val, bool raw)
{
bool success = false;
ADC_ChannelConfTypeDef channelConf;
HAL_ADC_Stop(&hadc);
HAL_ADCEx_Calibration_Start(&hadc);
channelConf.Rank = 1;
channelConf.SamplingTime = CONFIG_ADC_SAMPLE_TIME;
channelConf.Channel = spec->adcChannel;
if (HAL_ADC_ConfigChannel(&hadc, &channelConf) != HAL_OK)
{
return false;
}
HAL_ADC_Start(&hadc);
HAL_StatusTypeDef rc = HAL_ADC_PollForConversion(&hadc, 500);
if (rc == HAL_OK)
{
uint32_t res = HAL_ADC_GetValue(&hadc);
#if CONFIG_CALIB_MODE == 1
COM_Trace("Raw %s=%d", spec->name, res);
#endif
if (!raw && spec->isHalf)
{
*val = (float)res * gAdcResolution * 2;
}
else
{
*val = (float)res * gAdcResolution;
}
}
else
{
goto out;
}
*val += *val * spec->testPointVolLinearCalib;
success = true;
out:
channelConf.Rank = ADC_RANK_NONE;
HAL_ADC_ConfigChannel(&hadc, &channelConf);
HAL_ADC_Stop(&hadc);
HAL_Delay(100);
return success;
}
HAL_INIT
static void ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
HAL_ADCEx_Calibration_Start(&hadc);
HAL_Delay(10);
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = 1;
sConfig.SamplingTime = CONFIG_ADC_SAMPLE_TIME;
const uint16_t VREFIN_CAL = *((uint16_t*)0x1FFFF7BA);
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_ADC_Start(&hadc);
if (HAL_ADC_PollForConversion(&hadc, 500) == HAL_OK)
{
uint32_t val = HAL_ADC_GetValue(&hadc);
uint32_t vdda = (3300UL * (uint32_t)VREFIN_CAL) / val;
PM_SetVDDA(vdda / 1000.0f);
}
sConfig.Rank = ADC_RANK_NONE;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
HAL_ADC_Stop(&hadc);
}
CONFIG GPIO ADC
#define ADC_PIN_NUM 7
#define ADC_INPUT_3 { .port = GPIOA, .pin = GPIO_PIN_3 }
#define ADC_INPUT_4 { .port = GPIOA, .pin = GPIO_PIN_4 }
#define ADC_INPUT_5 { .port = GPIOA, .pin = GPIO_PIN_5 }
#define ADC_INPUT_6 { .port = GPIOA, .pin = GPIO_PIN_6 }
#define ADC_INPUT_7 { .port = GPIOA, .pin = GPIO_PIN_7 }
#define ADC_INPUT_8 { .port = GPIOB, .pin = GPIO_PIN_0 }
#define ADC_INPUT_9 { .port = GPIOB, .pin = GPIO_PIN_1 }
Upvotes: 0
Views: 513