낮은 주파수의 기준 클럭에서 높은 주파수를 만들어 내는 회로 (Phase-Locked Loop, 위상 고정 루프).
왜 필요한가
외부 크리스털은 보통 8MHz, 12MHz, 25MHz CPU는 168MHz, 480MHz 로 돌리고 싶다
- 고주파 크리스털을 쓰면 되지 않나?
- 비싸고, 안정성이 떨어지고, EMI가 커지고, 기판 설계가 어려워진다
저주파 크리스털은 정확하고 싸다. 그것을 기준으로 칩 안에서 곱하는 것이 훨씬 유리하다.
동작 원리
- VCO가 어떤 주파수를 만든다
- 그것을 N으로 나눈 값과 기준 클럭을 위상 비교한다
- 차이가 있으면 VCO의 제어 전압을 조정한다
- 위상이 일치하면(locked) 안정된다
결과적으로 출력 = 기준 × N / M / P 가 된다. "위상을 맞춘다(phase-locked)"는 이름 그대로다.
STM32 예시
- HSE = 8MHz 크리스털
PLLM = 8 → 8MHz / 8 = 1MHz (VCO 입력. 1~2MHz 권장)
PLLN = 336 → 1MHz × 336 = 336MHz (VCO 출력. 범위 제한 있음)
PLLP = 2 → 336 / 2 = 168MHz ← SYSCLK
PLLQ = 7 → 336 / 7 = 48MHz ← USB 는 정확히 48MHz 필요
PLLQ가 USB용으로 따로 있는 이유 — USB는 48MHz가 정확해야 동작한다. 시스템 클럭과 별개로 뽑아야 하므로 출력 분주기가 여러 개다.
설정 시 지켜야 할 제약
- ① VCO 입력 주파수 범위 — (예: 1~2MHz) — 벗어나면 지터가 커진다
- ② VCO 출력 주파수 범위 — (예: 100~432MHz)
- ③ 각 버스의 최대 주파수 (AHB 168, APB1 42, APB2 84)
- ④ 플래시 웨이트 스테이트 — 클럭에 맞춰 먼저 설정 — ★
★ ④를 빠뜨리면 클럭 전환 순간 HardFault가 난다. 플래시가 CPU를 따라오지 못해 명령어를 잘못 읽기 때문이다.
올바른 순서 클럭을 올릴 때: 웨이트 증가 → PLL 설정 → 전환
- 클럭을 내릴 때: 전환 — → 웨이트 감소 항상 "느린 쪽 기준 설정"을 먼저
Lock 대기 — 반드시 필요하다
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY)) { } // 안정될 때까지 대기
PLL은 켠 즉시 정확한 주파수를 내지 않는다. 수십~수백 마이크로초의 안정화 시간이 필요하다. 대기하지 않고 전환하면 불안정한 클럭으로 동작해 예측 불가능한 오류가 난다.
타임아웃도 함께 두어야 한다.
uint32_t timeout = 10000;
while (!(RCC->CR & RCC_CR_PLLRDY) && --timeout) { }
if (!timeout) { /* 크리스털 불량 → HSI로 폴백 */ }
크리스털이 불량이면 여기서 영원히 멈춘다. 양산 제품에서 "일부 기기만 부팅이 안 된다"는 증상의 원인이 되곤 한다.
지터 — 공짜가 아니다
PLL 출력은 기준 클럭보다 지터(주기 흔들림)가 크다
영향받는 것들
- 고속 통신(USB, 이더넷) — → 지터 규격을 만족해야 한다
- ADC 샘플링 — → 샘플 시점이 흔들리면 노이즈로 나타난다
- 오디오 — → 재생 품질 저하
정밀한 타이밍이 필요하면 크리스털을 직접 쓰거나 별도 클럭 소스를 둔다. 오디오 코덱에 전용 크리스털을 다는 이유다.
클럭 소스 종류
| 정확도 | 특징 | |
|---|---|---|
| HSI (내부 RC) | ±1~2% | 즉시 사용 가능. 부팅 기본값 |
| HSE (외부 크리스털) | ±20~50ppm | 정확. 통신에 필요 |
| LSI (내부 저속 RC) | ±5% | 워치독, 저전력 |
| LSE (32.768kHz) | 정확 | RTC 전용 |
32.768kHz가 표준인 이유 — 2¹⁵ = 32768이라 15비트 카운터로 정확히 1초를 만들 수 있다.
클럭 보안 시스템 (CSS)
HSE 크리스털이 고장나면 → 자동으로 HSI 로 전환 + NMI 발생 현장에서 크리스털이 죽어도 최소한의 동작을 유지하고 오류를 보고할 수 있다. 안전이 중요한 기기에서는 켜 두는 것이 권장된다.