Эффективный способ создания / распаковки больших битовых полей в C? - PullRequest
3 голосов
/ 05 апреля 2010

У меня есть один микроконтроллер, берущий выборку из множества АЦП и отправляющий измерения по радио с очень низкой скоростью передачи битов, и пропускная способность становится проблемой.

Прямо сейчас каждый АЦП дает нам только 10 бит данных, и они хранятся в 16-битном целом числе. Есть ли простой способ упаковать их детерминированным образом, чтобы первое измерение было с битом 0, второе с битом 10, третье с битом 20 и т. Д.?

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

РЕДАКТИРОВАТЬ: Пока что мне больше всего нравится @ MSN's answer, но я отвечу на комментарии

@ EvilTeach: Я не уверен, был ли бы полезен точный битовый шаблон или как лучше отформатировать его только с текстом, но я подумаю об этом.

@ Джонатан Леффлер: В идеале я бы упаковал 8 10-битных значений в 10 8-битных байтов. Если это облегчит обработку, я бы согласился на 3 значения в 4 байта или 6 значений в 8 байтов (хотя эти 2 эквивалентны мне, такое же количество «потерянных» битов)

Ответы [ 3 ]

4 голосов
/ 05 апреля 2010

Используйте биты 0 и 31 для определения порядка байтов и упакуйте 3 10-битные значения в середину. Один простой способ проверить соответствие порядку байтов - установить бит 0 в 0 и бит 31 в 1. На принимающей стороне, если бит 0 равен 1, подтвердить, что бит 31 равен 0, и поменять местами. В противном случае, если бит 0 равен 0, подтвердите, что бит 31 равен 1, и извлеките 3 значения.

3 голосов
/ 05 апреля 2010

Вы можете использовать битовые поля, но порядок внутри машинных слов не определен:

Тем не менее, это будет выглядеть примерно так:

struct adc_data { 
unsigned first :10;
unsigned second :10; 
unsigned third :10; 
};

РЕДАКТИРОВАТЬ: Исправлено, благодаря Джонатану.

0 голосов
/ 05 апреля 2010

Самое простое, что нужно сделать с порядком байтов, это просто выбрать один для передачи. Чтобы упаковать биты в поток передачи, используйте аккумулятор (по крайней мере, 17 бит в вашем случае), в котором вы сдвигаете по 10 бит за раз и отслеживаете, сколько в нем битов. Когда вы передаете байт, вы вытаскиваете байт из аккумулятора, вычитаете 8 из своего счета и сдвигаете аккумулятор на 8. Я здесь использую «передачу» свободно, вы, вероятно, сохраняете в буфер для последующей передачи.

Например, если передача имеет прямой порядок байтов, вы сдвигаете свои 10 бит вверху аккуматора (в его битах MS) и вытягиваете свои байты снизу. Например: для двух значений a и b:

Accumulator     Count
(MS to LS bit)   
aaaaaaaaaa      10      After storing a
aa              2       After sending first byte
bbbbbbbbbbaa    12      After storing b
bbbb            4       After sending second byte

Прием является аналогичной операцией распаковки.

...