2017-01-28 6 views
0

나는 아래와 같은 코드가 있습니다C 연합 (EU), 구조체 내부 배열 패딩

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; 

구조체 MODER_REG 내부에서 배열을 사용할 수 있습니까? 이 같은 GPIO를 사용하려면 다음을 수행해야이

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

PS의 정의처럼 보이는 방법

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

: __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

좋아요, orginally하기 때문에 이런 식으로 사용할 감각이 없다는 것을 의미합니다 : __IO uint32_t MODER; 그냥 참조 설명서에서 비트가 시작된 곳에서 확인하지 않으려는 경우 –

+0

@MateuszTocha - 매크로 또는 함수가 비트에 액세스하는 것입니다 명명 된 멤버만큼이나 분명합니다. – StoryTeller

+0

C++은 무엇입니까? –