Булево массив и побитовая операция в C - PullRequest
1 голос
/ 09 апреля 2019

Я должен реализовать набор последовательных сдвиговых регистров с каждыми 8 выходами.Выходы подключены к переключателям, поэтому в настоящее время я использую логические массивы в C, которые либо включают переключатель (true), либо выключают (false).

Таким образом, каждый сдвиговый регистр имеет массив из 8 логических значений, который на самом деле представляет собой 8-битовое целое число без знака.Я мог бы продолжать работать с массивами, но я предполагаю, что это намного медленнее, чем просто побитовая манипуляция с целым числом.Также передача целого числа в интерфейс SPI намного проще, чем для массива.

Есть ли простой способ преобразовать логические массивы в целые числа или манипулировать целыми числами так же, как я мог бы манипулировать массивом?

Т.е.:

bool switch[8];
switch[0] = True; //Switch 1 on
switch[1] = False; //Switch 2 off
...

- это то же самое, что и

uint8_t switch;
switch = 0b00000001;

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

Производительностьявляется ключевым, так как мой SPI должен быть очень быстрым.

Ответы [ 5 ]

2 голосов
/ 09 апреля 2019

Используйте uint8_t для хранения 8-битных данных, связанных с оборудованием, точка. Если это аппаратный регистр с отображением в памяти, он также должен быть квалифицирован volatile.

Если вы хотите назвать отдельные выводы, вы можете сделать это с помощью определений:

#define SWITCH3 (1u << 3);

Доступ с побитовыми операторами.

uint8_t switch = 0;
switch = SWITCH1 | SWITCH3;   // set all bits
switch |= SWITCH3;            // set a specific bit
switch &= (uint8_t)~SWITCH3;  // clear a specific bit
2 голосов
/ 09 апреля 2019

Вы не можете использовать синтаксис массива (для этого потребуется перегрузка операторов, что возможно в C ++). Но вы можете использовать некоторую вспомогательную функцию для установки и получения бита (/ 8 и% 8 оптимизированы для битовых сдвигов и ands, обратите внимание, что это не то же самое, что int для типа для индекса)

typedef uint8_t bit_mem_t;

static inline void set_bit(bit_mem_t* array, unsigned index, bool value) {
    array[index/8] = (array[index/8] | 1 << (index%8)) ^ !value << (index%8);
}

static inline bool get_bit(bit_mem_t const* array, unsigned index) {
    return (array[index/8] & 1 << (index%8)) != 0;
}

static inline void flip_bit(bit_mem_t* array, unsigned index) {
    array[index/8] ^= 1 << (index%8);
}

/*static inline size_t bit_array_size(size_t bit_count) {
    return (bit_count+7) / 8;
}*/
#define bit_array_size(bit_count) (((size_t)(count)+7)/8)

int main() {
    bit_mem_t array[bit_array_size(3)] {}; // clear it to 0s

    set_bit(array, 0, true);
    set_bit(array, 1, false);
    set_bit(array, 2, !get_bit(array, 1));
}
1 голос
/ 09 апреля 2019
#define SWITCH1 1U
#define SWITCH2 2U
#define SWITCH3 4U
#define SWITCH4 8U
#define SWITCH5 16U
#define SWITCH6 32U
#define SWITCH7 64U
#define SWITCH8 128U


unsigned int switches = 0x0U;

Чтобы включить переключатель, скажем, говорит переключатель 4

switches = (switches | SWITCH4)

Чтобы отключить переключатель, пусть говорит переключатель 4

switches = (switches & ~SWITCH4)
1 голос
/ 09 апреля 2019

Используйте макросы:

uint8_t sw;
#define SW_ON(s)    sw=(sw|(1u<<(s)))
#define SW_OFF(s)   sw=(sw&(~(1u<<(s))))

и используйте как:

SW_OFF(3);
SW_ON(2);
0 голосов
/ 09 апреля 2019

Вы можете использовать битовое поле следующим образом:

union {
     struct {
          unsigned char s1:1,
                        s2:1,
                        s3:1,
                        s4:1,
                        s5:1,
                        s6:1,
                        s7:1,
                        s8:1
     } sw;
    unsigned char nr[1];
} u;

Вы можете получить доступ к полям индивидуально (u.sw.s1 - u.sw.s8) для коммутаторов, но также получить доступ ко всему номеру в u.nr [0].

Также может быть возможно использовать unsigned char nr вместо массива с 1 членом, но стандарт объявляет его действительным только для char массивов , так что лучше не рисковать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...