PWM 주파수 듀티 계산 공식과 MCU 타이머 레지스터 설정 가이드

임베디드 모터 드라이브와 전력 변환 회로 설계에서 정밀한 타이머 타이밍 제어는 핵심 과제입니다. 스위칭 주파수를 높이면 인덕터와 커패시터 부피를 줄일 수 있지만, 스위칭 손실과 타이머 카운터 분해능(Resolution) 저하라는 트레이드오프가 필연적으로 발생합니다. 반대로 주파수를 낮추면 전력 소자 발열은 줄어들지만 가청 대역 소음과 심각한 토크 리플이 시스템을 불안정하게 만듭니다.

실무 엔지니어링 현장에서 가장 빈번하게 발생하는 문제는 클록 트리 해석 오류로 인한 주파수 불일치입니다. 특히 APB 버스 분주비에 따라 내부 타이머 클록이 2배로 자동 승압되는 하드웨어 구조를 간과하면 계산값과 오실로스코프 실측 파형 사이에 2배의 오차가 발생합니다. 정밀한 전압 및 전류 제어를 위해서는 PWM 주파수 듀티 계산 수식을 로우레벨 타이머 레지스터 구조와 완벽히 결합해야 합니다.

PWM 주파수 듀티 계산을 위한 오실로스코프 파형 측정 및 마이크로컨트롤러 타이머 레지스터 디버깅 환경

타이머 카운터 모드별 PWM 주파수 듀티 계산 공식과 내부 동작

PWM 신호는 타이머 클록 주파수, 프리스케일러(Prescaler), 자동 재장전 레지스터(Auto-Reload Register), 그리고 캡처/비교 레지스터(Capture/Compare Register)의 유기적인 조합으로 생성됩니다. 카운터 동작 방식이 엣지 정렬(Edge-Aligned)인지 또는 중앙 정렬(Center-Aligned)인지에 따라 수학적 계산 공식이 완전히 분기됩니다.

1. 엣지 정렬 모드 (Up-Counting 및 Down-Counting)

카운터가 0에서 ARR 값까지 증가한 뒤 오버플로하여 다시 0으로 리셋되는 방식입니다. 일반적인 단극성 스위칭 회로나 단순 DC 모터 속도 제어에 널리 사용됩니다. 출력 주파수 및 듀티 사이클은 다음과 같은 공식으로 도출됩니다.

PWM 출력 주파수: f_PWM = f_TIM_CLK / ((PSC + 1) * (ARR + 1))

PWM Mode 1 기준 듀티 비율: Duty = CCR / (ARR + 1)

비교 레지스터 설정값: CCR = round(Duty * (ARR + 1))

2. 중앙 정렬 모드 (Center-Aligned / Phase-Correct)

카운터가 0에서 ARR까지 증가한 후 방향을 전환하여 0까지 감소하는 방식입니다. 스위칭 고조파 노이즈가 주파수 스펙트럼상에서 고르게 분산되며, 대칭적인 스위칭 파형을 생성하므로 BLDC 및 PMSM 인버터 제어에 표준으로 사용됩니다.

PWM 출력 주파수: f_PWM = f_TIM_CLK / (2 * (PSC + 1) * ARR)

중앙 정렬 듀티 비율: Duty = CCR / ARR

비교 레지스터 설정값: CCR = round(Duty * ARR)

PWM 주파수 듀티 계산 엣지 정렬 카운터와 중앙 정렬 카운터의 타이머 업다운 파형 비교 다이어그램

“The timer clock frequencies are automatically fixed by hardware. If the APB prescaler is 1, the timer clock frequency is set to the same frequency as that of the APB domain. Otherwise, it is set to twice the APB frequency (x2). In center-aligned mode, the counter counts from 0 up to the auto-reload value minus 1, generates a counter overflow event, then counts down to 1 and generates a counter underflow event.”
— STMicroelectronics STM32G4 Series Reference Manual (RM0440), Section 27.3

타이머 레지스터 최적값 자동 연산 C99 알고리즘 스니펫

1. 분해능 극대화 및 양자화 오차 최소화 원리

실제 펌웨어 환경에서는 클록 분주비와 카운터 주기 사이에서 양자화 오차를 최소화하고 분해능(Resolution)을 극대화해야 합니다. 분해능은 log2(ARR + 1)에 정비례하므로, 프리스케일러(PSC)는 가능한 작게 유지하고 자동 재장전 레지스터(ARR)를 가능한 크게 설정해야 부드러운 듀티 변조가 가능합니다.

2. 16비트 레지스터 자동 탐색 구현 코드

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>

typedef struct {
    uint16_t psc;
    uint16_t arr;
    uint16_t ccr;
    double actual_freq;
    double actual_duty;
    double freq_error;
    uint8_t resolution_bits;
} pwm_config_t;

bool calculate_edge_pwm_registers(uint32_t tim_clk_hz, double target_freq, 
                                  double target_duty, pwm_config_t *out_cfg) 
{
    if (tim_clk_hz == 0 || target_freq <= 0.0 || target_duty < 0.0 || target_duty > 100.0 || !out_cfg) {
        return false;
    }
    double total_div_ideal = (double)tim_clk_hz / target_freq;
    if (total_div_ideal < 1.0 || total_div_ideal > (65536.0 * 65536.0)) {
        return false;
    }

    uint32_t best_psc = 0;
    uint32_t best_arr = 0;
    double min_freq_err = 1e12;
    uint32_t psc_min = (uint32_t)ceil(total_div_ideal / 65536.0);
    if (psc_min > 0) psc_min -= 1;

    for (uint32_t psc = psc_min; psc <= 65535; psc++) {
        uint32_t arr = (uint32_t)lround(total_div_ideal / (double)(psc + 1)) - 1;
        if (arr > 65535) continue;

        double actual_f = (double)tim_clk_hz / ((double)(psc + 1) * (double)(arr + 1));
        double err = fabs(actual_f - target_freq);

        if (err < min_freq_err) {
            min_freq_err = err;
            best_psc = psc;
            best_arr = arr;
            if (min_freq_err < 0.001 && best_arr >= 1000) break;
        }
    }

    uint32_t ccr = (uint32_t)lround((target_duty / 100.0) * (double)(best_arr + 1));
    if (ccr > (best_arr + 1)) ccr = best_arr + 1;

    out_cfg->psc = (uint16_t)best_psc;
    out_cfg->arr = (uint16_t)best_arr;
    out_cfg->ccr = (uint16_t)ccr;
    out_cfg->actual_freq = (double)tim_clk_hz / ((double)(best_psc + 1) * (double)(best_arr + 1));
    out_cfg->actual_duty = ((double)ccr / (double)(best_arr + 1)) * 100.0;
    out_cfg->freq_error = min_freq_err;
    out_cfg->resolution_bits = (uint8_t)(log2((double)best_arr + 1.0));
    return true;
}

위 코드는 16비트 타이머의 최대 레지스터 한계(65535)를 초과하지 않으면서 주파수 편차를 최소화합니다. 분주비 탐색 루프에서 ARR 값이 최대가 되는 지점을 우선 선택하여 실효 제어 분해능 비트를 극대화하도록 설계되었습니다.

PWM 주파수 듀티 계산을 위한 타이머 레지스터 연산 C 코드 실행 결과 터미널 화면

MCU 제조사별 타이머 아키텍처 및 안전 하드웨어 사양 비교

1. 주요 제조사별 타이머 레지스터 및 섀도우 구조 비교

마이크로컨트롤러 아키텍처에 따라 섀도우 레지스터 동기화 시점과 데드타임(Dead-time) 생성 하드웨어 구성에 차이가 있습니다. 모터 인버터 스위칭 중 레지스터를 즉시 갱신하면 파형 글리치나 브리지 단락 사고가 일어날 수 있습니다.

제조사 / 아키텍처타이머 모듈핵심 레지스터 명칭섀도우(Preload) 메커니즘하드웨어 데드타임 지원
STMicroelectronics
(STM32G4/F4)
Advanced Timer
(TIM1, TIM8)
TIMx_PSC
TIMx_ARR
TIMx_CCRx
CR1.ARPE, CCMRx.OCxPE
(업데이트 이벤트 UEV 동기화)
TIMx_BDTR 레지스터
(DTG 비트열 기반 지연 삽입)
Texas Instruments
(C2000 TMS320F)
Enhanced PWM
(ePWM)
CLKDIV, HSPCLKDIV
TBPRD
CMPA, CMPB
TBCTL[PRDLD], CMPCTL
(CTR=0 또는 CTR=PRD 로드)
DBRED, DBFED 레지스터
(상/하단 독립 나노초 지연)
Microchip
(AVR ATmega328P)
Timer/Counter 1
(TC1)
TCCR1B[CS]
ICR1 / OCR1A
OCR1A, OCR1B
OCR1x 버퍼 자동 섀도우
(TOP/BOTTOM 자동 반영)
기본 미지원
(외부 게이트 드라이버 의존)
NXP Semiconductors
(S32K3 / i.MX RT)
FlexPWMCTRL[PRSC]
INIT, VAL1
VAL2, VAL3, VAL4
MCTRL[LDOK] 동시 래칭
(스위칭 중간 글리치 차단)
DTCNT0, DTCNT1 레지스터
(서브모듈별 독립 데드타임)

2. 슛스루 방지를 위한 하드웨어 데드타임 보호 원리

인버터 하프 브리지에서 상단과 하단 MOSFET이 동시 도통할 경우 전원단이 쇼트되는 슛스루 현상이 발생합니다. 이를 원천 차단하기 위해 Advanced Timer의 하드웨어 데드타임 생성기를 통해 스위치 간 안전 지연 시간을 필수적으로 삽입해야 합니다.

PWM 주파수 듀티 계산 및 모터 하프 브리지 슛스루 방지 하드웨어 데드타임 타이밍도

모터 종류별 PWM 제어 메커니즘: BLDC, DC, 유도 전동기

구동 대상 모터의 전기적 구조에 따라 적합한 스위칭 주파수 대역과 PWM 변조 방식이 달라집니다. 고정밀 모터 제어를 위해서는 모터 고유의 특성을 고려하여 타이머 구조를 설정해야 합니다.

1. 브러시 DC 모터 (Brushed DC Motor)

단상 H-브리지 회로를 통해 평균 전압을 제어합니다. 단극성(Unipolar) 변조는 한쪽 레그만 PWM으로 스위칭하여 리플 전류를 줄이고 스위칭 손실을 낮춥니다. 양극성(Bipolar) 변조는 대각선 방향 스위치를 교차 구동하여 정역회전 응답성과 회생 제동 특성을 극대화합니다. 통상 10 kHz에서 25 kHz 주파수를 사용하여 가청 소음을 억제합니다.

2. BLDC 모터 (Brushless DC Motor)

3상 전교류 인버터 브리지를 필요로 합니다. 사다리꼴파(Trapezoidal) 6스텝 제어 방식은 한 시점에 2개 상만 도통시키고 1개 상은 플로팅 상태로 둡니다. 플로팅된 상에서 유기되는 역기전력(BEMF)의 영교차점(Zero-Crossing)을 검출하여 정류 타이밍을 동기화합니다. 반면 공간벡터 변조(SVPWM) 기반 FOC 제어는 3상 전 권선에 중앙 정렬 PWM을 지속 인가하여 토크 리플을 없앱니다.

3. 유도 전동기 (AC Induction Motor, ACIM)

권선 인덕턴스가 커서 통상 2 kHz에서 16 kHz 사이의 비교적 낮은 캐리어 주파수를 채택합니다. 기본 구동은 고정자 자속 포화를 방지하기 위해 주파수에 비례하여 출력 전압을 변경하는 V/f 스칼라 제어를 사용합니다. 또한 회전자 유도 전류 형성을 위한 슬립 주파수(Slip Frequency) 보상 알고리즘이 필수적으로 결합되어야 합니다.

PWM 주파수 듀티 계산 기반 DC 및 3상 BLDC 유도 전동기 인버터 제어 구조도

실무 인버터 설계를 위한 필수 아키텍처 체크리스트

  • 프리로드(Preload) 레지스터 활성화: ARR 및 CCR 갱신 시 반드시 섀도우 버퍼를 거쳐 언더플로 또는 오버플로 시점에 동기화 전송되도록 설정합니다.
  • 하드웨어 상보 출력 및 데드타임 보장: 소프트웨어 토글을 배제하고 타이머 내부 DTG 모듈을 사용하여 t_dead > t_off_delay + t_fall + t_margin 조건을 만족시킵니다.
  • 하드웨어 긴급 셧다운 회로 구축: 과전류 트립 신호 발생 시 CPU 인터럽트를 거치지 않고 나노초 단위로 PWM 출력을 차단하는 브레이크 핀(BKIN, Trip-Zone)을 타이머에 직접 연동합니다.

타이머 레지스터 및 PWM 제어 실무 FAQ

Q1. 실행 중 CCR 값을 변경할 때 섀도우 레지스터를 켜지 않으면 어떤 결함이 발생하나요?

카운터가 상향 카운팅 중인 상태에서 현재 카운터 값보다 작은 CCR 값으로 직접 덮어쓰면 비교 일치(Compare Match) 이벤트가 누락됩니다. 그 결과 카운터가 타이머의 최대 카운트(65535)까지 도달하는 오버플로 글리치가 발생하여 전원단 스위칭 소자가 파손될 수 있습니다.

Q2. 스위칭 주파수를 100 kHz 이상으로 높일 때 듀티 제어 분해능이 왜 급격히 떨어지나요?

PWM 분해능 단계 수는 ARR + 1로 결정됩니다. 고정된 타이머 입력 클록에서 주파수를 높이려면 ARR 값을 낮출 수밖에 없습니다. 예컨대 100 MHz 클록에서 100 kHz 신호를 생성하면 ARR이 999에 불과해 약 10비트 분해능(1000단계)으로 축소되며, 고정밀 전압 변조 시 양자화 리플 노이즈가 급증합니다.

Q3. 인버터 브리지 제어 시 소프트웨어 인터럽트로 상보 PWM을 생성하면 안 되는 이유는 무엇인가요?

소프트웨어 기반 GPIO 제어는 인터럽트 지연 시간(Latency)과 지터(Jitter)로 인해 상단 MOSFET 턴오프와 하단 MOSFET 턴온 사이클 간에 마이크로초 단위의 충돌 구간을 형성합니다. 이는 전원 레일과 접지가 직접 연결되는 슛스루(Shoot-through) 현상을 초래하므로 반드시 전용 하드웨어 데드타임 생성 모듈을 사용해야 합니다.

기술 참조 문서 및 공식 가이드

공식 하드웨어 매뉴얼 및 레퍼런스 규격

함께 보면 좋은 글

📌 안내
이 글은 정보 제공을 목적으로 작성되었으며, 실제 기기·환경·정책에 따라 결과가 다를 수 있습니다. 보다 정확하고 최신인 정보는 아래 공신력 있는 기관의 자료를 함께 참고하시기 바랍니다.

Similar Posts