【问题标题】:Convert Q18.2 to float将 Q18.2 转换为浮点数
【发布时间】:2023-04-04 13:10:01
【问题描述】:

我正在尝试从MPL3115 读取压力值。 ds 在第 14.3 章说:

压力数据存储为带有小数部分的 20 位无符号整数。这 OUT_P_MSB (01h)、OUT_P_CSB (02h) 和 OUT_P_LSB (03h) 的位 7 至 6 寄存器包含帕斯卡的整数部分。 OUT_P_LSB 的位 5 到 4 包含 分数成分。该值代表 Q18.2 定点格式,其中 有 18 个整数位和 2 个小数位。

这是我的 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

要获得帕斯卡的压力,我必须右移 4 位数据:

  • q18n2 = 98908

现在要将 Q18.2 转换为浮点数,我应该乘以 2^-n 或除以 4:

  • 值 = 24727 帕

这应该是帕斯卡,所以除以 100 并得到 mBar = 247.27 mBar……我这里不太可能有这么大的压力!顺便说一下,现在应该是 1008 mBar 左右。

我的想法有什么错误吗?

【问题讨论】:

  • 您的计算似乎正确,可能您的设备设置不正确或有缺陷?
  • 这是个好消息!我可能会尝试焊接一个新的。不管怎么说,温度读数是完美的,因此应该只有芯片的压力部分有缺陷......
  • 嗯,也许您正在读取垃圾数据,因为新样本尚未准备好?您是否尝试过禁用过采样并查看它是否有任何不同?
  • 禁用过采样不会改变任何事情,我正在等待足够的时间来获取新样本(每 2 秒读取一次)。
  • 为什么是MPL3115_ReadPressure(float *value) ... *value = (double) q18n2 / 4; 而不是... *value = (float) q18n2 / 4;

标签: c floating-point fixed-point


【解决方案1】:

您必须将 6 位数据右移,然后添加小数部分(2 位 * 0.25)。

*value = (raw0 << 10) | (raw1 << 2) | (raw2 >> 6);
*value += 0.25 * ((raw2 >> 4) & 0x03);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 2011-02-28
    • 2020-08-25
    • 2020-05-14
    • 2012-05-25
    相关资源
    最近更新 更多