Как инвертировать 16-битное шестнадцатеричное значение в C? - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь изменить свое значение данных Pressure и сохранить этот обратный результат в целых числах uint16_t Pcounts. Я нашел макрос, который можно использовать, и он, кажется, переворачивает некоторые биты, но не другие. Вот мой код:

#define REV(X) ((X << 24) | (((X>>16)<<24)>>16) | (((X<<16)>>24)<<16) | (X>>24))

uint16_t PressureData;
uint16_t Pcounts;
Pcounts = REV(PressureData);

Если PressureData = 0xAABB, я ожидаю, что Pcounts будет 0xBBAA. Однако это значение равно 0xBB00.

PressureData - это значение давления, измеренное датчиком в реальном времени.

Ответы [ 2 ]

2 голосов
/ 16 марта 2020

Если PressureData = 0xAABB, я ожидаю, что Pcounts будет 0xBBAA.

Допустим, с abcd, OP хочет cdab (байт), а не dcba ( nibble swap):

Ниже приведено обратное преобразование байтов для 32-битного значения. @ Какой-то программист чувак

#define REV(X) ((X << 24) | (((X>>16)<<24)>>16) | (((X<<16)>>24)<<16) | (X>>24))

Чтобы инвертировать байты для 16-битного беззнакового значения. @ Eri c (Уведомление () о X.)

#define REV16_A(X) (((X) << 8) | ((X)>>8))

Лучший код не будет зависеть от знака, но вызовет проблему.

#define REV16_B(X) (((uint16_t)(X) << 8) | ((uint16_t)(X)>>8))

Тем не менее, я вижу небольшую причину для макроса здесь и просто использую вспомогательную функцию. Сделайте это inline, если хотите.

uint16_t rev16(uint16_t x) {
  return (x << 8) | (x >>8);
}

Кроме того, я ожидаю, что желание перевернуть байты является проблемой endian . Так что, если код портирован, переключение байтов может / не может быть желательным. В этом случае вполне вероятно, что оборудование представляет байты в определенном порядке байтов, который может / не может совпадать с собственным порядком байтов кода. Рассмотрим вспомогательную функцию для этого.

uint16_t endian_hw_to_native16(uint16_t x) {
  // endian sensitive code ...
}
0 голосов
/ 16 марта 2020

Проблема в том, что вы переопределяете некоторые биты.

Попробуйте использовать функцию вместо макроса:

swapped = ((input>>8)&0x0f) | // move byte 1 to byte 0
           (input<<8)&0xf0)); // byte 0 to byte 1
...