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.
ADUC7061
Production
The ADuC7060/ADuC7061 are fully integrated, 8 kSPS, 24-bit data acquisition systems incorporating high performance multi-channel sigma-delta (S-?) analog...
Datasheet
ADUC7061 on Analog.com
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
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
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.