Least significant byte
[BIT1 BIT0 xx xx xx xx xx xx ]
The 10 bit number represents the temperature in Degrees C with a 0.25 degree/bit resolution. So here's how I am trying to get the value of the registers:
float DS3234::get_temp(void)
{
int16_t temperature = 0x00; // initialize to zero
this->_busy_wait(); // wait for chip not busy
this->_write_spi(0x8E, 0x20); // force a temperature conversion
temperature |= (this->_read_spi(0x11, 0x00) << 8); // get hi bits
temperature |= this->_read_spi(0x12, 0x00); // get lo bits
return (float)(temperature / 256.0); // return chip temperature
}
What the code does is take a SIGNED 16 bit int (temperature), then OR in the two register values. The sign bit gets placed in bit 15 of "temperature" which makes it positive or negative depending on the sign bit. Finally I divide by 256.0 which in effect "bit shifts" the data down to where the "xxx" bits are, then divides by 4 to convert each bit into 0.25 degree increments and returns the result as a float.
My question is: Am I right in "depending" on a signed int to work properly to give me my positive and negative values, or is there a "better way" to do it?
What you have done is fine as long as the sensor (which one is it??) gives you a twos complement number.
One slight/minor tweak would be to not initialize temperature to zero and then the first read would be:
temperature = (this->_read_spi(0x11, 0x00) << 8); // get hi bits
But I have seen (IIRC) a sensor that gives the temperature in sign-magnitude format. In that case the number must be handled a bit differently.
el_supremo:
What you have done is fine as long as the sensor (which one is it??) gives you a twos complement number.
One slight/minor tweak would be to not initialize temperature to zero and then the first read would be:
temperature = (this->_read_spi(0x11, 0x00) << 8); // get hi bits
But I have seen (IIRC) a sensor that gives the temperature in sign-magnitude format. In that case the number must be handled a bit differently.
Pete
It's the sensor in the Dallas/Maxim DS3234 RTC chip.
The datasheet describes the register as such:
The temperature is encoded in two’s complement format, with bit 7 in the MSB representing the SIGN bit. The upper 8 bits, the integer portion, are at location 11h and the lower 2 bits, the fractional portion, are in the upper nibble at location 12h. Example: 00011001 01b = +25.25°C.
I wish they had given a negative temperature example as well so I could check my function!
float DS3234::get_temp(void)
{
int16_t temperature;
_busy_wait(); // wait for not busy
_write_spi(0x8E, 0x20); // force a temperature conversion
temperature = (_read_spi(0x11, 0x00) << 8); // get hi bits
temperature |= _read_spi(0x12, 0x00); // get lo bits
temperature >>= 6; // slide bits down
return (float)(temperature / 4.0);
}
Is there any functional difference between shifting right 6 and divide by 4 as opposed to divide by 256?