C并集,结构内数组的填充

C并集,结构内数组的填充,c,struct,stm32,unions,C,Struct,Stm32,Unions,我的代码如下: struct MODER_BITS { __IO uint32_t MODER0:2; __IO uint32_t MODER1:2; __IO uint32_t MODER2:2; __IO uint32_t MODER3:2; __IO uint32_t MODER4:2; __IO uint32_t MODER5:2; __IO uint32_t MODER6:2; __IO uint32_t MODER7:2

我的代码如下:

  struct MODER_BITS
{   __IO uint32_t MODER0:2;
    __IO uint32_t MODER1:2;
    __IO uint32_t MODER2:2;
    __IO uint32_t MODER3:2;
    __IO uint32_t MODER4:2;
    __IO uint32_t MODER5:2;
    __IO uint32_t MODER6:2;
    __IO uint32_t MODER7:2;
    __IO uint32_t MODER8:2;
    __IO uint32_t MODER9:2;
    __IO uint32_t MODER10:2;
    __IO uint32_t MODER11:2;
    __IO uint32_t MODER12:2;
    __IO uint32_t MODER13:2;
    __IO uint32_t MODER14:2;
    __IO uint32_t MODER15:2;
};

typedef union {
    __IO uint32_t all;
    struct MODER_BITS bit;
}MODER_REG;
然后我就可以使用GPIO结构了

typedef struct
{
  MODER_REG MODER_REG;
  //__IO uint32_t MODER    ;/*!< GPIO port mode register,                  
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,            */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,          */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,     */
  __IO uint32_t IDR;      /*!< GPIO port input data register,            */
  __IO uint32_t ODR;      /*!< GPIO port output data register,           */
  __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,          */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register,     */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     */
} GPIO_TypeDef;
是否有某种方法可以在struct MODER_REG.中使用数组?要像这样使用GPIO:

GPIOA->MODER_REG.bit.MODER0=0x2;
GPIOA->MODER_REG.bit.MODER[0]=0x2;
应该如何定义

struct MODER_BITS{
 __IO uint32_t MODER[?]:? //options     
}
附言: __IO只是一个易失性宏


请指教。

没有办法。C不允许位数组

但是,您仍然可以使用位掩码访问原始字:

GPIOA->MODER_REG.all = (GPIOA->MODER_REG.all)&(~3<<0)|(2<<0);

GPIOA->MODER_REG.all=(GPIOA->MODER_REG.all)&(~3没有办法。C不允许位数组

但是,您仍然可以使用位掩码访问原始字:

GPIOA->MODER_REG.all = (GPIOA->MODER_REG.all)&(~3<<0)|(2<<0);

GPIOA->MODER\u REG.all=(GPIOA->MODER\u REG.all)&(~3Ok,这意味着这样使用没有意义,因为最初是:u IO uint32_t MODER;我只是想避免检查引用中位的起始位置manual@MateuszTocha一个宏或一个函数是访问比特,就像命名成员一样清晰。C++ + @ MateuszTocha怎么样?它有一个好消息。ns这样使用是没有意义的,因为最初是:_IO uint32_t MODER;我只是想避免检查引用中位的起始位置manual@MateuszTocha一个宏或一个函数是访问比特,它和命名成员一样清晰。C++ +?@ MateuszTocha——它是什么?它有一个注释,用于头文件。遵循CMSIS标准,您不需要知道每个字段的起始位置,因为标头为每个位提供单独的定义。因此,如果您需要设置MODER9字段的位,将有一个定义,如
GPIO\u MODER\u MODER9\u 0
GPIO\u MODER\u MODER9\u 1
。所有寄存器都遵循此标准。此外,新版本的f标题为
..\u Pos
宏提供字段的位位置-例如STM32F0标题中的
GPIO\u MODER\u MODER9\u Pos
。是的,我注意到stm32f411xe.h中有此位的定义,但我更喜欢此新版本的宏:GPIO\u MODER\u MODER9\u Pos。我不知道这个新版本。谢谢!你用C++模板和STD:比特集来考虑这个解决方案?我认为太多的工作太少了。(我认为C++中只需使用最低级别的TE寄存器,使用高级接口就可以了。用这种方法,大多数外设的驱动程序都是很短的,不管你使用的是<代码> GPIOA->AuthyRe.Big.Mald[0 ]=0x2;< /Calp>或<代码> GPIOSETMODER(GPIOA,0,0x02)。
不过是格式上的差异(同样——在我看来)。请注意,对于遵循CMSIS标准的标头,您不需要知道每个字段的起始位置,因为标头为每个位提供了单独的定义。因此,如果您需要设置MODER9字段的位,将有一个定义,如
GPIO\u MODER\u MODER9\u 0
GPIO\u MODER9\u 1
。所有寄存器都遵循此标准s、 此外,标题的新版本提供了带有字段位位置的
..\u Pos
宏,例如STM32F0标题中的
GPIO\u MODER\u MODER9\u Pos
。是的,我注意到在stm32f411xe.h中有这个位的定义,但我更喜欢这个带有:GPIO\u MODER\u MODER9\u Pos的新版本的宏。我不知道这个新版本。谢谢。你用C++模板和STD:比特集来考虑这个解决方案?在我看来,太多的工作太少了。(我认为C++中只需使用最低级别的TE寄存器,使用高级接口就可以了。用这种方法,大多数外设的驱动程序都是很短的,不管你使用的是<代码> GPIOA->AuthyRe.Big.Mald[0 ]=0x2;< /Calp>或<代码> GPIOSETMODER(GPIOA,0,0x02)。
不过是格式上的差异(同样——在我看来)。