내가 만약 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
이므로
2. 0x40011000 으로 가서
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 |