2017-01-28 54 views
0

我有如下代码:Ç联盟,结构内部阵列的填充

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; 

那么我可以用这个定义是这样的:

GPIOA->MODER_REG.bit.MODER0=0x2; 

是否有一些方法来使用struct MODER_REG内的数组?要使用的GPIO这样的:

GPIOA->MODER_REG.bit.MODER[0]=0x2; 

应该如何看起来像

struct MODER_BITS{ 
__IO uint32_t MODER[?]:? //options  
} 

PS的定义: __IO只是一种挥发性

请咨询宏。

+0

注意,对于头标遵循CMSIS标准,您不需要知道每个字段的起始位置,因为头文件为每个位提供单独的定义。因此,如果您需要设置MODER9字段的位,将会有一个像GPIO_MODER_MODER9_0和GPIO_MODER_MODER9_1这样的定义。所有寄存器均遵循此标准。此外,新版本的头文件提供'... Pos'宏的字段位置 - 例如STM32F0头文件中的'GPIO_MODER_MODER9_Pos'。 –

+0

是的,我注意到在stm32f411xe.h里面有这个BITS的定义,但我更喜欢这个新版本的宏:GPIO_MODER_MODER9_Pos。我不知道这个新版本。谢谢 !您对C++模板和std:bitset的解决方案有何看法? –

+0

太多的工作得不到太多的收益 - 在我看来(我认为在C++中,你应该在最低级别使用te寄存器,并且使用一些更高级别的接口,通过这种方法,大多数外设的驱动程序非常短无论如何,以及是否使用'GPIOA-> MODER_REG.bit.MODER [0] = 0x2;''或'gpioSetModer(GPIOA,0,0x02);'只不过是一种格式差异(再次 - 在我看来) –

回答

3

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

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

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

第一部分复位在位置0的位,第二部分套再到值2

+0

好吧,这意味着没有什么灵敏的使用这样的,因为原来是这样的:__IO uint32_t MODER;我只是想避免检查参考手册中位的起始位置 –

+0

@MateuszTocha - 宏或函数访问位是就像一个有名的成员一样清晰。 – StoryTeller

+0

C++怎么样? –