繁体   English   中英

32 位二进制到 24 位有符号转换

[英]32 bit binary to 24 bit signed conversion

我在 Arduino 上使用了 24 位 I2C ADC,并且没有 3 字节(24 位)数据类型,所以我改用了uint32_t ,它是一个 32 位无符号整数。 然而,我的实际输出是一个 24 位有符号数,如下所示:

如果您有兴趣,这里还有我用来阅读结果的代码:

uint32_t readData(){
  Wire.beginTransmission(address);
  Wire.write(0x10);
  Wire.endTransmission();
  Wire.requestFrom(address,3);
  byte dataMSB = Wire.read();
  byte data = Wire.read();
  byte dataLSB = Wire.read();
  uint32_t data32 = dataMSB;
  data32 <<= 8;
  data32 |= data;
  data32 <<= 8;
  data32 |= dataLSB;
  return data32;
}

为了使这个数字有用,我需要将它转换回一个 24 位有符号整数(如果可能,我不知道该怎么做或前夕,因为 24 不是 2 的幂)所以我是有点卡住了。 如果有人能帮助我就好了,因为我几乎完成了项目,这是最后几步之一。

问题是在 C 中没有安全且可移植的方法来使用移位进行符号扩展——充其量它是实现定义的。 因此,如果您想便携地执行此操作,则需要手动将您的 2s 补码值转换为有符号整数。

int32_t cvt24bit(uint32_t val) {
    val &= 0xffffff;  // limit to 24 bits -- may not be necessary
    if (val >= (UINT32_C(1) << 23))
        return (int32_t)val - (INT32_C(1) << 24);
    else
        return val;
}

这将在 uint32_t 中获取您的 24 位二进制补码值并将其转换为(有符号的)int32_t。

可以通过以下方式将uint32_t 24 位二进制补码转换为int32_t

int32_t Convert(uint32_t x)
{
    int32_t t = x & 0xffffff;
    return t - (t >> 23 << 24);
}

x & 0xffffff确保数字没有高于第 23 位的伪位。如果确定没有设置这些位,那么语句可以只是int32_t t = x; .

然后t >> 23删除第 0 到 22 位,只留下第 23 位,它是 24 位整数的符号位。 然后<< 24对此进行缩放,产生 0(对于正数)或 2 24 (对于负数)。 t减去它会产生所需的值。

unit32_t使用int32_t而不是data32 然后在返回值之前,将其向左移动 8,然后向右移动 8 以对其进行符号扩展。

所以这段代码:

uint32_t readData(){
  Wire.beginTransmission(address);
  Wire.write(0x10);
  Wire.endTransmission();
  Wire.requestFrom(address,3);
  byte dataMSB = Wire.read();
  byte data = Wire.read();
  byte dataLSB = Wire.read();
  int32_t data32 = dataMSB;
  data32 <<= 8;
  data32 |= data;
  data32 <<= 8;
  data32 |= dataLSB;
  return (data32 << 8) >> 8;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM