【发布时间】:2023-04-01 10:59:01
【问题描述】:
我目前正在为 PIC 微控制器编写代码,我想使用 uint8_t 作为部分代码的“状态计数器”来构建我的一些代码。这涉及大量的按位运算。我想做的是为这个uint8_t 创建一个结构,类似于标题中的 SFR 位结构,我在下面包含了一个来自头文件的示例。
头文件允许使用类似于访问结构中元素的符号访问 SFR 中的位,例如 U1STAbits.UTXBF 和 uint16_t 这是我想在我的代码中实现的请允许我使用 switch 语句作为我的代码的主要结构。
#define U1STA U1STA
extern volatile unsigned int U1STA __attribute__((__sfr__));
__extension__ typedef struct tagU1STABITS {
union {
struct {
unsigned URXDA:1;
unsigned OERR:1;
unsigned FERR:1;
unsigned PERR:1;
unsigned RIDLE:1;
unsigned ADDEN:1;
unsigned URXISEL:2;
unsigned TRMT:1;
unsigned UTXBF:1;
unsigned UTXEN:1;
unsigned UTXBRK:1;
unsigned :1;
unsigned UTXISEL0:1;
unsigned UTXINV:1;
unsigned UTXISEL1:1;
};
struct {
unsigned :6;
unsigned URXISEL0:1;
unsigned URXISEL1:1;
};
};
} U1STABITS;
extern volatile U1STABITS U1STAbits __attribute__((__sfr__));
更新: 我基于此提出了一个潜在的解决方案:
typedef struct {
union {
struct{
unsigned breakDetected :1;
unsigned overrunError :1;
unsigned framingError :1;
unsigned startDetected :1;
unsigned dmxMode :1;
unsigned rdmMode :1;
};
uint8_t UartFlags;
};
} UartFlagsBits;
UartFlagsBits uartFlags;
【问题讨论】:
-
这称为位域。你的问题是什么?
-
几乎所有现代 CPU 上最小的可寻址单元是字节。像您显示的那样的位字段由编译器处理,生成获取或设置各个位所需的代码。
-
那么,如果我以类似的方式声明我的位域,我是否也可以将其作为 uint8_t 访问?
-
如果您将解决方案与工会一起使用,那么可以。
-
@RobbG 至少您应该至少使用相同类型的位作为标志变量(
uint8_t而不是unsigned)。但即便如此,C 标准也允许编译器在位域中添加填充并更改类型或顺序。一般来说,位字段对于您要执行的操作来说是一团糟。我会使用普通的uint8_t并使用位掩码运算符~&|^来修改位以100% 控制。
标签: c struct bit-fields