C中的布尔数组和按位运算

问题描述 投票:1回答:5

我必须为每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需要非常快。

c arrays
5个回答
2
投票

您不能使用数组语法(这将需要运算符重载,这可以使用C ++)。但是你可以使用一些辅助函数来设置和得到一点(/ 8和%8被优化为位移和和,注意这与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));
}

2
投票

使用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

1
投票
#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
投票

使用宏:

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
投票

您可以使用这样的位域:

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数组有效,所以最好安全地使用它。

© www.soinside.com 2019 - 2024. All rights reserved.