ATTINY84: странная проблема с обращенным порядком байтов - PullRequest
0 голосов
/ 12 апреля 2019

Я кодирую 6 значений (4x 3 бита + 1 бит) в 16-битное целое число и передаю их через последовательный порт в ATTINY84, разделяя их на 2 байта. Это работает хорошо до тех пор, пока я не соберу байты в 16-битное целое число.

Пример:

Я отправляю следующее двоичное состояние 0001110000001100, которое переводится в 7180 и разбивается на байтовый массив [18, 28].

Я помещаю этот байтовый массив в EEPROM и читаю его в следующем цикле питания.

После отключения питания мой последовательный вывод отладки выглядит следующим образом:

18
28
7180

Высокий. Выглядит все хорошо, и мой код для этой части:

byte d0 = EEPROM.read(0);
byte d1 = EEPROM.read(1);
unsigned int w = d0 + (256 * d1);

Но теперь происходит самое странное. Когда я читаю понемногу, я возвращаюсь:

0011000000111000

should be:

0001110000001100

с помощью:

 for(byte t = 0; t < 16; t++) {
    serial.print(bitRead(w, t) ? "1" : "0");
  }

Представление бит полностью перевернуто. Как это возможно? Или, может быть, я что-то упустил.

Также я подтвердил, когда извлекаю фактическое 3-битное местоположение для получения моего исходного значения 0..7 все выключено.

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 12 апреля 2019

Похоже, я попал в маленькую / большую ловушку с обратным порядком байтов.

В основном, как сказал Ален, в комментариях - все правильно, и это просто представления.

Я придумал следующий метод, который может извлекать биты из порядкового номера с прямым порядком байтов, который должен быть в формате с прямым порядком байтов:

/**
 * @bex
 */
uint8_t bexd(uint16_t n, uint8_t o, uint8_t l, uint8_t d) {
  uint8_t v = 0;
  uint8_t ob = d - o;
  for (uint8_t b=ob; b > (ob-l); b--) v = ( v << 1 ) | ( 0x0001 & ( n >> (b-1) ) );
  return v;
}
uint8_t bexw(uint16_t n, uint8_t o, uint8_t l) {return bexd(n, o, l, 16);}
uint8_t bexb(uint8_t n, uint8_t o, uint8_t l) {return bexd(n, o, l, 8);}

Например:

В старшем порядке байтов «второе» значение сохраняется в битах 3,4 и 5 по сравнению с младшим порядковым номером, где оно будет храниться в битах 10, 11 и 12. Вышеописанный метод позволяет работать в «младшем порядке» "value, как будто это будет значение с" прямым порядком байтов ".

Чтобы извлечь второе значение из этого значения 0011000000111000, просто выполните:

byte v = bex(7180, 3, 3);  // 111
Serial.println(v); // prints 255

Надеюсь, это кому-нибудь поможет.

...