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:
- 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.
- 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.




; 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