C - 如何从位字段接收一个位作为函数中的参数?

时间:2013-04-17 18:22:28

标签: c arduino microcontroller bit bit-fields

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

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 个答案:

答案 0 :(得分:3)

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

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

    这将是一个无操作。

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

    #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);

}