Отображение числа в битовую позицию в C - PullRequest
0 голосов
/ 10 октября 2018

Я разрабатываю программу, работающую на Atmel AT90CAN128.К этому контроллеру подключено 40 устройств, каждое из которых имеет статус (вкл / выкл).Поскольку мне нужно сообщать о состоянии каждого из этих устройств на ПК через последовательную связь, у меня есть 40 битов, которые определяют, включено ли устройство или нет.Кроме того, ПК может включать и выключать любое из этих устройств.

Итак, моей первой попыткой было создать следующую структуру:

typedef struct {
     unsigned char length;      //!< Data Length
     unsigned data_type;        //!< Data type
     unsigned char data[5];     //!< CAN data array 5 * 8 = 40 bits
} SERIAL_packet;

Проблема с этим состояла в том, что ПКunsigned char address отправит мне сообщение о включении / выключении устройства, поэтому доступ к биту, соответствующему этому номеру address, оказался довольно сложным ...

Итак, я начал искать варианты, иЯ наткнулся на тип C99 _Bool.Я подумал, отлично, так что теперь я просто создаю _Bool data[40], и я могу получить доступ к биту address, просто проиндексировав мой массив data.Оказывается, что в C (или C ++) для отображения памяти требуется целый байт для ее адресации.Таким образом, даже если я объявлю _Bool размер этого _Bool будет 8 бит, что является проблемой (это должно быть как можно быстрее, поэтому, чем больше я отправлю бит, тем медленнее он получит, и компьютер будет наблюдать40 бит только ) и не очень эффективны для связи.Поэтому я начал изучать битовые поля и попробовал следующее:

typedef struct {
    unsigned char length;   //!< Data Length
    unsigned data_type;     //!< Data type
    arrayData data[40]; //!< Data array 5 bytes == 40 bits
} SERIAL_packet;

typedef struct {
    unsigned char aux : 1;
} arrayData;

И мне интересно, будет ли это отображать data[40] в последующий блок памяти размером 40 бит (5 байт)??

Если нет, есть ли какое-то очевидное решение, которое я пропускаю?Это не кажется слишком сложной задачей (было бы намного проще, если бы было менее 32 устройств, поэтому я мог бы использовать int и просто получить доступ через битовую маску).

1 Ответ

0 голосов
/ 10 октября 2018

Предполагая, что возвращаемые адреса находятся в диапазоне 0–39 и что char имеет 8 битов, вы можете рассматривать ваш массив data как массив битов:

| data[0]                       | data[1]                           ...
-----------------------------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15|
-----------------------------------------------------------------

Toустановить бит i:

packet.data[i/8] |= (1 << (i%8));

Сбросить бит i:

packet.data[i/8] &= (1 << (i%8)) ^ 0xff;

Чтобы прочитать бит i:

 int flag = (packet.data[i/8] & (1 << (i%8)) != 0;
...