3

我有一个这样定义的位字段(它来自微控制器库,所以看起来有点不同):

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 的库之类的东西。任何人都知道如何以我喜欢的方式做到这一点?

4

4 回答 4

3
  1. C 是一种按值传递的语言,所以即使你可以这样做:

    void setbit(bit Bit) {
         Bit = 1;
    }
    

    这将是一个无操作。

  2. 您可以使用类似函数的宏来执行您正在尝试的操作:

    #define setbit(x) do { (x) = 1; } while(0)
    

    如果你用 调用这个宏PTAD_PTAD5,它应该像你期望的那样工作。

于 2013-04-17T18:28:34.140 回答
2

因为您可以单独访问位域中的位,所以设置位非常容易:

_PTAD_PTAD5 = 1;

多亏了#define _PTAD_PTAD5,这将评估为

_PTAD.Bits.PTAD5 = 1;

请注意,由于 C 是一种按值传递的语言,

void setBit(bit Bit){
    Bit = 1;
}

不要做你所期望的。相反,它将(函数)局部变量Bit设置为 1,而您发送给它的变量保持不变。

通常,您会使用指向要在函数中更改的变量的指针,但是由于您不能在位域中获取位的地址,因此在这种情况下您不能这样做。

于 2013-04-17T18:29:38.857 回答
0

在 C 中,我不相信可以将位域作为数组访问。一种想法是传入一个枚举类型或常量,并将其值转换为 8 个不同的集合函数。不是最干净的方法,但我相信它会起作用。


#define PTAD5  5
...

void setbit(PTADSTR byte, int bit)
{
    switch(bit)
    {
        ...
        case PTAD5  : byte.PTAD5 = 1; break;
        default: ASSERT_ALWAYS(); break;
    }
}
于 2013-04-17T18:27:34.320 回答
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);

}
于 2016-09-16T15:05:07.297 回答