我有一个像这样定义的字段(它来自一个微控制器库,所以它看起来有点不同):
typedef union {
byte Byte;
struct {
byte PTAD0 :1;
byte PTAD1 :1;
byte PTAD2 :1;
byte PTAD3 :1;
byte PTAD4 :1;
byte PTAD5 :1;
byte :1;
byte :1;
} Bits;
} PTADSTR;
extern volatile PTADSTR _PTAD @0x00000000;
#define PTAD _PTAD.Byte
#define PTAD_PTAD0 _PTAD.Bits.PTAD0
#define PTAD_PTAD1 _PTAD.Bits.PTAD1
#define PTAD_PTAD2 _PTAD.Bits.PTAD2
#define PTAD_PTAD3 _PTAD.Bits.PTAD3
#define PTAD_PTAD4 _PTAD.Bits.PTAD4
#define PTAD_PTAD5 _PTAD.Bits.PTAD5
因此。让我们说我想要一个设置一点的功能,如:
void setbit(bit Bit) {
Bit = 1;
}
当然,“位”声明不起作用。我想宣布我可以使用
setbit(PTAD_PTAD5)
它会设置这个位。我能做到
void setbit(byte Byte, byte number) {
Byte |= 1<<(number);
}
并发送
setbit(PTAD,5);
这完美无缺,但是......这不是我想要的,因为我想做像Arduino的库那样的事情。任何人都知道如何以我喜欢的方式做到这一点?
答案 0 :(得分:3)
C是一种按值传递的语言,所以即使你可以这样做:
void setbit(bit Bit) {
Bit = 1;
}
这将是一个无操作。
您可以使用类似函数的宏执行您正在尝试的操作:
#define setbit(x) do { (x) = 1; } while(0)
如果您使用PTAD_PTAD5
调用此宏,它应该可以像您期望的那样工作。
答案 1 :(得分:2)
因为您可以单独访问位域中的位,所以设置位非常容易:
_PTAD_PTAD5 = 1;
,由于#define _PTAD_PTAD5
,评估为
_PTAD.Bits.PTAD5 = 1;
请注意,由于C是按值传递的语言,
void setBit(bit Bit){
Bit = 1;
}
不要做你期望的事。相反,它将(函数 - )局部变量Bit
设置为1,使您发送给它的变量保持不变。
通常你会使用指向你想在函数中改变的变量的指针,但是因为你不能在位域中取一个位的地址,所以在这种情况下你不能这样做。
答案 2 :(得分:0)
在C中,我不相信可以将位域作为数组访问。一种想法是传入枚举类型或常量,并将其值切换为8个不同的集合函数。不是最干净的方式,但我相信它会起作用。
#define PTAD5 5
...
void setbit(PTADSTR byte, int bit)
{
switch(bit)
{
...
case PTAD5 : byte.PTAD5 = 1; break;
default: ASSERT_ALWAYS(); break;
}
}
答案 3 :(得分:0)
这个怎么样? 使用static const限定符应该确保内存开销大约为零
typedef struct
{
uint8_t* reg;
uint8_t bitnum;
}bit;
void setbit(bit b)
{
*b.reg |= (1 << b.bitnum);
}
void clrbit(bit b)
{
*b.reg &= ~(1 << b.bitnum);
}
static const bit PTAD_PTAD0 = {&PTAD, 0};
static const bit PTAD_PTAD1 = {&PTAD, 1};
static const bit PTAD_PTAD2 = {&PTAD, 2};
static const bit PTAD_PTAD3 = {&PTAD, 3};
static const bit PTAD_PTAD4 = {&PTAD, 4};
static const bit PTAD_PTAD5 = {&PTAD, 5};
static const bit PTAD_PTAD6 = {&PTAD, 6};
static const bit PTAD_PTAD7 = {&PTAD, 7};
int main()
{
printf("PTAD: %02X\n", PTAD);
setbit(PTAD_PTAD0);
printf("PTAD: %02X\n", PTAD);
clrbit(PTAD_PTAD0);
printf("PTAD: %02X\n", PTAD);
}