0

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 }

READ ADC IMAGE READ ADC IMAGE

3
  • This may be hardware issue: inadequate VDDA/VREF+ supply stability, too high input signal source's impedance. The latter one could potentially be remedied by increasing sampling time. Commented Nov 3, 2023 at 14:10
  • @pmacfarlane, that is actually correct - val there is ADC readout for the fixed internal voltage source (VREFINT), so the higher ADC's reference VREF+=VDDA goes, the lower this readout will be. Commented Nov 3, 2023 at 21:52
  • @wek Ahh, I see. I was confusing it with reading from the other channels. My bad, didn't read it thoroughly. Commented Nov 3, 2023 at 22:46

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.