Skip to main content
Explorer
July 17, 2024
Question

STM32H745ZIT6 ADC error

  • July 17, 2024
  • 3 replies
  • 4409 views

I'm encountering an issue with the ADC on my STM32H745ZIT6 microcontroller when reading voltages from a power supply. Here's the problem in detail:

I'm using the ADC to convert analog voltages from a power supply into digital values. However, I've noticed significant inaccuracies in the ADC readings across all voltage ranges. For example, when the power supply outputs 6V, the ADC reads 6.22V consistently, and similar deviations occur across other voltage levels.

I've ensured that the power supply voltages are stable and within the operating range specified for the ADC. The issue is persistent and does not seem to be related to specific voltage thresholds.

 

Has anyone else in the community encountered similar issues with the STM32H7 series ADC? If so, how did you resolve them? Any insights or suggestions on how to troubleshoot or resolve this issue would be greatly appreciated.

 

    This topic has been closed for replies.

    3 replies

    Super User
    July 17, 2024

    ADCs will not be exact. Is this custom hardware? Be sure you follow rules for how to get the best accuracy out of the ADC.

    cd00211314-how-to-get-the-best-adc-accuracy-in-stm32-microcontrollers-stmicroelectronics.pdf

     

    You mention voltages outside of the ADC range, so I assume there's a voltage divider or op-amp.

     

    More insight into exactly what the values are and how they're inaccurate would help to address your questions. For a given power supply voltage, do you see variations in the ADC reading? How much variation? Show results, be specific.

    MorisG_PEAuthor
    Explorer
    July 17, 2024

    we are using the MCU in a 60V power supply where the output voltage is reduced to values between 0-2.7V using opamp voltage divider. The ADC is supposed to read the output voltage(after being reduced to 0-2.7V) and it's values are used to give the voltage reading for the user. the problem is that at some of our boards the ADC values are not accurate at some voltages. for example(at a problematic board) instead of reading 6V it reads 6.22 etc. we tried to manually replace the MCU at some controllers and the problem seemed to be fixed. BTW we are using ADC1. 

    Super User
    July 17, 2024

    0.22V out of a 60 V range is 0.3% error. Fairly low. Can you share your schematic? What are you doing to ensure the accuracy is what you want it to be? Op-amps will add additional error due to gain error, offset, and resistor uncertainties. You're going to see some amount of board to board variance.

    Graduate
    July 30, 2024

    As i understood, HAL_ADCEx_Calibration_Start() should be called every "startup". Is there a way to call it self-calibration of the ADC once, save the calibration values (e.g. to internal eeprom) and every statup to recall the same self-calibration values?

    I found and used:

    HAL_ADCEx_LinearCalibration_GetValue(ADC_HandleTypeDef *hadc, uint32_t *LinearCalib_Buffer)
    HAL_ADCEx_LinearCalibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t *LinearCalib_Buffer)
     
    I've called the self calibration with the offset linearity option:
    //Calling once
    HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED))
    uint32_t selfLinearCalib_Buffer[ADC_LINEAR_CALIB_REG_COUNT]; 
    save_buff_to_eeprom(selfLinearCalib_Buffer);
    HAL_ADCEx_LinearCalibration_GetValue(&hadc3, selfLinearCalib_Buffer);
     
    //From that point on, every startup - a flag indicates ADC was already self-calibrated
    load_buff_from_eeprom(selfLinearCalib_Buffer);
    HAL_ADCEx_LinearCalibration_SetValue(&hadc3, selfLinearCalib_Buffer);
     
    ==> the setValue is not working, as the ADC is not calibrated as after HAL_ADCEx_Calibration_Start()
    What am I missing?
    Thanks in advance!
     
    Super User
    July 30, 2024

    No - you just run

    HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED))

    1x ...after program start .  Thats all. (no need set...get...factory value...etc.)

    You get calibrated ADC at actual temperature etc.

    Just if your program running 24/7  without any stop - maybe do calibration every some hours or days.

    Or only at power up and then  never again, if you dont need best performance on long time.

    Graduate
    July 30, 2024

    Thanks for your prompt reply.

    Right, this works fine, but I want to avoid changing the calibration every power up, meaning i want to have a one-time calibration per product life, as we do a manual calibration in addition to the ADC-self calibration. So trying to figure out how to save and retrieve the self-calibration done in HAL_ADCEx_Calibration_Start().

    Graduate
    July 31, 2024

    TDK, thank you for the info, I've managed to set it manually as in the following flow:

    1. call HAL_ADCEx_Calibration_Start() //Performs self-calibration
    2. wait 10 msec
    3. call HAL_ADCEx_LinearCalibration_GetValue(): get calibrated values (160-bits LINEAR_CALIB_REG save calibrated values (e.g. EEPROM)
    4. Get (hadc.Instance)->CALFACT (11-bits linearity factor) and save (e.g. EEPROM)
    5. Power cycle 
    6. call HAL_ADCEx_LinearCalibration_SetValue(): retrieve saved 160-bits LINEAR_CALIB_REG values
    1. (hadc3.Instance)->CALFACT = retrieve saved 11-bits linearity factor value
    2. HAL_Delay(10)