Post Go back to editing

ADuC7061. ADC Offset Calibration Register (ADC0OF, ADC1OF)

After calibration Primary / Auxiliary Channel ADC Offset Calibration Register (ADC0OF, ADC1OF) always are read = 0. Both self-offset and zero-scale calibration mode. It is unclear how to correct the values for negative/positive offsets.

  • Hi,

    I saw that you attached an image, but it's not loading on my end.

    Have you checked the offset calibration register before initiating the calibration? Is the reading 0 as well?

    The ADC offset calibration register is automatically applied to the ADC reading to compensate for the offset error.

    Regards,

    Karl

  • Before initiating the calibration value of registers ADC0OF, ADC1OF is about 2..8.

  • What is the configuration for the ADCFLT register? Is chopping enabled?

  • Yes, of course:

    ADCFLT_CHOP_ENABLE | ADCFLT_RUNNING_AVERAGE | ADCFLT_NOTCH2
    +
     SF=9, AF=63 (Data_Rate=12.12Hz, Settling_Time=165ms, 50Hz --> -329dB)

  • Chopping already corrects the offset error. That is why the offset calibration register (ADC0OF, ADC1OF) reads as 0 after initiating the calibration since the chopping is enabled.

  • Primary (ADC0/ADC1)/ Auxiliary (ADC2/ADC3) channels are in differential mode, enable, external reference inputs (VREF+, VREF−).

    All the iput pins are short-circuited. (ADC0=ADC1=ADC2=ADC3).

    "Chop Enable = 1" does not correct the offset error Auxiliary (ADC2/ADC3) channel.

    Command ADC self-offset calibration: "ADCMDE  = ADCMDE_OFFSET_CAL | ADCCLKSEL_131KHZ;" does not correct the offset error Auxiliary (ADC2/ADC3) channel too.

    The value of offset error Auxiliary (ADC2/ADC3) channel = 1500 ... 3500.

    When using an internal reference, self-offset calibration works well. The value of offset error = 0..3.

  • Is there no difference in ADC output before and after enabling chop or performing ADC self-offset calibration?

    Are you using an ADuC7060 evaluation board or your board in testing the ADC?

    Can you show the register values and sequence used in configuring both?


  •    The board is its own. The board does not affect, because the inputs are short-circuited.

    Uref = 300 Ohm * 600 uA = 180 mV. Increasing the current to 1000uA (300 mV) has no effect.

        // Excitation Current Sources = 600 uA

        IEXCON  = BIT7 | BIT2 | BIT1; // IEXC1=1, 600uA
        DelayMS(2000);          // Delay 2000 mS



        // ADC0 = (ADC0/ADC1) pins
        // ADC1 = (ADC2/ADC3) pins

        ADCMDE  = ADC_IDLE_MODE;    // ADC idle mode
        // SF=7, AF=59 (Data_Rate=16.128Hz, Settling_Time=124ms, 50Hz --> -329dB)
        ADCFLT  = (ADCFLT_CHOP_ENABLE | (0x07 << 0) | (0x3B << 8));
        // ADC0 Gain=1, ext.ref (VREF+,VREF-), ADC0/ADC1
        ADC0CON = (ADC0CON_REF_EXT | ADC0CON_ADC0EN | ADC0CON_CHANNEL_DIFF_0_1);
        // ADC1 Gain=1, ext.ref (VREF+,VREF-), ADC2/ADC3
        ADC1CON = (ADC1CON_REF_EXT | ADC1CON_ADC0EN | ADC1CON_CHANNEL_2_3_DIFF);
        DelayMS(250);               // Delay 250 mS


        // Get Data ADC
        ADCMDE  = ADCMDE_VALUE;     // Continuous mode, ADCCLK = 512 kHz  
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        ADC1_Dat = ADC1DAT;        // Auxiliary ADC  =  107
        ADC0_Dat = ADC0DAT;        // Primary ADC    =  2564

        // ADC self-gain calibration
        ADCMDE  = ADCMDE_OFFSET_CAL | ADCCLKSEL_131KHZ;
        while(!(ADCSTA & ADCCALSTA)) {} // Wait ADC calibration status

        // Get Data ADC
        ADCMDE  = ADCMDE_VALUE;     // Continuous mode, ADCCLK = 512 kHz  
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        ADC1_Dat = ADC1DAT;        // Auxiliary ADC  =  -27
        ADC0_Dat = ADC0DAT;        // Primary ADC    =  2417









        // ADC0 = ADC1 = (ADC2/ADC3) pins


        ADCMDE  = ADC_IDLE_MODE;    // ADC idle mode
        // SF=7, AF=59 (Data_Rate=16.128Hz, Settling_Time=124ms, 50Hz --> -329dB)
        ADCFLT  = (ADCFLT_CHOP_ENABLE | (0x07 << 0) | (0x3B << 8));
        // ADC0 Gain=1, ext.ref (VREF+,VREF-), ADC2/ADC3
        ADC0CON = (ADC0CON_REF_EXT | ADC0CON_ADC0EN | ADC0CON_CHANNEL_DIFF_2_3);
        // ADC1 Gain=1, ext.ref (VREF+,VREF-), ADC2/ADC3
        ADC1CON = (ADC1CON_REF_EXT | ADC1CON_ADC0EN | ADC1CON_CHANNEL_2_3_DIFF);
        DelayMS(250);               // Delay 250 mS


        // Get Data ADC
        ADCMDE  = ADCMDE_VALUE;     // Continuous mode, ADCCLK = 512 kHz  
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        ADC1_Dat = ADC1DAT;        // Auxiliary ADC  =  2480
        ADC0_Dat = ADC0DAT;        // Primary ADC    =  2488

        // ADC self-gain calibration
        ADCMDE  = ADCMDE_OFFSET_CAL | ADCCLKSEL_131KHZ;
        while(!(ADCSTA & ADCCALSTA)) {} // Wait ADC calibration status

        // Get Data ADC
        ADCMDE  = ADCMDE_VALUE;     // Continuous mode, ADCCLK = 512 kHz  
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        while (!(ADCSTA & (ADC0RDY | ADC1RDY))) {}  // Wait new data
        ADC1_Dat = ADC1DAT;        // Auxiliary ADC  =  2447
        ADC0_Dat = ADC0DAT;        // Primary ADC    =  2478



  • Can you check the ADC reading before and after calibration if the primary and auxiliary ADC configuration uses the internal reference?

    Can you also try performing a system zero-scale calibration using your ADC configurations?

  • Internal reference, before calibration:  ADC0 = 2730;  ADC1 = 4772

    Internal reference, after calibration:  ADC0 = 1;   ADC1 = -3

    As an experiment, I tried to use zero-scale calibration. Works well. But to do this,have to short the channel externally. In work it is impossible.