17. 범용 타이머·PWM 출력
범용 타이머(TIM)는 채널·PWM·입력 캡처를 제공합니다. 가장 많이 쓰는 PWM은 켜진 시간의 비율(듀티)을 빠르게 조절해 LED 밝기나 모터 속도를 "아날로그처럼" 제어합니다. TIM2 채널1(PA0)로 1kHz PWM을 만들고 듀티를 조절합니다. 세 핵심 레지스터 PSC(분주)·ARR(주기)·CCR(듀티)의 관계와, APB1 타이머 클럭이 PCLK1의 2배가 되는 함정을 익힙니다.
이 강의에서 배우는 것
- 1범용 타이머의 시간축(PSC·ARR)과 카운터 클럭을 계산한다
- 2PWM 모드1의 동작(CNT vs CCR 비교)을 이해한다
- 3TIM2 채널1로 PWM을 출력하도록 레지스터를 설정한다
- 4CCR로 듀티를, ARR로 주파수를 조절한다
- 5APB1 타이머 클럭이 PCLK1의 2배가 되는 규칙을 안다
소개
디지털 핀은 0/1만 내지만, 켜진 시간 비율을 빠르게 바꾸면 평균 전압이 달라져 아날로그처럼 동작합니다. 타이머 출력은 GPIO의 대체 기능(AF)이라 PA0를 AF 푸시풀(0xB)로 둬야 합니다.
핵심 개념
1) 시간축 — PSC·ARR·CCR
counter_clk = TIMxCLK / (PSC + 1)
pwm_freq = counter_clk / (ARR + 1)
duty(%) = CCR * 100 / (ARR + 1)
/* PSC=71 → 72MHz/72 = 1MHz, ARR=999 → 1kHz, CCR=250 → 25% */타이머 클럭 함정: TIM2~4는 APB1 버스인데, APB1 프리스케일러가 1이 아니면 타이머 클럭은 PCLK1의 2배가 됩니다. 표준 72MHz 설정에서 PCLK1=36MHz지만 TIM2 클럭은 72MHz입니다.
2) PWM 모드1과 설정 순서
PWM 모드1: CNT < CCR 동안 출력 High. 설정 순서는 클럭 → 핀(AF) → 시간축(PSC/ARR) → 듀티(CCR) → 모드(CCMR1 OC1M=110+OC1PE) → 출력(CCER CC1E) → UG(강제 로드) → CEN(시작).
TIM2->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; /* PWM1(110) */
TIM2->CCMR1 |= TIM_CCMR1_OC1PE; TIM2->CCER |= TIM_CCER_CC1E;
TIM2->CR1 |= TIM_CR1_ARPE; TIM2->EGR |= TIM_EGR_UG; TIM2->CR1 |= TIM_CR1_CEN;핵심 예제
#include "stm32f10x.h"
int main(void){
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
GPIOA->CRL &= ~0xFu; GPIOA->CRL |= 0xBu; /* PA0 = AF 푸시풀 */
TIM2->PSC = 71u; TIM2->ARR = 999u; TIM2->CCR1 = 250u; /* 1kHz, 25% */
TIM2->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE;
TIM2->CCER |= TIM_CCER_CC1E;
TIM2->CR1 |= TIM_CR1_ARPE; TIM2->EGR |= TIM_EGR_UG; TIM2->CR1 |= TIM_CR1_CEN;
while (1) { /* CCR1 을 바꾸면 듀티가 즉시 바뀐다 */ }
}계산 검산: PSC=71,ARR=999,CCR=250 → 1000Hz·25%. CCR=500 → 50%. ARR=499 → 2000Hz. Logic Analyzer에 PORTA.0을 추가하면 듀티 비율을 확인할 수 있습니다.
자주 하는 실수
Q. 핀에서 PWM이 안 나와요.
A. ① PA0를 AF 푸시풀(0xB)로 설정, ② CCER의 CC1E로 출력 켜기, ③ CR1의 CEN으로 카운터 시작 — 세 가지를 확인하세요.
Q. 주파수가 계산의 절반/2배로 나와요.
A. 타이머 클럭을 잘못 잡았습니다. APB1 프리스케일러가 1이 아니면 TIM2 클럭은 PCLK1의 2배(72MHz)입니다. 36MHz로 계산하면 2배 어긋납니다.
Q. 설정을 바꿨는데 첫 주기에 반영이 안 돼요.
A. EGR의 UG 비트로 업데이트 이벤트를 강제하면 PSC/ARR/CCR이 즉시 로드됩니다. 빠뜨리면 다음 업데이트까지 옛 값으로 돕니다.
정리
- 타이머: PSC로 카운터 클럭, ARR로 주기, CCR로 듀티를 정한다
- PWM 모드1은 CNT < CCR 동안 High → 듀티 = CCR/(ARR+1)
- 타이머 출력은 AF 핀(PA0=0xB)으로 내보낸다
- 설정 순서: 클럭 → 핀 → 시간축 → 모드/출력 → UG → CEN
- APB1 타이머 클럭은 PCLK1의 2배(72MHz)임에 주의
과제
- 듀티를 0→100%로 서서히 올렸다 내리는 LED 호흡(breathing) 효과 구현
- PWM 주파수를 500Hz로 바꾸려면 PSC/ARR을 어떻게 할지 계산
- CCR ≥ ARR+1 이면 출력이 항상 High(100%)임을 확인