임베디드/고추건조기

GPIO 탐구

twoweeks-within 2024. 11. 21. 02:51

 GPIO_InitStruct.Pin = GPIO_LED_Pin;
     GPIO_LED_Pin = 8192 // PC13 1<<13
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_MODE_OUTPUT_PP =1 
GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_PULLUP = 2
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_SPEED_FREQ_HIGH = 3 = 0x3

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

uint32_t position = 0x00u;
while (((GPIO_Init->Pin) >> position) != 0x00u){
position++;
// while 문의 조건은 값 저장x
//
10000000000000 8192!= 0
01000000000000 4096!= 0
00100000000000
....
00000000000001
00000000000000 // 이때 멈춤
//
ioposition = (0x01uL << position);
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
 if (iocurrent == ioposition)
// ioposition 이 8192 즉 13번핀 일때 if문으로 들어감 // position= 13일때
   (비트and 연산 둘다 같아야 1) > 몇번째 핀인지 확인용
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;   //General purpose output push-pull 
config = 3 + 0 == 3


configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL    : &GPIOx->CRH;
 > 8번핀보다 작냐? : x 
     > &GPIOx->CRH ( control register High) : 0x40011004
     > configregister  = 0x40011004;

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

#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)

CLEARMASK = (GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset
                      3 | 0x3 <<2 (1100 == 12)
                  = 15 << 20
VAL = (READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))
// not 을 한뒤 and 연산하면 그부분만 0 으로 바뀜 >> CLEAR MASK
// or 연산 하면 그부분 1 로 바뀜 >> SET MASK

SETMASK= config << registeroffset  // 3 << 20 
(READ_REG(REG)) & (~(CLEARMASK))) = *(0x40011004) & ( 15 << 20 ) 

>>
 VAL = (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
=  (*(0x40011004) & ~(15 << 20 ) | ( 3 << 20 )

VAL =   ( 100 0100 0100 0100 0100 0100 0100 0100 & 
                       ~(1111 0000 0000 0000 0000 0000)) | ( 11 0000 0000 0000 0000 0000 )
       =     100 0100 0000 0100 0100 0100 0100 0100 | 11 0000 0000 0000 0000 0000
       =     100 0100 0011 0100 0100 0100 0100 0100
       =     1,144,276,036
// ~(1111 0000 0000 0000 0000 0000) == 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 1111 1111 1111 1111 1111
    >> int형이라 원래 앞에 0 이였던 부분도 다 1로 바뀜,총 8바이트
        >> 결국은 20~23 비트를 0으로 만들기 위함 

WRITE_REG(REG, VAL)   REG = VAL 
       *(0x40011004) = 1144276036

레퍼런스 메뉴얼
p171, Table59. GPIO register map and reset values 

CNF7 까지가 GPIOx_CRL
7~CNF15 까지가 GPIOx_CRH
 > configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL  : &GPIOx->CRH;
     > 이거를 했던이유

GPIO_SPEED_FREQ_HIGH = 3 = 0x3
// 3 ( 11(2) ) : Output mode, max speed 50 MHz.

GPIO_CR_CNF_GP_OUTPUT_PP;
// 0 : General purpose output push-pull 


탐구 순서
1. GPIO 가 뭐지? 어떻게 사용하는지, 어디에 응용하는지
2. 이 칩에서는 어떻게 제어 하는 거지?
3. 결국 어떻게 소스로 작성하지?


소스를 통해서 동작을 보고 역으로 추척 하는 방식이 good

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

데이터 시트 보는법  (1) 2024.11.23
GPIO 마무리, 회로도 보기  (0) 2024.11.21
GPIO제어  (0) 2024.11.19
ACR 레퍼런스 메뉴얼  (1) 2024.11.16
HAL_Init();  (1) 2024.11.16