32-разрядное двоичное преобразование в 24-разрядное со знаком - PullRequest
0 голосов
/ 25 декабря 2018

Я использую 24-разрядный АЦП I2C с Arduino, и у нас нет 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), поэтому я немного застрял.Было бы здорово, если бы кто-нибудь смог мне помочь, так как я почти закончил с проектом, и это один из последних нескольких шагов.

Ответы [ 3 ]

0 голосов
/ 25 декабря 2018

Проблема в том, что не существует безопасного и портативного способа использовать сдвиг для расширения знака в 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;
}

это возьмет значение 24-битного дополнения до двух в uint32_t и преобразует его(подписано) int32_t.

0 голосов
/ 25 декабря 2018

Преобразование из 24-битного двоичного дополнения в uint32_t в 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 дает желаемое значение.

0 голосов
/ 25 декабря 2018

Используйте int32_t вместо unit32_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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...