C 选择结构的成员并对其进行修改的函数';内容

C 选择结构的成员并对其进行修改的函数';内容,c,C,因此,我试图编写一个函数,它接受指向结构的指针、结构的元素(表示寄存器)和表示要设置的寄存器位的int 我的想法是 SET_GPIO_BIT(GPIO_TypeDef *PORT, volatile uint32_t reg, uint32_t bit) { PORT->reg |= (1 << bit); } 但是我得到一个(arm none eabi gcc)编译器错误: error: 'GPIO_TypeDef {aka struct <anonymous

因此,我试图编写一个函数,它接受指向结构的指针、结构的元素(表示寄存器)和表示要设置的寄存器位的int

我的想法是

SET_GPIO_BIT(GPIO_TypeDef *PORT, volatile uint32_t reg, uint32_t bit) {
    PORT->reg |= (1 << bit);
}
但是我得到一个(arm none eabi gcc)编译器错误:

error: 'GPIO_TypeDef {aka struct <anonymous>}' has no member named 'reg'

它将选择GPIO端口A并设置BSRR寄存器中的第七位(例如)。有没有办法做到这一点?

因为你要找的是文本替换,所以你需要一个宏:

#define SET_GPIO_BIT(port, reg, bit) ((port)->reg |= (1 << (bit)))

由于您正在寻找的是文本替换,因此需要一个宏:

#define SET_GPIO_BIT(port, reg, bit) ((port)->reg |= (1 << (bit)))

这不是对所述问题的回答;这是一个以不同方式解决根本问题的建议

与其将“寄存器”作为结构中单独命名的成员,不如使用数组:

enum {
    IOREG_MODE = 0,
    IOREG_OTYPE,
    /* All registers, in order */
    IOREG_COUNT
};

typedef struct {
    volatile uint32_t  ioreg[IOREG_COUNT];
} ioregs;
这允许您使用宏

#define IOREG_SET(port, reg, bit) (((port)->ioreg[reg]) |= (1u << (bit)))
#define IOREG_UNSET(port, reg, bit) (((port)->ioreg[reg]) &= ~(1u << (bit)))
#define IOREG_TOGGLE(port, reg, bit) (((port)->ioreg[reg]) ^= (1u << (bit)))

#define IOREG_SET(port,reg,bit)(((port)->IOREG[reg])|=(1u IOREG[reg])&=(1u IOREG[reg])^=(1u IOREG[reg]|=1u IOREG[reg]&=(1u IOREG[reg]^=1u这不是对所述问题的回答;而是以不同方式解决根本问题的建议

与其将“寄存器”作为结构中单独命名的成员,不如使用数组:

enum {
    IOREG_MODE = 0,
    IOREG_OTYPE,
    /* All registers, in order */
    IOREG_COUNT
};

typedef struct {
    volatile uint32_t  ioreg[IOREG_COUNT];
} ioregs;
这允许您使用宏

#define IOREG_SET(port, reg, bit) (((port)->ioreg[reg]) |= (1u << (bit)))
#define IOREG_UNSET(port, reg, bit) (((port)->ioreg[reg]) &= ~(1u << (bit)))
#define IOREG_TOGGLE(port, reg, bit) (((port)->ioreg[reg]) ^= (1u << (bit)))

#define IOREG_SET(port,reg,bit)(((port)->IOREG[reg])|=(1u IOREG[reg])和=~(1u IOREG[reg])^=(1u IOREG[reg]|=1u IOREG[reg]&=(1u IOREG[reg]^=1u不是
寄存器
C中的关键字?除此之外,看起来您要做的是将结构成员的名称传递给函数,对吗?是的,我把它命名为“reg”在我的原始程序中,但我将其更改为“注册”为了让它更清晰,我将对其进行编辑。是的,这是正确的,但需要注意的是,该函数可以更改结构成员的值。旁注:您不使用BSRR的原因是什么?您的代码既不是线程安全的,也不是中断安全的。更多信息,请参阅RTF(ine)M和一本初级C语言书,与嵌入式无关,但与C语言基础有关。
register
不是C语言中的一个关键字吗?除此之外,看起来您要问的是如何将结构成员的名称传递给函数,对吗?是的,我在原始程序中将其作为“reg”,但我将其更改为“register”为了让它更清晰,我将对其进行编辑。是的,这是正确的,但需要注意的是,该函数可以更改结构成员的值。旁注:您不使用BSRR的原因是什么?您的代码既不是线程安全的,也不是中断安全的。更多信息,请参阅RTF(ine)M和一本C入门书,与嵌入式无关,但与C语言基础有关。@EmbeddedDeveloper在这种情况下是的,尽管最好尽可能避免这些类型的转换。请参阅我的更新,以获取一个不使用宏的示例。@NominalAnimal在本例中
reg
不应使用括号,因为它是字段并将导致语法错误。虽然我发布了不同的“答案”,但在我看来,这个答案非常完美地回答了所述问题。(我的答案只是建议对基本任务采用不同的方法,一种根本不存在OP所述问题的方法。)@EmbeddedDeveloper在这种情况下是的,不过如果可能的话最好避免这些类型的转换。请参阅我的更新以获取一个不使用宏的示例。@NominalAnimal在这种情况下
reg
不应该有括号,因为它是一个字段的名称,如果有,将导致语法错误。尽管我发布了不同的“答案”,在我看来,这个答案非常完美地回答了所述问题。(我的答案只是建议对基本任务采用不同的方法,一种根本不存在OP所述问题的方法。)
#define IOREG_SET(port, reg, bit) (((port)->ioreg[reg]) |= (1u << (bit)))
#define IOREG_UNSET(port, reg, bit) (((port)->ioreg[reg]) &= ~(1u << (bit)))
#define IOREG_TOGGLE(port, reg, bit) (((port)->ioreg[reg]) ^= (1u << (bit)))
static inline uint32_t ioreg_set(regs *const port,
                                 const int reg,
                                 const unsigned char bit)
{
    return port->ioreg[reg] |= 1u << bit;
}

static inline uint32_t ioreg_unset(regs *const port,
                                   const int reg,
                                   const unsigned char bit)
{
    return port->ioreg[reg] &= ~(1u << bit);
}

static inline uint32_t ioreg_toggle(regs *const port,
                                    const int reg,
                                    const unsigned char bit)
{
    return port->ioreg[reg] ^= 1u << bit;
}