버스와 주변장치: AHB, APB, 메모리 맵 I/O
CPU가 GPIO를 움직이는 방법은 메모리에 값을 쓰는 것과 같습니다. 주변장치를 잇는 버스 구조와 클럭 활성화가 필요한 이유.
메모리 맵 I/O
ARM에는 I/O 전용 명령어가 없습니다. 주변장치 레지스터가 메모리 주소에 배치되어 있어서, 일반 메모리 쓰기 명령(STR)으로 GPIO 핀을 바꾸고 읽기 명령(LDR)으로 UART 수신 데이터를 가져옵니다.
버스 계층
| 버스 | 속도 | 연결 대상 |
|---|---|---|
| AHB | 빠름 | Flash, SRAM, DMA, GPIO(일부 칩) |
| APB1 | 느림 | UART2, I2C, 일반 타이머 |
| APB2 | 중간 | UART1, SPI1, ADC, 고급 타이머 |
APB는 AHB에서 브리지를 거쳐 나뉘고, 각각 다른 클럭 분주를 씁니다. 그래서 같은 타이머라도 APB1에 붙었는지 APB2에 붙었는지에 따라 입력 클럭이 다릅니다.
클럭 활성화
전력을 아끼기 위해 대부분의 주변장치는 리셋 후 클럭이 꺼져 있습니다. 레지스터를 쓰기 전에 RCC에서 해당 주변장치의 클럭을 켜야 합니다.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // 이 줄이 없으면 GPIOA 설정이 먹지 않음
"코드는 맞는데 핀이 안 움직인다"는 문제의 상당수가 이 한 줄을 빠뜨린 것입니다.