将 Q18.2 转换为浮点数
Convert Q18.2 to float
我正在尝试从 MPL3115 读取压力值。
在第 14.3 章,ds 说:
The pressure data is stored as a 20-bit unsigned integer with a fractional part. The
OUT_P_MSB (01h), OUT_P_CSB (02h) and bits 7 to 6 of the OUT_P_LSB (03h)
registers contain the integer part in Pascals. Bits 5 to 4 of OUT_P_LSB contain the
fractional component. This value is representative as a Q18.2 fixed point format where
there are 18 integer bits and two fractional bits.
这是我的 Microchip XMEGA (GCC) 的(测试)代码:
#define MPL3115_ADDRESS 0x60
#define MPL3115_REG_PRESSURE_DATA 0x01
bool _ReadRegister(uint8_t address, uint8_t *readBuf, uint8_t readCount)
{
TWI_MasterWriteRead(&twiMaster, MPL3115_ADDRESS, &address, 1, readCount);
while (twiMaster.status != TWIM_STATUS_READY);
memcpy(readBuf, (void *) twiMaster.readData, readCount);
return true;
}
bool MPL3115_ReadPressure(float *value) {
uint8_t raw[3];
_ReadRegister(MPL3115_REG_PRESSURE_DATA, raw, 3);
uint32_t data = (((uint32_t) raw[0]) << 16) | (((uint32_t) raw[1]) << 8) | raw[2];
uint32_t q18n2 = data >> 4;
*value = (double) q18n2 / 4;
return true;
}
我很确定 i2c 线路正常工作,因为我可以从同一芯片成功读取温度。
我将其配置为气压计模式和 128 过采样 (CTRL_REG1 = 0x38)。
在调试模式下,我读取了以下值:
- raw0 = 0x18
- raw1 = 0x25
- raw2 = 0x70
- 数据=1582448
为了获得 Pascal 的压力,我必须右移 4 位数据:
- q18n2 = 98908
现在要将 Q18.2 转换为浮点数,我应该乘以 2^-n 或除以 4:
- 值 = 24727 Pa
这应该是帕斯卡单位,所以除以 100 得到 mBar = 247.27 mBar...我这里不太可能有这么大的压力!顺便说一句,现在应该在 1008 mBar 左右。
我的想法有没有错误?
必须右移6位数据,然后加上小数部分(2位*0.25)。
*value = (raw0 << 10) | (raw1 << 2) | (raw2 >> 6);
*value += 0.25 * ((raw2 >> 4) & 0x03);
我正在尝试从 MPL3115 读取压力值。 在第 14.3 章,ds 说:
The pressure data is stored as a 20-bit unsigned integer with a fractional part. The OUT_P_MSB (01h), OUT_P_CSB (02h) and bits 7 to 6 of the OUT_P_LSB (03h) registers contain the integer part in Pascals. Bits 5 to 4 of OUT_P_LSB contain the fractional component. This value is representative as a Q18.2 fixed point format where there are 18 integer bits and two fractional bits.
这是我的 Microchip XMEGA (GCC) 的(测试)代码:
#define MPL3115_ADDRESS 0x60
#define MPL3115_REG_PRESSURE_DATA 0x01
bool _ReadRegister(uint8_t address, uint8_t *readBuf, uint8_t readCount)
{
TWI_MasterWriteRead(&twiMaster, MPL3115_ADDRESS, &address, 1, readCount);
while (twiMaster.status != TWIM_STATUS_READY);
memcpy(readBuf, (void *) twiMaster.readData, readCount);
return true;
}
bool MPL3115_ReadPressure(float *value) {
uint8_t raw[3];
_ReadRegister(MPL3115_REG_PRESSURE_DATA, raw, 3);
uint32_t data = (((uint32_t) raw[0]) << 16) | (((uint32_t) raw[1]) << 8) | raw[2];
uint32_t q18n2 = data >> 4;
*value = (double) q18n2 / 4;
return true;
}
我很确定 i2c 线路正常工作,因为我可以从同一芯片成功读取温度。 我将其配置为气压计模式和 128 过采样 (CTRL_REG1 = 0x38)。 在调试模式下,我读取了以下值:
- raw0 = 0x18
- raw1 = 0x25
- raw2 = 0x70
- 数据=1582448
为了获得 Pascal 的压力,我必须右移 4 位数据:
- q18n2 = 98908
现在要将 Q18.2 转换为浮点数,我应该乘以 2^-n 或除以 4:
- 值 = 24727 Pa
这应该是帕斯卡单位,所以除以 100 得到 mBar = 247.27 mBar...我这里不太可能有这么大的压力!顺便说一句,现在应该在 1008 mBar 左右。
我的想法有没有错误?
必须右移6位数据,然后加上小数部分(2位*0.25)。
*value = (raw0 << 10) | (raw1 << 2) | (raw2 >> 6);
*value += 0.25 * ((raw2 >> 4) & 0x03);