Skip to main content
Visitor II
December 1, 2023
Question

STM32L471RGT6 ADC Calibration

  • December 1, 2023
  • 6 replies
  • 3813 views

Hi ,

 Is there an automatic calibration routine for the STM32L471RGT6 ADC? If there isn't can someone point me to example code on how to read the internal reference (or some other approach) so I can write code to perform calibration. 

Thank you very much 

Richard

    This topic has been closed for replies.

    6 replies

    Super User
    December 1, 2023

    The reference manual RM0351 covers calibration procedure for the ADC.

    TDK_0-1701442965214.png

     

    rwils.1Author
    Visitor II
    December 1, 2023

    This is the code I have tried so far to read the calibration values 

     

    ///////////try calibrating the ADC //////////////

    HAL_ADC_Start(&hadc1);

    while (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) != HAL_OK) {} calibration=HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED); // This function returns the calibration value

    Super User
    December 1, 2023

    > This is the code I have tried so far to read the calibration values 

    Why do you think that will read calibration values? Are we just throwing stuff at a wall and seeing if it works? This looks like something ChatGPT would write.

    Follow the reference manual. If you can't or don't want to for whatever reason, follow an existing working CubeMX example that uses the ADC. Here is one of many:

    https://github.com/STMicroelectronics/STM32CubeL4/blob/master/Projects/NUCLEO-L452RE/Examples/ADC/ADC_RegularConversion_Polling/Src/main.c

     

    rwils.1Author
    Visitor II
    December 1, 2023

    Yes I am throwing stuff at a wall after reading through the HAL manual sections! I appreciate the links you sent. 

    Cheers

    Richard

    Super User
    December 1, 2023

    Fair enough, thanks for the honesty. Apologies for being a bit harsh.

    Super User
    December 2, 2023

    Perhaps share more about your setup. Is this a custom board or known good hardware? Can you share the schematic? Is VREF+ stable and decoupled appropriately? Is VDDA?

    If you can share more of your code or specific situation, the answers you get will generally be better. Why do you think they are 10% off? What are you measuring and what do you expect? If you connect the input to GND, do you get 0? If you connect it to VREF+/VDDA do you get 4095? If not, how close?

    > I can't access register values directly as they don't appear in the header file

    CMSIS headers are generally comprehensive, especially on common peripherals like ADC. What registers don't exist there? DEEPPWD is defined on line 1438 here:

    https://github.com/STMicroelectronics/cmsis_device_l4/blob/013bf0e41256ffbc2b539676f2007d08b297a86a/Include/stm32l471xx.h

    Some general tips on ADC accuracy are here. In particular, sampling time has a large effect.

    https://www.st.com/resource/en/application_note/an2834-how-to-optimize-the-adc-accuracy-in-the-stm32-mcus-stmicroelectronics.pdf

     

    rwils.1Author
    Visitor II
    December 2, 2023

    Thank you very much,

    it is a custom board and the VREF is AVDD , it is well decoupled and stable (measured with an oscilloscope). My approach is to measure the actual voltage present on the ADC pin and calculate the expected number of counts by VIN/VDDA*4096. I confess i haven't done the obvious check of tying the pin to ground and VDDA directly , that will take some board hacking, but I will do it regardless. i think your point about ADC sampling speed is salient. I'll slow down the sampling rate and see if that changes the result at all.

    i couldn't find DEEPPWD in the listing for the project CMSIS header file STM32L471x.h. After actually reading through the header file I realize it is ADC_CR_DEEPPWD. Now I understand the settings, thanks!

    I appreciate your help

     

    rwils.1Author
    Visitor II
    December 6, 2023

    TDK,

     Fixed!. As these problems always are it is simple once you know. When the ADC takes a reading, it charges an internal capacitor from voltage present on the pin. The output of the op-amp driving the pin drooped during this period. So where I thought I was measuring a stable DC voltage, I wasn't, I was sampling during the charge time. Once I realized this I changed the delay to the maximum time and everything works as expected. 

             ADC_ChannelConfTypeDef sConfig = {0};

             sConfig.Channel = ADC_CHANNEL_12;

             sConfig.Rank = ADC_REGULAR_RANK_1;

    --->    //sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;

             sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;

             sConfig.SingleDiff = ADC_SINGLE_ENDED;

             sConfig.OffsetNumber = ADC_OFFSET_NONE;

             sConfig.Offset = 0;

             if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

             {

               Error_Handler();

             }

    Pretty simple once you know! Thanks for your help

     

    Richard

     

     

    Graduate
    December 6, 2023

    Since an opamp is the signal source, you will probably still find joy at much lower sample cycles. The ADC section in the data sheet should provide the info needed.

    rwils.1Author
    Visitor II
    December 6, 2023

    Thank you very much, I'll investigate.