5
\$\begingroup\$

I'm using LTC2485 and got confused by the provided software code vs. the datasheet. As described in LTC2485 I2C Data Format the LTC2485 ADC is 24 bits + sign ADC so like 25 bits.

In the given software code multiply by 2 then divide the result by 256 to get back from 32 bits to 24 bits but in doing this we "loose" the bit 6 that was supposed to contain information, right?

Can you explain what's going on here vs. the datasheet?

data.LT_byte[3]=data.LT_byte[3] & 0x7F; //Remove sign bit
data.LT_int32 = data.LT_int32 << 1; //shift left by one bit to restore two's complement
data.LT_int32/=256;  //Convert back to 24 bit value from 32 bits

According to the datasheet BIT31 is SIGN, BIT30 is MSB, next 24 bits are data and remaining 6 bits are under LSB (noise). That's why I would have expect /=128 instead to have real 24 bits + sign result. My understanding is that BIT31 SIGN is more like "overflow bit" and BIT30 MSB is the real "sign bit". But maybe I'm missing something.

Edit : I have a theory ! Library bits manipulation theory

That would make the library to work but the datasheet is wrong somewhere !

The first two bits (SIG and MSB) can be used to indicate over range conditions. If both bits are HIGH, the differential input voltage is above +FS and the following 24 bits are set to LOW to indicate an overrange condition. If both bits are LOW, the input voltage is below –FS and the following 24 bits are set to HIGH to indicate an underrange condition. The function of these two bits is summarized in Table 1. The next 24 bits contain the conversion results in binary two’s complement format. The remaining six bits are Sub LSBs below the 24-bit level.

In fact MSB seems to be part of those 24 bits so this lets 7 bits remaining...

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I do not believe their code will give the correct result when in an overflow. As in this case the meaning of the highest bit is different.

This code seems to give correct result over the full range on my bench.

float toVoltage(
   int32_t byte1, int32_t byte2, int32_t byte3, int32_t byte4, 
   float vRef, bool* overflow)
{    
    bool sign = byte1 & 0x80;
    bool msb = byte1 & 0x40;

    int32_t adcValue = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;    
    adcValue = adcValue << 1; // restore 2's compliment

    float volts;
    if( (sign != msb) || (adcValue==0) )  // normal
    {
        volts = vRef/2.0f * ((float)adcValue / (float)0x7FFFFFFF);
    }
    else // indicates overflow
    { 
        *overflow = true;
        volts = vRef/2.0f * (sign ? 1.0f : -1.0f);
    }

    return volts;
}
```
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.