Skip to main content
gustavo
Associate
June 13, 2013
Question

STM32F303 Discovery board ADC offset

  • June 13, 2013
  • 5 replies
  • 1204 views
Posted on June 13, 2013 at 09:18

Hi,

I've configured ADC1 to sample one of the channels like PA1 (Channel 2). However,

when I connect a power supply to the input, there is a large offset. For example, connecting 2V I can see around 200-250mV offset. Below is my code. I can see the adc value change with the change in input voltage, but I am not sure whether some specific calibration is required. Any insight is appreciated.

GPIO_TypeDef * adcChanPortType;

    

    ADC_InitTypeDef       ADC_InitStructure;

    ADC_CommonInitTypeDef ADC_CommonInitStructure;

    /* Configure the ADC clock */

    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);

    /* Enable ADC1/2 clock */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);

    /* ADC Channel configuration */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    

    GPIO_InitTypeDef      GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(adcChanPortType, &GPIO_InitStructure);

        

    ADC_StructInit(&ADC_InitStructure);

    /* Calibration procedure */

    ADC_VoltageRegulatorCmd(ADC1, ENABLE);

    // Insert delay equal to 10 µs

    // To allow regulator to settle

    unsigned long int i = 4800;

    for(;i>0;i--);

    ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);

    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1) != RESET );

    //calibration_value = ADC_GetCalibrationValue(ADC1);

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

    ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;

    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

    ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;

    ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;

    ADC_CommonInit(ADC1, &ADC_CommonInitStructure);

    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;

    ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;

    ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;

    ADC_InitStructure.ADC_NbrOfRegChannel = 1;

    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 configuration */

    ADC_RegularChannelConfig(ADC1, adcChanNum, 1, ADC_SampleTime_181Cycles5);
    This topic has been closed for replies.

    5 replies

    raptorhal2
    Lead
    June 13, 2013
    Posted on June 13, 2013 at 15:36

    Disconnect the power supply and connect board ground to PA1 to see if is a grounding problem with the power supply.

    Cheers, Hal

    gustavo
    gustavoAuthor
    Associate
    June 14, 2013
    Posted on June 14, 2013 at 05:23

    Hal,

    I did so. When I connect ground I see 0 at the output. When the pin is floating I see 160/170mV.

    Thanks

    raptorhal2
    Lead
    June 14, 2013
    Posted on June 14, 2013 at 14:23

    That is normal. The sample and hold channel capacitor will drift if the input is not connected to a low impedance signal.

    You didn't say, but I am guessing the power supply signal source is grounded to the wall socket, and so is the Programming/debug PC providing ground to the board. Or you have something similar causing a ground loop. You are using a long sample time, so the problem is external to the processor.

    Cheers, Hal

    mattfox
    Associate III
    July 12, 2013
    Posted on July 12, 2013 at 21:19

    Hi,  

    I've been having a really similar issue as you, where I have my ADC running really well except for when I have USART connected (or any driven pin for certain pins around the ADC).  I described my problem here: 

    [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32F3%20Discovery%20-%20ADC%20Offset&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/AllItems.aspx&currentviews=25]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fSTM32Discovery%2fSTM32F3%20Discovery%20-%20ADC%20Offset&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&TopicsView=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FAllItems%2Easpx&currentviews=25

    I was wondering if you made any progress or learned a solution to this problem, as I can't seem to find one anywhere online.  I'd love to hear about how you've moved forward with this problem!

    mattfox
    Associate III
    July 13, 2013
    Posted on July 13, 2013 at 05:06

    I figured out the solution just now.  If anyone is interested, I posted a fairly detailed solution on the thread that I linked to above.