내용핵심
예를들어 GPIOB_BRR이 0x40010C14라고 하자.
여기서 GPIOB : 0x40010C00이며
BRR은 여기에 + 0x14를 더한것이다.
GPIOA : 0x40010800이며 GPIOA_BRR은 0x40010814이다.
이러한것을 #define을 이용하여 일일이 주소를 치던것을 간단하게 GPIOA_BRR, GPIOB_BRR 등으로 쳐서 표현하자는것
이 책에서 나오는 define은 대부분 STMicroelectronics의 Standard Peripheral Driver Library에 적용되어 있다.
여기에 연습하면서 적은 코드를 적어둔다
/////////////////////////////////////////////////////////////////////////////////////
platform_config.h
#define GPIOA_CRL (*(volatile unsigned *)0x40010800)
#define GPIOA_CRH (*(volatile unsigned *)0x40010804)
typedef enum{
GPIO_Mode_User_Out_PP=0x00,
GPIO_Mode_Use_Out_OD=0x01,
GPIO_Mode_Use_AF_PP=0x10,
GPIO_Mode_Use_AF_OD=0x11
}GPIOMode_Output_TypeDef;
void GPIO_A_Output_Init(uint16_t pinNum, GPIOSpeed_TypeDef speedValE, GPIOMode_Output_TypeDef modeE){
//modeE : CNF
//speedValE : MODE
//pinNum : 비트방식의 pinNum표시. 0x1(0b1), 0x2(0b10)... 16비트:16핀
//0xFFFF : 0b1111.1111.1111.1111.
//GPIOSpeed_TypeDef : stm32f10x_gpio.h에 정의
uint32_t tmpVal = modeE<<2 | speedValE; //CNF와 MODE 붙임
uint32_t pinpos = 0x00;
//pin #0~#7(GPIO_CRL)
if((pinNum & 0xFF)!=0){
//하위 8비트에 어떤 값이 존재
for(pinpos=0x00; pinpos<0x08; pinpos++){
if(pinNum==((uint32_t)0x01) << pinpos){
//pinpos : 원하는 설정을 저장할 위치(4비트 단위로 건너뜀)
pinpos = pinpos*4;
GPIOA_CRL &= ~(0xF << pinpos); //대상비트를 0으로 Set. 나머지는 그대로 살림(and)
GPIOA_CRL |= tmpVal << pinpos; //대상비트에 설정사항(tmpval)적용
break;
}
}
}
//pin #8~#15
else{
//8비트 오른쪽 shift시켜 CRH의 port bit configuration에 적용
pinNum = pinNum>>8;
for(pinpos = 0x00; pinpos < 0x08; pinpos++){
if(pinNum == ((uint32_t)0x01) << pinpos){
pinpos = pinpos*4;
GPIOA_CRH &= ~(0xF << pinpos);
GPIOA_CRH |= tmpVal << pinpos;
break;
}
}
}
}
책에 있는데 안적은 내용은, 위에서 언급한 Standard peripheral Driver Library에 있기때문
/////////////////////////////////////////////////////////////////////////////////////////////
Test_LED_Function_Used.c
#include <stm32f10x.h>
#include <platform_config.h>
static void delay_int_count(volatile unsigned int nTime)
{
for(; nTime > 0; nTime--);
}
void delay_1_second(void)
{
delay_int_count(806596);
}
//앞의 platforconfig.h와 비교
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void GPIOA_0_On(void){
GPIOA->BRR |= GPIO_Pin_0;
}
void GPIOA_1_On(void){
GPIOA->BRR |= GPIO_Pin_1;
}
void GPIOA_4_On(void){
GPIOA->BRR |= GPIO_Pin_4;
}
void GPIOA_0_Off(void){
GPIOA->BSRR |= GPIO_Pin_0;
}
void GPIOA_1_Off(void){
GPIOA->BSRR |= GPIO_Pin_1;
}
void GPIOA_4_Off(void){
GPIOA->BSRR |= GPIO_Pin_4;
}
void GPIOA_On_All(void){
GPIOA_0_On();
GPIOA_1_On();
GPIOA_4_On();
}
void GPIOA_Off_All(void){
GPIOA_0_Off();
GPIOA_1_Off();
GPIOA_4_Off();
}
void GPIOA_OnOffAll_Mult(uint32_t count){
for(;count>0;count--)
{
GPIOA_0_Off();
GPIOA_1_On();
GPIOA_4_On();
delay_1_second();
GPIOA_0_On();
GPIOA_1_Off();
GPIOA_4_On();
delay_1_second();
GPIOA_0_On();
GPIOA_1_On();
GPIOA_4_Off();
delay_1_second();
}
}
void GPIOA_Test(void){
#if 0
GPIOA_On_All();
delay_1_second();
GPIOA_Off_All();
delay_1_second();
#else
GPIOA_OnOffAll_Mult(10);
#endif
}
int main(void){
RCC->APB2ENR |= RCC_APB2Periph_GPIOA;
//GPIO_Speed_10MHz : output mode의 Open-drain
GPIO_A_Output_Init(GPIO_Pin_0,GPIO_Speed_10MHz,GPIO_Mode_User_Out_PP);
GPIO_A_Output_Init(GPIO_Pin_1,GPIO_Speed_10MHz,GPIO_Mode_User_Out_PP);
GPIO_A_Output_Init(GPIO_Pin_4,GPIO_Speed_10MHz,GPIO_Mode_User_Out_PP);
while(1){
GPIOA_Test();
}
}
GPIOA를 이용해서 LED테스트를 해보았다. 직접 읽고 내용을 이해할 수 있었으면 한다.
'중도연재종료 > CORTEX M3' 카테고리의 다른 글
GPIO_Init (0) | 2013.05.25 |
---|---|
Key가 눌린것 알아채기 (0) | 2013.05.24 |
LED 끄기[GPIO Set Reset 레지스터] (0) | 2013.05.24 |
LED회로도를 통한 기본적인 이해 (0) | 2013.05.22 |
Cortex M3 시작. 자료 (0) | 2013.05.22 |