我从温度传感器(MCP9808类型)读取这个16位值。

忽略前三个MSBs,有什么简单的方法可以将其他位转换成浮点数?我设法将值2^7到2^0转换为整数,并进行了一些位移位:
uint16_t rawBits = readSensor();
int16_t value = (rawBits << 3) / 128;但是,我想不出一种简单的方法也包括指数小于0的位,除非手动检查它们是否被设置,然后分别将1/2、1/4、1/8和1/16添加到结果中。
发布于 2021-06-24 14:08:10
像这样的事似乎很合理。取数字部分,除以16,并固定标志。
float tempSensor(uint16_t value) {
bool negative = (value & 0x1000);
return (negative ? -1 : 1) * (value & 0x0FFF) / 16.0f;
}发布于 2021-06-24 14:01:46
float convert(unsigned char msb, unsigned char lsb)
{
return ((lsb | ((msb & 0x0f) << 8)) * ((msb & 0x10) ? -1 : 1)) / 16.0f;
}或
float convert(uint16_t val)
{
return (((val & 0x1000) ? -1 : 1) * (val << 4)) / 256.0f;
}发布于 2021-06-24 14:26:46
如果性能不是一个超级大问题,我会选择一些不那么聪明、解释得更清楚的东西,大致如下:
bool is_bit_set(uint16_t value, uint16_t bit) {
uint16_t mask = 1 << bit;
return (value & mask) == mask;
}
float parse_temperature(uint16_t raw_reading) {
if (is_bit_set(raw_reading, 15)) { /* temp is above Tcrit. Do something about it. */ }
if (is_bit_set(raw_reading, 14)) { /* temp is above Tupper. Do something about it. */ }
if (is_bit_set(raw_reading, 13)) { /* temp is above Tlower. Do something about it. */ }
uint16_t whole_degrees = (raw_reading & 0x0FF0) >> 4;
float magnitude = (float) whole_degrees;
if (is_bit_set(raw_reading, 0)) magnitude += 1.0f/16.0f;
if (is_bit_set(raw_reading, 1)) magnitude += 1.0f/8.0f;
if (is_bit_set(raw_reading, 2)) magnitude += 1.0f/4.0f;
if (is_bit_set(raw_reading, 3)) magnitude += 1.0f/2.0f;
bool is_negative = is_bit_set(raw_reading, 12);
// TODO: What do the 3 most significant bits do?
return magnitude * (is_negative ? -1.0 : 1.0);
}老实说,这是很多简单的常量数学,如果编译器不能对其进行大量优化,我会感到惊讶的。当然,这需要确认。
https://stackoverflow.com/questions/68117185
复制相似问题