임베디드/고추건조기

GPIO 탐구

러비코스믹 2025. 5. 2. 00:30

내가 만약 PC13의 위치에서 GPIO 목적으로 쓰고 싶다면.. // 입출력 신호 전달 목적

Push-pull / Pull-Up -> High(1) / High speed 

 

 

 

HAL_GPIO_WritePin(Test13_GPIO_Port, Test13_Pin, GPIO_PIN_SET);

// Port 의 PIN13 활성화

 > GPIOx->BSRR = GPIO_Pin; 

   >  Set the corresponding ODRx bit 

      >> atomic 으로 동작 // 인터럽트 보호

           + Regi 바로 변경 > 빠름 

       <> 하나만 가능

 

<> GPIOx_ODR :  read and written by software and can be accessed in Word mode only.

      >  read and written 연산 // Word 단위 : 2byte

GPIOC->ODR |= ((1 << 13) | (1 << 14) | (1 << 15));  // PC13, PC14, PC15 HIGH
1. GPIOC->ODR 값 읽기
2. ((1 << 13) | (1 << 14) | (1 << 15) OR 연산
3. 결과를 다시 GPIOC->ODR에 씀

    

   >  여러개 한번에 가능

   <> 느림 

 

GPIO_InitStruct.Pin = Test13_Pin;                                  // 8192

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  //  1

GPIO_InitStruct.Pull = GPIO_PULLUP;                          // 2  

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 3

 

HAL_GPIO_Init(Test13_GPIO_Port, &GPIO_InitStruct);

>
HAL_GPIO_Init(GPIO_LED_GPIO_Port, &GPIO_InitStruct);
    GPIO_LED_GPIO_Port : 0x40011000 = GPIOC
    &GPIO_InitStruct : 0x20004fe0

 

config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;   //General purpose output push-pull 
  > config = 3 + 0 == 3

 

// iocurrent, position  : 13번 pin 확인

configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL    : &GPIOx->CRH;
  :  13 > 8
     > &GPIOx->CRH ( control register High) : 0x40011004
       > configregister  = 0x40011004;

registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2u) : ((position - 8u) << 2u);
  :13 > 8 

   > (position - 8u) << 2u : 
    13-8 ==5
    0101 <<2
    010100  == 20
       > registeroffset = 20;

 

MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), (config << registeroffset));

>
#define MODIFY_REG(REG, CLEARMASK, SETMASK) 
                     WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))

>
#define WRITE_REG(REG, VAL)   ((REG) = (VAL))
#define READ_REG(REG)         ((REG))

 

REG = *configregister == *(0x40011004)

 

// CLEAR MASK : 1 -> 0 으로 바꿀때

     >원하는 부분에1을 쓰고  '~' : not 을 하면 0 -> & 연산 하면 0이됨
//  SET MASK     : 0 -> 1 로 바꿀때

CLEARMASK = (GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset
   > 3 | 0x3 <<2 // 001100 == 12
      : 15 << 20

      > 1111 0000 0000 0000 0000 0000

         " ~ "

      >1111 1111 0000 1111 1111 1111 1111 1111

       // bit[23:20] 을 0으로 clear

       // 나머진 그대로

 

SETMASK= config << registeroffset 

  : 3 << 20 

   > 0011 0000 0000 0000 0000 0000

   // bit[21:20] 을 1 로 set


VAL = (READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))

==  (*(0x40011004) & ~(15 << 20 ) | ( 3 << 20 )

  > Regi 의 주소에 가서 

   bit[23:20] 을 0 으로 초기화 하고

   bit[21:20] 을 1로 set 해라

WRITE_REG(REG, VAL)   REG = VAL 

// Reset Value *(0x40011004) =0x4444 4444
>>>>>>>

  *(0x40011004) =  0100 0100 0011 0100 0100 0100 0100 0100

 

 


데이터시트 + 레퍼런스 메뉴얼로 어떤 뜻인지 확인

 

1. 내가 만약 PC13의 위치에서 GPIO 목적으로 쓰고 싶다면.. // 입출력 신호 전달 목적

 

PC13 

== Port C 13 

이므로

 

Register Memory Map

2. 0x40011000 으로 가서

 

 

한 Port 안의 pin들 // 나머지 공간은 Reserved

 

 

 

 

 

3. PIN 보다 크므로 CRH 로 간다. 0x40011004 //Address offset : 0x04

4. bit[23:20] 이 PIN 13에 관한내용 // PIN0 ~

>

다른 장치에 신호를 쏠거고(Output) Push-pull 로  H/L 를 묶어놔야지

그리고 High -> Low 전환 시간을 빠르게 해야지

>> bit[23:20] : 0011 //  mode[1:0] > 00 이면 OutPut mode

 

>>>>> 초기값 Reset value: 0x4444 4444

*(0x40011004) |= 0100 0100 0011 0100 0100 0100 0100 0100  

 

 

총정리

GPIO_CRL_MODE0 | GPIO_CRL_CNF0 

  > 이게 내가 설정할값 

   > 레지스터에가서 MASK 씌움

'임베디드 > 고추건조기' 카테고리의 다른 글

USART, UART  (0) 2025.05.06
데이터시트 해석  (1) 2025.05.03
HAL_Init();  (1) 2025.04.29
고추건조기 with Thread (FreeRTOS)  (0) 2025.01.28
드디어 완성..  (1) 2024.12.31