Home

ADC produces near maximum output when input is 0V

E-mail Print PDF
( 0 Votes )
Question: I am using the Delta Sigma ADC in the single ended mode to measure an input voltage starting from VSS (0-1.024V, 0-2.048V etc).  When the input is 0V, the output of the ADC goes to near full scale.  What is the cause for this and what is the solution?

Answer: The single ended ADC is nothing but a differential ADC implementation where the sign is ignored.  When the offset voltage of the ADC is +ve, there will be no problem in measurement and the ADC result will be above 0x0000 when input is 0V.  But when the ADC offset is negative, the otuput of the ADC produces a -ve result and when sign bit is ignored, the result is a positive number which is near full scale voltage.  For example if the input offset is equal to -3 counts of ADC result, the signed result from a 24 bit decimator would be 0xFFFFFD. The MSB of this 24 bit result is dropped and the lower 16 bits are returned as unsigned result.  Now, the result is 0xFFFD which is equal to 65533 in unsigned value.
A work around is to check the sign bit of the 24 bit decimator output and if the sign bit is 1, set the ADC result to 0x0000.  For example, the following is the code from the ADC_Delsig_1_GetResult16 function found in ADC_Delsig_1.c file.

int16 ADC_Delsig_1_GetResult16(void)
{
    uint16 result;
    result = ADC_Delsig_1_DEC_SAMPM ;
    result = (result << 8 ) | ADC_Delsig_1_DEC_SAMP;
    return( result );
}

This may be modified to

int16 ADC_Delsig_1_GetResult16(void)
{
    uint16 result;

    // Check if the sign bit in the MSB of the 24 bit
    // decimator register is set.  If yes, return a value of 0
    if(ADC_Delsig_1_DEC_SAMPH & 0x10)
        return 0;

    // If sign is not -ve, then read the result from the lower
    // 16 bits and return
    result = ADC_Delsig_1_DEC_SAMPM ;
    result = (result << 8 ) | ADC_Delsig_1_DEC_SAMP;
    return result;
}

In the above method, the ADC result will always saturate to 0x00000 when the ADC offset voltage is negative.

Caveats:
  1. The addition of code adds some overhead to the ADC_GetResult function.  At very high sample rates, you need to make sure that this overhead does not exceed the ADC's conversion time.
  2. This method can only be used where the result of the ADC is read in firmware.  When the ADC result is being transferred using DMA, this will not work.  So, when using DMA, using single ended mode is not advisable.
Tags: PSoC3 ADC Analog
Comments (2)
  • alager  - How would I do this on the ADCINC?
    I put this into the ISR (ADCINCINT.asm):

    ; Sample data is now in iResult
    tst reg[DEC_DH], 0x10 //see if the MSB is set
    jz done_checkfornegative
    mov [VA_ADCINC_iResult + LowByte], 0 //since the 16th bit of a 13bit number is set, it must be negative, return 0 instead
    mov [VA_ADCINC_iResult + HighByte], 0
    done_checkfornegative:

    But I only get 0 a result. How would this be done for this A2d?

    thanks,
    Aaron
  • graaja
    Aaron,
    The DEC_DH register is not the correct register to check for negative result. Instead directly check MSB of the [VA_ADCINC_iResult + HighByte] for negative value. If set, reset both the LowByte and HighByte values.
    Regards,
    Ganesh
Only registered users can write comments!