RP2040에서 PWM 주파수를 맞출 때 TOP=주파수로 나눈 값으로만 계산하면 한 카운트가 어긋납니다. 카운터는 0부터 TOP까지 세므로 한 주기는 TOP+1 카운트입니다. Raspberry Pi의 RP2040 데이터시트와 공식 Pico SDK PWM 헤더를 기준으로, 125 MHz 클록에서 1 kHz·20 kHz를 만드는 값을 계산해 봅니다.
1. 주파수 식과 적용 조건
기본적인 free-running, trailing-edge PWM에서 f_PWM = f_clk_sys / (DIV × (TOP+1))입니다. DIV는 8비트 정수부와 4비트 소수부를 가진 분주 값으로, 2 + 0/16은 정확히 2입니다. TOP은 16비트 wrap 값이므로 0부터 65535까지 설정할 수 있습니다. 분주가 1일 때 PWM 카운터는 시스템 클록마다 증가합니다.
이 식은 phase-correct 모드를 끈 상태에 적용합니다. SDK는 phase-correct 모드가 PWM 주파수를 절반으로 낮춘다고 설명합니다. B 핀 입력으로 카운트를 제어하는 모드에도 같은 계산을 그대로 적용할 수 없습니다. 실제 clk_sys는 프로젝트의 클록 설정에 따라 다를 수 있으니 보드에서는 clock_get_hz(clk_sys)로 확인하세요.
2. 1 kHz와 20 kHz 계산
예시의 clk_sys=125,000,000 Hz에서 1 kHz를 원한다면 DIV=2, TOP+1=62,500이므로 TOP=62,499입니다. 같은 클록에서 20 kHz는 DIV=1, TOP+1=6,250이므로 TOP=6,249입니다.
| 목표 | DIV | TOP | 계산 주파수 |
|---|---|---|---|
| 1 kHz | 2 | 62499 | 1000 Hz |
| 20 kHz | 1 | 6249 | 20000 Hz |
1 kHz 설정에서 채널의 compare level을 31,250으로 주면 31,250 / 62,500 = 50%입니다. 두 출력 채널 A·B는 같은 PWM 슬라이스의 분주와 TOP을 공유하므로 주파수를 따로 정할 수 없습니다. 듀티는 각 채널의 level로 조절합니다. 설정값을 바꾼 직후의 첫 주기는 기존 카운터 상태의 영향을 받을 수 있으므로, 파형을 측정할 때는 안정된 연속 주기를 확인하세요.
3. PC에서 계산 검증
다음 표준 C 예제는 레지스터를 건드리지 않는 계산 테스트입니다. pwm_frequency.c로 저장하고 gcc -std=c11 -Wall -Wextra -Werror pwm_frequency.c -o pwm_frequency로 빌드한 뒤 실행하세요. div16은 실제 분주 값의 16배입니다.
예상 출력:
예제의 PASS는 식과 두 설정값만 검증합니다. 보드의 실제 클록, 핀 다중화, 배선 및 오실로스코프 파형까지 검증한 결과는 아닙니다.
4. Pico SDK에 적용하고 실측하기
SDK에서는 PWM 핀을 설정한 뒤 pwm_config_set_clkdiv_int_frac4(&config, 2, 0)와 pwm_config_set_wrap(&config, 62499)로 1 kHz 조건을 구성할 수 있습니다. pwm_init(slice, &config, true)로 시작하고 pwm_set_chan_level(slice, channel, 31250)으로 50% compare 값을 설정합니다. 공식 Pico SDK PWM 헤더에서 각 함수의 인자와 해당 보드 SDK 버전을 확인하세요.
clock_get_hz(clk_sys)가 예시의 125 MHz인지 확인하고 다르면 식으로 TOP을 다시 계산합니다.TOP이 16비트 범위인지, level이 의도한 듀티인지 확인합니다. 주파수가 높아질수록 사용할 수 있는 카운트 수가 줄어 듀티 분해능도 낮아집니다.- 오실로스코프로 핀의 연속 주기와 HIGH 시간을 측정합니다. 모터·LED 드라이버 입력이라면 부하 회로의 전기적 제한도 별도로 확인합니다.
댓글
첫 댓글을 남겨 보세요.