Я хотел бы напечатать как MSB, так и LSB переменной u16, вот мой код:

__u16 reg = 0x10A0; /* Device register to access */
__s32 res;
char buf[10];

buf[0] = reg;

printf("0x%X\n", buf[0]);

Этот код просто печатает часть LSB в шестнадцатеричном формате, но вы можете сказать мне, как мне распечатать часть MSB?

0
Martin Denion 24 Фев 2021 в 11:41

1 ответ

Лучший ответ

Этот код просто печатает часть LSB

Конечно, buf[0] = reg; копирует только 8 бит.

И какой результат вы получите, точно не определено, потому что char не может надежно хранить необработанный двоичный файл. Он может быть подписан в ваших системах, и тогда вы можете получить из-за него всевозможные тонкие ошибки.

Шаг 1 - исправить ваши типы. Избавьтесь от char, а также от самодельных стандартных целочисленных типов в пользу стандартных типов C:

#include <stdint.h>

uint16_t reg = 0x10A0u; 
uint8_t  buf [10];

Затем определите порядок байтов вашего массива. Предполагая, что вы хотите, чтобы индекс 0 был самым значимым байтом, тогда быстрая и грязная версия будет выглядеть так:

buf[0] = reg >> 8;
buf[1] = reg;

Это сработает в данном конкретном случае. Однако хорошие компиляторы будут стонать по поводу неявных рекламных акций и тому подобного. Строго говоря, вы должны иметь привычку всегда приводить к uint32_t перед тем, как выполнять какие-либо сдвиги (при условии, что> = 32-битная система). Мы можем сделать код более жестким и отключить такие предупреждения:

buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

Этот метод безопасно масштабируется и для более крупных типов.

Кроме того, различные решения шарлатана на SO и в других местах говорят вам использовать для этого union или символьные указатели. Такие решения делают код излишне зависимым от байтов. Версия shift на 100% переносима даже между процессорами с разным порядком байтов.

Затем, наконец, печать с помощью printf. Вы можете получить правильный описатель формата для любого uintn_t автоматически из заголовка inttypes.h. Он предоставляет PRIx8 для шестнадцатеричного нижнего регистра и PRIX8 для шестнадцатеричного верхнего регистра.

Полная программа:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

int main (void)
{
  uint16_t reg = 0x10A0u; 
  uint8_t  buf[10];

  buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
  buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

  printf("0x%"PRIX8 "%"PRIX8 "\n", buf[0], buf[1]);
}
1
Lundin 24 Фев 2021 в 10:20