1. 서론
Buck 컨버터는 입력 DC 전압을 낮은 출력 DC 전압으로 변환하는 스위칭 레귤레이터로, 디지털 제어기를 통해 높은 정밀도와 동적 응답성을 제공합니다. TI의 C2000 DSP(F28379D)는 고속 ADC, PWM, CMPSS, CLA를 제공하여 디지털 전력 변환에 적합합니다. 본 문서의 목적은 TI C2000 DSP를 활용하여 Buck 컨버터의 디지털 제어기를 설계하는 상세 절차를 이론적인 베이스로 상세하게 기술하는 것으로, 피크 전류 모드 제어(PCMC)를 구현하고, UART를 통한 RUN/STOP 제어, 외부 스위치 입력, 소프트 스타트, 과전압/과전류 보호(OVP/OCP)를 포함합니다. 설계 과정은 요구사항 정의, 하드웨어 설계, 아날로그 및 디지털 모델링, 제어기 이산화, DSP 코드 구현, 시뮬레이션 및 검증을 제시한다.
2. 설계 요구사항
Buck 컨버터의 디지털 제어기 설계 요구사항은 다음과 같습니다:
- 입력 전압 (\( V_{in} \)): 12V
- 출력 전압 (\( V_{out} \)): 2.5V
- 출력 전류 (\( I_{out} \)): 1A
- 스위칭 주파수 (\( f_{sw} \)): 200kHz (\( T_{sw} = \frac{1}{f_{sw}} = 5 \mu s \))
- 샘플링 주기 (\( T_s \)): 5μs (PWM과 동기화)
- 전류 모드: 연속 전도 모드 (CCM)
- 제어 방식: VMC 및 PCMC
- 하드웨어 플랫폼: TI Delfino F28379D LaunchPad + 커스터마이징된 동기 정류 Buck 컨버터 보드
- 성능 목표:
- 출력 전압 리플: \( \Delta V_{out} \leq 25mV \) (1% 이하)
- 과도 응답 시간: \(\leq 100\mu s\) (부하/전압 스텝 응답)
- 위상 마진: 45°~60°
- 대역폭: 약 20kHz (\( f_{sw}/10 \))
- 추가 요구사항:
- ADC: 12비트, 3.3V 기준
- PWM: Up-Down 모드, 200MHz 시스템 클럭
- 안정성: 듀티 사이클 제한 (0.1~0.9), ADC 입력 범위 보호
- 디버깅: UART (SCIA, 115200 baud)로 \( V_{out}, I_{out} \), 상태 모니터링
- 보호: 과전압 (\( V_{out} > 2.75V \)), 과전류 (\( I_{out} > 1.5A \))
- 기능: UART 명령('R'/'S'), 외부 스위치(GPIO4), 소프트 스타트 (10ms)
- 최적화: CLA로 PI 연산, IQmath로 고정소수점 연산, Pre-warping
3. 하드웨어 설계
커스터마이징된 동기 정류 Buck 컨버터는 BOOSTXL-BUCKCONV를 참고하여 설계되며, 입력 12V, 출력 2.5V, 1A, 200kHz, CCM에 최적화된 동기 정류 전원단과 센싱 회로로 구성됩니다. 동기 정류 방식은 프리휠링 다이오드 대신 저측(Low-Side) MOSFET을 사용하여 효율성을 향상시킵니다. 하드웨어는 TI Delfino F28379D LaunchPad와 호환되며, UART, 외부 스위치, 보호 기능을 지원합니다.
3.1 인덕터 설계
- 인덕터 리플 전류 (\( \Delta I_L \)): \( I_{out} \times 0.3 = 1A \times 0.3 = 0.3A \).
- 인덕터 값 계산: \[ L = \frac{V_{in} \cdot \left( \frac{V_{out}}{V_{in}} \right) \cdot \left( 1 - \frac{V_{out}}{V_{in}} \right)}{f_{sw} \cdot \Delta I_L} \] 대입: \( V_{in} = 12V \), \( V_{out} = 2.5V \), \( f_{sw} = 200 \times 10^3 Hz \), \( \Delta I_L = 0.3A \). \[ L = \frac{12 \cdot 0.2083 \cdot 0.7917}{200 \times 10^3 \cdot 0.3} \approx 33 \times 10^{-6} H = 33 \mu H \]
- 선택: 33μH 인덕터 (포화 전류 ≥ 1.5A, DCR ≤ 50mΩ, 예: Coilcraft MSS7341-333MLB).
3.2 커패시터 설계
- 전압 리플 (\( \Delta V_{out} \)): \( V_{out} \times 0.01 = 2.5V \times 0.01 = 0.025V \).
- 커패시터 값 계산: \[ C = \frac{\Delta I_L}{8 \cdot f_{sw} \cdot \Delta V_{out}} \] 대입: \( \Delta I_L = 0.3A \), \( f_{sw} = 200 \times 10^3 Hz \), \( \Delta V_{out} = 0.025V \). \[ C = \frac{0.3}{8 \cdot 200 \times 10^3 \cdot 0.025} = 7.5 \times 10^{-6} F = 7.5 \mu F \]
- 선택: 10μF 세라믹 커패시터 (ESR ≤ 10mΩ, 6.3V 이상, 예: Murata GRM31CR60J106KA01L).
3.3 스위치 및 동기 정류
- 고측(High-Side) MOSFET: N-채널, 30V, 25A (TI CSD87588N, \( R_{DS(on)} \leq 10m\Omega \)), ePWM1A(GPI0)로 구동.
- 저측(Low-Side) MOSFET: N-채널, 30V, 25A (TI CSD87588N, \( R_{DS(on)} \leq 10m\Omega \)), ePWM1B(GPI1)로 구동, 동기 정류 구현.
- 게이트 드라이버: UCC27424, 4A 듀얼 채널, 3.3V 로직 호환, High-Side 및 Low-Side MOSFET 동시 구동, 데드타임 66.7ns 설정.
- 설명: 동기 정류는 프리휠링 다이오드를 저측 MOSFET으로 대체하여 전도 손실을 줄이고 효율성을 향상시킵니다. ePWM1A와 ePWM1B는 상보적 출력으로 설정되며, 데드타임은 MOSFET 스위칭 충돌을 방지합니다.
3.4 센싱 및 제어 회로
- 전압 센싱:
- 분압 회로: \( R_1 = 3.3k\Omega \), \( R_2 = 2.2k\Omega \), 출력 전압을 0~3.3V로 스케일링.
- ADC 입력: ADCINA0 (GPIO2), 12비트, 3.3V 기준.
- 전류 센싱 (PCMC):
- 션트 저항: 0.1Ω (1% 정밀도, 1W 이상, 예: Vishay WSL1206R1000FEA).
- ADC 입력: ADCINA1 (GPIO3), CMPSS1로 피크 전류 비교.
- 옵션: INA240 전류 센서 앰프(고정밀도, -4V~80V CMRR)로 대체 가능.
- 외부 스위치:
- GPIO4: 풀업 저항(10kΩ), Low=RUN, High=STOP.
- 스위치: 푸시 버튼 또는 토글 스위치, 디바운싱 회로(100nF 병렬 커패시터).
- UART 디버깅:
- SCIA: GPIO28(TX), GPIO29(RX), 115200 baud.
- FTDI 칩(예: FT232R) 또는 XDS110 내장 UART 사용.
3.5 하드웨어 플랫폼
- F28379D LaunchPad: 200MHz 듀얼 코어, 12비트 ADC, 16채널 PWM, CLA 지원.
- 커스터마이징된 Buck 컨버터 보드:
- 동기 정류 전원단: High-Side/Low-Side MOSFET(CSD87588N), UCC27424 드라이버.
- 인덕터: 33μH, 커패시터: 10μF.
- 센싱: 전압 분압기, 0.1Ω 션트, INA240(옵션).
- 입출력: 12V 입력(최소 2A), 2.5V/1A 출력, 동적 부하 지원(2.5Ω 저항).
- 외부 장비:
- 전원 공급기: 12V, 2A DC.
- 오실로스코프: Tektronix TBS2000 (리플, 과도 응답 측정).
- 부하: 2.5Ω 저항(1A 정격), 동적 부하(0.5A~1A 스텝).
4. 아날로그 모델링
4.1 State-Space 평균화 모델
CCM에서 상태 변수는 인덕터 전류 (\( i_L \))와 출력 커패시터 전압 (\( v_C \))입니다.
- 스위치 온 (\( D \)): \[ L \frac{di_L}{dt} = v_{in} - v_C, \quad C \frac{dv_C}{dt} = i_L - \frac{v_C}{R} \]
- 스위치 오프 (\( 1-D \)): \[ L \frac{di_L}{dt} = -v_C, \quad C \frac{dv_C}{dt} = i_L - \frac{v_C}{R} \]
- 평균화: \[ \frac{d}{dt} \begin{bmatrix} i_L \\ v_C \end{bmatrix} = \begin{bmatrix} 0 & -\frac{1}{L} \\ \frac{1}{C} & -\frac{1}{R C} \end{bmatrix} \begin{bmatrix} i_L \\ v_C \end{bmatrix} + \begin{bmatrix} \frac{D}{L} \\ 0 \end{bmatrix} v_{in} \] 출력: \( y = v_C = [0 \ 1] \begin{bmatrix} i_L \\ v_C \end{bmatrix} \).
4.2 소신호 모델
- 상태 변수 분리: \( i_L = I_L + \hat{i}_L \), \( v_C = V_C + \hat{v}_C \), \( d = D + \hat{d} \).
- VMC 전달 함수 (\( G_{vd}(s) \)): \[ G_{vd}(s) = \frac{V_{in}}{1 + s \frac{L}{R} + s^2 L C} \] 대입: \( V_{in} = 12V \), \( L = 33 \mu H \), \( C = 10 \mu F \), \( R = 2.5 \Omega \). \[ \omega_0 = \frac{1}{\sqrt{L C}} \approx 8.72 \times 10^4 \, \text{rad/s}, \quad Q = R \sqrt{\frac{C}{L}} \approx 0.69 \]
- PCMC 전달 함수 (\( G_{id}(s) \)): \[ G_{id}(s) = \frac{V_{in}}{s L + R_L + \frac{1}{s C} \parallel R} \]
4.3 MATLAB 모델링
% Buck 컨버터 플랜트 모델
Vin = 12; L = 33e-6; C = 10e-6; R = 2.5;
Gvd = tf(Vin, [L*C, L/R, 1]); % VMC 전달 함수
figure; bode(Gvd); grid on; % 주파수 응답
figure; step(Gvd); grid on; % 계단 응답
5. 디지털 제어기 설계
- VMC: 단일 전압 루프, 간단, 안정성 높음, 과도 응답 느림.
- PCMC: 전압/전류 이중 루프, 빠른 응답, 부하 변화에 강인, Slope compensation 필요.
5.1 아날로그 PI 제어기
- 전달 함수: \[ G_c(s) = K_p + \frac{K_i}{s} = \frac{K_p s + K_i}{s} \] \( K_p = 0.1 \), \( K_i = 1000 \) (MATLAB pidTuner, 위상 마진 45°~60°, 대역폭 20kHz).
- MATLAB 튜닝:
Kp = 0.1; Ki = 1000; Gc = tf([Kp Ki], [1 0]); G_loop = series(Gc, Gvd); margin(G_loop); grid on;
5.2 이산화 (Tustin 변환 with Pre-warping)
- Pre-warping 주파수: 20kHz.
- Tustin 변환: \[ s = \frac{\omega_p}{\tan(\omega_p T_s / 2)} \cdot \frac{z - 1}{z + 1}, \quad \omega_p = 2 \pi \cdot 20 \times 10^3, \quad T_s = 5 \times 10^{-6} \]
- 이산 PI 제어기: \[ G_c(z) \approx \frac{0.1025 z - 0.0975}{z - 1} \] 차분 방정식: \[ u[n] = u[n-1] + 0.1025 e[n] - 0.0975 e[n-1] \]
- MATLAB:
Ts = 5e-6; Gc_d = c2d(Gc, Ts, 'tustin', 'PrewarpFrequency', 2e4); [num, den] = tfdata(Gc_d, 'v'); % 출력: [0.1025, -0.0975], [1, -1]
5.3 PCMC 추가 설계
- 전류 루프: CMPSS1로 인덕터 전류를 \( I_{ref} = 1A \)와 비교.
- Slope compensation: \( m_c = 0.01 V/\mu s \).
- MATLAB:
mc = 0.01e6; % Slope compensation (V/s) Iref = 1.0; % 피크 전류 참조
6. TI C2000 DSP 구현
F28379D에서 PCMC를 구현하며, CLA, IQmath, UART, RUN/STOP, 소프트 스타트, OVP/OCP를 통합합니다.
6.1 시스템 구성
- ADC: 12비트, 3.3V 기준, ADCINA0(전압), ADCINA1(전류).
- PWM: 200kHz Up-Down 모드, 주기 375 (200MHz / (2 * 200kHz)).
- CMPSS (PCMC): 내부 DAC로 피크 전류 참조.
- CLA: PI 연산.
- UART: SCIA, GPIO28(TX), GPIO29(RX), 115200 baud.
- 외부 스위치: GPIO4, 풀업, RUN/STOP 토글.
- GPIO: PWM(GPI0, GPI1), 전압(GPIO2), 전류(GPIO3), UART(GPIO28, GPIO29), 스위치(GPIO4).
6.2 PCMC 코드
PCMC는 전압 및 전류 루프를 결합하며, 추가 기능을 통합합니다.
// buck_pcmc.c: F28379D 기반 Buck 컨버터 피크 전류 모드 제어(PCMC) 디지털 제어기
// 시스템 클럭: 200MHz, PWM 주파수: 200kHz, ADC: 12비트, 목표 출력: 2.5V/1A
#include "F28x_Project.h"
#include "IQmathLib.h"
// 제어기 파라미터 (IQ24 고정소수점 형식)
#define VREF _IQ(2.5) // 목표 출력 전압: 2.5V
#define KP _IQ(0.1) // 비례 게인: 0.1 (MATLAB pidTuner로 튜닝, 위상 마진 45°~60°)
#define KI _IQ(1000.0) // 적분 게인: 1000 (위상 마진 45°~60°)
#define TS _IQ(0.000005) // 샘플링 주기: 5us (200kHz PWM 동기화)
#define ADC_VREF _IQ(3.3) // ADC 기준 전압: 3.3V (F28379D ADC 기준)
#define ADC_MAX _IQ(4095.0) // 12비트 ADC 최대값 (2^12 - 1)
#define PWM_PERIOD 500 // PWM 주기: 200MHz / (2 * 200kHz) = 500 (Up-Down 모드)
#define DUTY_MIN _IQ(0.1) // 최소 듀티 사이클: 0.1 (MOSFET 보호)
#define DUTY_MAX _IQ(0.9) // 최대 듀티 사이클: 0.9 (안정성 보장)
#define DUTY_INIT _IQ(0.208) // 초기 듀티 사이클: Vout/Vin = 2.5/12 (손실 미고려)
#define IREF _IQ(1.0) // 목표 피크 전류: 1A
#define SHUNT_R _IQ(0.1) // 션트 저항: 0.1Ω (전류 측정용)
#define SLOPE_COMP _IQ(0.01) // Slope compensation: 0.01 V/us (m_c > 0.5 * (Vin - Vout) / L)
#define V_OVP _IQ(2.75) // 과전압 보호 임계값: 2.5V + 10%
#define I_OCP _IQ(1.5) // 과전류 보호 임계값: 1.5A
#define SOFT_START_TIME _IQ(0.01) // 소프트 스타트 시간: 10ms
#define SOFT_START_STEPS 2000 // 소프트 스타트 스텝 수: 10ms / 5us = 2000
// 전역 변수: 상태 모니터링 및 제어
volatile _iq Vout = _IQ(0.0); // 측정 출력 전압 (IQ24, ADC 변환 결과)
volatile _iq Iout = _IQ(0.0); // 측정 인덕터 전류 (IQ24, 션트 저항 기준)
volatile _iq error = _IQ(0.0); // 전압 오차 (Vref - Vout)
volatile _iq duty = _IQ(0.0); // 현재 듀티 사이클 (소프트 스타트 초기 0)
volatile _iq error_prev = _IQ(0.0); // 이전 오차 (PI 제어용)
volatile _iq duty_prev = _IQ(0.0); // 이전 듀티 사이클 (PI 제어용)
volatile Uint16 error_count = 0; // ADC 에러 카운터 (디버깅용)
volatile Uint16 system_state = 0; // 시스템 상태: 0(STOP), 1(RUN), 2(FAULT)
volatile Uint16 soft_start_count = 0; // 소프트 스타트 카운터
volatile _iq duty_target = DUTY_INIT; // 목표 듀티 사이클 (소프트 스타트용)
// CLA 전용 변수: CPU-CLA 메모리 공유 (F28379D CLA Data RAM)
#pragma DATA_SECTION(CLA_Vout, "Cla1DataRam0");
#pragma DATA_SECTION(CLA_Iout, "Cla1DataRam0");
#pragma DATA_SECTION(CLA_error, "Cla1DataRam0");
#pragma DATA_SECTION(CLA_duty, "Cla1DataRam0");
volatile _iq CLA_Vout, CLA_Iout, CLA_error, CLA_duty;
// 함수 선언
void initSystem(void); // 시스템 클럭, PIE, CLA 초기화
void initGPIO(void); // GPIO 설정 (PWM, ADC, UART, 스위치)
void initADC(void); // ADC 설정 (ADCA 모듈, Vout/Iout 샘플링)
void initPWM(void); // ePWM1 설정 (200kHz Up-Down)
void initCMPSS(void); // CMPSS1 설정 (전류 루프, 내부 DAC)
void initCLA(void); // CLA 설정 (PI 및 전류 루프 연산 오프로드)
void initUART(void); // SCIA 설정 (115200 baud, RUN/STOP 명령)
void initInterrupts(void); // 인터럽트 설정 (ADCINT1, CLA Task 1, SCIA RX)
void scia_xmit(_iq data); // UART 데이터 전송 (Vout, Iout)
void scia_xmit_status(Uint16 status); // UART 상태 전송 (STOP, RUN, FAULT)
void softStart(void); // 소프트 스타트 (듀티 선형 증가)
void checkProtection(void); // OVP/OCP 보호 확인
void updateSystemState(Uint16 new_state); // 시스템 상태 업데이트
__interrupt void adc_isr(void); // ADC ISR (Vout, Iout 샘플링)
__interrupt void cla_task1_isr(void); // CLA ISR (PI 및 전류 루프)
__interrupt void scia_rx_isr(void); // UART RX ISR (명령 처리)
// 시스템 초기화: 200MHz 클럭, PIE, CLA 설정
void initSystem(void) {
EALLOW;
// 시스템 클럭 설정 (F28379D: 200MHz, PLL 사용)
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0; // PLL 비활성화
ClkCfgRegs.SYSCLKSRCSEL.all = 0; // 내부 오실레이터 선택
ClkCfgRegs.SYSPLLMULT.all = 20; // 10MHz * 20 = 200MHz
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 1; // PLL 활성화
while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1); // PLL 락 대기
ClkCfgRegs.SYSCLKDIVSEL.all = 0; // SYSCLK = PLL / 1 = 200MHz
// PIE 초기화
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // PIE 활성화
// CLA 클럭 활성화
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // 내부 오실레이터
ClkCfgRegs.LOSPCP.all = 0; // CLA 클럭 = SYSCLK / 1 = 200MHz
EDIS;
}
// GPIO 초기화: ePWM1, ADCA, SCIA 핀 설정
void initGPIO(void) {
EALLOW;
// ePWM1A (GPIO0), ePWM1B (GPIO1)
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B
// ADCA0 (GPIO28), ADCA1 (GPIO29)
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 0; // ADCA0 (Vout)
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0; // ADCA1 (Iout)
// SCIA TX (GPIO43), RX (GPIO42)
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 1; // SCIA TX
GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 1; // SCIA RX
GpioCtrlRegs.GPBDIR.bit.GPIO43 = 1; // TX 출력
GpioCtrlRegs.GPBDIR.bit.GPIO42 = 0; // RX 입력
EDIS;
}
// ADC 초기화: ADCA 모듈, 12비트, ePWM1 트리거, Vout/Iout 샘플링
void initADC(void) {
EALLOW;
// ADCA 클럭 설정 (SYSCLK / 4 = 50MHz)
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // ADC 클럭 = 200MHz / 4
// ADC 모드 설정: 12비트, 인터럽트 펄스 위치
AdcaRegs.ADCCTL1.bit.ADCBGPWD = 1; // 버퍼 활성화
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // ADC 전원 활성화
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // EOC 후 인터럽트
// SOC0: 채널 A0 (Vout), ePWM1 SOCA 트리거
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // A0 선택
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 15; // 샘플링 창: 15 SYSCLK
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // ePWM1 SOCA 트리거
// SOC1: 채널 A1 (Iout), ePWM1 SOCA 트리거
AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; // A1 선택
AdcaRegs.ADCSOC1CTL.bit.ACQPS = 15; // 샘플링 창: 15 SYSCLK
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 5; // ePWM1 SOCA 트리거
// ADCINT1: SOC1 완료 시 트리거
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1; // SOC1 EOC
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // ADCINT1 활성화
EDIS;
}
// PWM 초기화: ePWM1, 200kHz, Up-Down 카운팅
void initPWM(void) {
EALLOW;
// ePWM1 클럭 활성화 (SYSCLK = 200MHz)
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0; // ePWM 클럭 = SYSCLK
// ePWM1 설정: 200kHz, Up-Down 모드
EPwm1Regs.TBCTL.bit.CTRMODE = 2; // Up-Down 모드
EPwm1Regs.TBCTL.bit.PHSEN = 0; // 위상 동기화 비활성화
EPwm1Regs.TBCTL.bit.PRDPERIOD = PWM_PERIOD; // 주기: 500 (200kHz)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 고속 클럭 분주: 1
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주: 1
// PWM 동작 설정
EPwm1Regs.AQCTLA.bit.ZRO = 2; // Zero: High
EPwm1Regs.AQCTLA.bit.CAU = 1; // CMPA Up: Low
EPwm1Regs.AQCTLA.bit.CAD = 2; // CMPA Down: High
EPwm1Regs.CMPA.bit.CMPA = 0; // 초기 듀티: 0
// SOCA 트리거: ADC 트리거용
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 활성화
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // Zero 시 SOCA 발생
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 매 주기 SOCA 발생
EDIS;
}
// CMPSS 초기화: CMPSS1, 내부 DAC, PCMC 전류 루프
void initCMPSS(void) {
EALLOW;
// CMPSS1 활성화
Cmpss1Regs.COMPCTL.bit.COMPDACE = 1; // 비교玩笑
System: // 비교기 활성화
Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // 내부 DAC 사용
Cmpss1Regs.COMPDACCTL.bit.DACSOURCE = 0; // DAC 값 설정
// 초기 DAC 값: Iref * Rshunt * (4095/3.3)
Cmpss1Regs.DACHVALS.bit.DACVAL = (Uint16)(_IQtoF(_IQmpy(IREF, SHUNT_R)) * ADC_MAX / _IQtoF(ADC_VREF));
Cmpss1Regs.COMPCTL.bit.ASYNCHEN = 1; // 비동기 출력 (PWM 트리거)
// CMPSS-PWM 연결 (F28379D의 Trip Zone 설정)
EPwm1Regs.DCTRIPSEL.bit.DCAEVT1SEL = 0; // CMPSS1 High 선택
EPwm1Regs.TZCTL.bit.DCAEVT1 = 2; // DCAEVT1 발생 시 PWM OFF
EDIS;
}
// CLA 초기화: CLA Task 1 설정, PI 및 전류 루프 연산
void initCLA(void) {
EALLOW;
// CLA Task 1 설정
Cla1Regs.MVECT1 = (Uint16)((Uint32)&cla_task1_isr); // Task 1 ISR
Cla1Regs.MCTL1.bit.IACKE = 1; // 인터럽트 활성화
Cla1Regs.MIER.bit.INT1 = 1; // Task 1 인터럽트 활성화
// CLA 메모리 설정
Cla1Regs.MMEMCFG.bit.RAM0E = 1; // Cla1DataRam0 활성화
EDIS;
}
// UART 초기화: SCIA, 115200 baud, RUN/STOP 명령 수신
void initUART(void) {
EALLOW;
SciaRegs.SCICCR.all = 0x0007; // 1 stop bit, No parity, 8-bit 데이터
SciaRegs.SCICTL1.all = 0x0003; // TX, RX 활성화
SciaRegs.SCIHBAUD.all = 0x0000; // Baud rate 상위 비트
SciaRegs.SCILBAUD.all = 216; // 115200 baud: 200MHz / (115200 * 8) - 1
SciaRegs.SCICTL2.bit.RXBKINTENA = 1; // RX 인터럽트 활성화
SciaRegs.SCICTL2.bit.TXINTENA = 1; // TX 인터럽트 활성화 (효율성 개선)
SciaRegs.SCIFFTX.all = 0xE040; // TX FIFO 활성화, 리셋
SciaRegs.SCIFFRX.all = 0x2044; // RX FIFO 리셋, 에러 클리어
SciaRegs.SCICTL1.all = 0x0023; // SW reset 해제
EDIS;
}
// UART 데이터 전송: Vout, Iout (mV, mA 단위)
void scia_xmit(_iq data) {
Uint16 val = (Uint16)(_IQtoF(data) * 1000); // IQ24를 mV/mA로 변환
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // TX 버퍼 비어질 때까지 대기
SciaRegs.SCITXBUF.all = val; // 데이터 전송
}
// UART 상태 전송: 시스템 상태 (0: STOP, 1: RUN, 2: FAULT, 0xFF: ADC 에러)
void scia_xmit_status(Uint16 status) {
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // TX 버퍼 대기
SciaRegs.SCITXBUF.all = status; // 상태 전송
}
// 소프트 스타트: 듀티 사이클을 0에서 목표값까지 선형 증가
void softStart(void) {
if (soft_start_count < SOFT_START_STEPS) {
// 듀티 증가: duty = (soft_start_count / SOFT_START_STEPS) * duty_target
duty = _IQmpy(_IQdiv(_IQ(soft_start_count), _IQ(SOFT_START_STEPS)), duty_target);
// 소프트 스타트 중 듀티 제한 (안정성 보장)
if (duty > DUTY_MAX) duty = DUTY_MAX;
if (duty < DUTY_MIN) duty = DUTY_MIN;
EPwm1Regs.CMPA.bit.CMPA = (Uint16)(_IQmpy(duty, _IQ(PWM_PERIOD))); // IQmath 최적화
soft_start_count++; // 카운터 증가
} else {
duty = duty_target; // 목표 듀티 도달
EPwm1Regs.CMPA.bit.CMPA = (Uint16)(_IQmpy(duty, _IQ(PWM_PERIOD)));
}
}
// 보호 기능: OVP, OCP 확인 및 PWM 비활성화
void checkProtection(void) {
// 과전압(2.75V) 또는 과전류(1.5A) 발생 시 FAULT 상태로 전환
if (_IQtoF(Vout) > _IQtoF(V_OVP) || _IQtoF(Iout) > _IQtoF(I_OCP)) {
updateSystemState(2); // FAULT 상태로 전환
EALLOW;
EPwm1Regs.TBCTL.bit.CTRMODE = 3; // PWM 비활성화 (정지 모드)
EPwm1Regs.CMPA.bit.CMPA = 0; // 듀티 0
EPwm1Regs.CMPB.bit.CMPB = 0; // Low-Side MOSFET 듀티 0
EDIS;
soft_start_count = 0; // 소프트 스타트 리셋
duty = _IQ(0.0); // 듀티 초기화
duty_prev = _IQ(0.0); // 이전 듀티 초기화
}
// FAULT 상태에서 조건 해소 시 STOP 상태로 복구
else if (system_state == 2 && _IQtoF(Vout) <= _IQtoF(V_OVP) && _IQtoF(Iout) <= _IQtoF(I_OCP)) {
updateSystemState(0); // STOP 상태로 복구
}
}
// 시스템 상태 업데이트: RUN/STOP/FAULT 전환 및 UART 전송
void updateSystemState(Uint16 new_state) {
if (new_state == system_state) return; // 동일 상태면 무시
system_state = new_state; // 상태 업데이트
EALLOW;
if (system_state == 1) { // RUN
EPwm1Regs.TBCTL.bit.CTRMODE = 2; // PWM 활성화 (Up-Down 모드)
soft_start_count = 0; // 소프트 스타트 초기화
duty = _IQ(0.0); // 듀티 초기화
} else { // STOP or FAULT
EPwm1Regs.TBCTL.bit.CTRMODE = 3; // PWM 비활성화
EPwm1Regs.CMPA.bit.CMPA = 0; // 듀티 0
EPwm1Regs.CMPB.bit.CMPB = 0; // Low-Side MOSFET 듀티 0
soft_start_count = 0; // 소프트 스타트 리셋
duty = _IQ(0.0); // 듀티 초기화
duty_prev = _IQ(0.0); // 이전 듀티 초기화
}
EDIS;
scia_xmit_status(system_state); // 상태를 UART로 전송
}
// 인터럽트 초기화: ADCINT1, CLA Task 1, SCIA RX 설정
void initInterrupts(void) {
EALLOW;
PieVectTable.ADCA1_INT = &adc_isr; // ADCINT1 ISR: ADCA 모듈
PieVectTable.CLA1_1_INT = &cla_task1_isr; // CLA Task 1 ISR
PieVectTable.SCIA_RX_INT = &scia_rx_isr; // SCIA RX ISR
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADCINT1 활성화 (그룹 1)
PieCtrlRegs.PIEIER11.bit.INTx1 = 1; // CLA 인터럽트 활성화 (그룹 11)
PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // SCIA RX 인터럽트 활성화 (그룹 9)
IER |= M_INT1 | M_INT9 | M_INT11; // CPU 인터럽트 그룹 1, 9, 11 활성화
EDIS;
}
// ADC ISR: ADCA 모듈로 Vout, Iout 샘플링, 보호 및 소프트 스타트 처리
__interrupt void adc_isr(void) {
// Vout = ADCARESULT0 * (3.3V / 4095)
Vout = _IQmpy(_IQ(AdcaRegs.ADCRESULT0), _IQdiv(ADC_VREF, ADC_MAX));
// Iout = ADCARESULT1 * (3.3V / (4095 * 0.1Ω))
Iout = _IQmpy(_IQ(AdcaRegs.ADCRESULT1), _IQdiv(ADC_VREF, _IQmpy(ADC_MAX, SHUNT_R)));
// 입력 범위 확인: Vout(0~3.3V), Iout(0~2A)
if (_IQtoF(Vout) < 0.0f || _IQtoF(Vout) > 3.3f || _IQtoF(Iout) < 0.0f || _IQtoF(Iout) > 2.0f) {
error_count++; // 에러 카운터 증가
scia_xmit_status(0xFF); // 에러 로그 전송 (0xFF: ADC 에러)
updateSystemState(2); // 즉시 FAULT 상태로 전환
Vout = _IQ(0.0); // 기본값 설정
Iout = _IQ(0.0);
}
CLA_Vout = Vout; // CLA로 Vout 전달
CLA_Iout = Iout; // CLA로 Iout 전달
// 보호 기능 확인: OVP(2.75V), OCP(1.5A)
checkProtection();
// RUN 상태에서만 소프트 스타트 및 CLA 트리거
if (system_state == 1) {
softStart(); // 소프트 스타트 처리
Cla1Regs.MIFRC.bit.INT1 = 1; // CLA Task 1 트리거
}
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // ADCINT1 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 1 ACK
}
// CLA ISR: PI 제어기 및 PCMC 전류 루프 연산
__interrupt void cla_task1_isr(void) {
if (system_state != 1) return; // RUN 상태가 아니면 연산 중지
// 오차 계산: e[n] = Vref - Vout
CLA_error = VREF - CLA_Vout;
// 이산 PI 제어기: u[n] = u[n-1] + 0.1025 e[n] - 0.0975 e[n-1]
CLA_duty = duty_prev + _IQmpy(_IQ(0.1025), CLA_error) - _IQmpy(_IQ(0.0975), error_prev);
// Anti-windup: 듀티 제한 시 적분 항 초기화
if (CLA_duty > DUTY_MAX || CLA_duty < DUTY_MIN) {
CLA_duty = (CLA_duty > DUTY_MAX) ? DUTY_MAX : DUTY_MIN;
error_prev = _IQ(0.0); // 적분기 포화 방지
}
// Slope compensation: I_comp = Iref * Rshunt - m_c * t
_iq slope_comp = _IQmpy(SLOPE_COMP, TS);
_iq t_ratio = _IQdiv(_IQ(Cla1Regs.MTBCTR), _IQ(PWM_PERIOD)); // CLA 타이머 사용
_iq I_comp = _IQmpy(IREF, SHUNT_R) - _IQmpy(slope_comp, t_ratio);
// CMPSS DAC 동적 업데이트
Cmpss1Regs.DACHVALS.bit.DACVAL = (Uint16)(_IQtoF(I_comp) * ADC_MAX / _IQtoF(ADC_VREF));
// 전류 루프: 인덕터 전류가 I_comp 이하일 때 PWM OFF
if (_IQtoF(CLA_Iout) <= _IQtoF(I_comp)) {
EPwm1Regs.AQCSFRC.bit.CSFA = 2; // High-Side PWM OFF
EPwm1Regs.AQCSFRC.bit.CSFB = 1; // Low-Side PWM ON
} else {
EPwm1Regs.AQCSFRC.bit.CSFA = 0; // 정상 동작 복구
EPwm1Regs.AQCSFRC.bit.CSFB = 0;
}
// 전압 루프: 소프트 스타트 완료 후 PWM 듀티 업데이트
if (soft_start_count >= SOFT_START_STEPS) {
EPwm1Regs.CMPA.bit.CMPA = (Uint16)(_IQmpy(CLA_duty, _IQ(PWM_PERIOD))); // IQmath 최적화
}
error_prev = CLA_error; // 이전 오차 저장
duty_prev = CLA_duty; // 이전 듀티 저장
Cla1Regs.MIRUN.bit.INT1 = 0; // CLA 인터럽트 클리어
}
// UART RX ISR: RUN('R'), STOP('S') 명령 처리
__interrupt void scia_rx_isr(void) {
Uint16 rx_data = SciaRegs.SCIRXBUF.all; // 수신 데이터 읽기
if (rx_data == 'R' && system_state == 0) {
updateSystemState(1); // RUN 상태로 전환
} else if (rx_data == 'S' && system_state == 1) {
updateSystemState(0); // STOP 상태로 전환
}
SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1; // 오버플로우 플래그 클리어
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // RX 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; // PIE 그룹 9 ACK
}
7. 시뮬레이션 및 검증
7.1 MATLAB/Simulink 시뮬레이션
- PCMC:
- Simscape: \( L = 33 \mu H \), \( C = 10 \mu F \), \( R = 2.5 \Omega \).
- Discrete Transfer Function: [0.1025, -0.0975], [1, -1].
- Slope compensation: \( m_c = 0.01 V/\mu s \).
- 테스트: 부하 스텝 (0.5A → 1A), 전압 스텝 (2.5V → 3V), 소프트 스타트 (10ms).
- 기준:
- 리플: \( \Delta V_{out} \leq 25mV \)
- 과도 응답: \(\leq 100\mu s\)
- 위상 마진: \(\geq 45^\circ\)
- OVP: \( V_{out} \leq 2.75V \), OCP: \( I_{out} \leq 1.5A \).
7.2 하드웨어 테스트
- 장비: F28379D LaunchPad, 커스터마이징된 동기 정류 Buck 보드, 오실로스코프, 전원 공급기 (12V, 2A).
- 절차:
- CCS v12로 빌드/플래시.
- Simulink External Mode로 \( K_p \), \( K_i \), \( I_{ref} \) 튜닝.
- UART로 \( V_{out}, I_{out} \), 상태 모니터링 ('R'/'S' 명령 전송).
- 외부 스위치(GPIO4)로 RUN/STOP 테스트.
- 소프트 스타트, OVP, OCP 동작 확인.
- 기준:
- \( V_{out} = 2.5V \pm 25mV \).
- 위상 마진 \(\geq 45^\circ\).
- 과도 응답 \(\leq 100\mu s\).
- 소프트 스타트: 10ms 내 안정화.
8. 참고 자료
- TI 문서: TIDM-DC-DC-BUCK, SLUA416, SPRUHM8I, C2000Ware Digital Power SDK.
- MATLAB: Control System Toolbox, C2000 Microcontroller Blockset.
- 도구: powerSUITE, Code Composer Studio v12.
'Power Electronics > DC-DC변환' 카테고리의 다른 글
TI C2000 DSP를 사용한 PSFB 컨버터 2차측 동기 정류 디지털 제어기 설계 (2) | 2025.08.26 |
---|---|
TI C2000 DSP를 사용한 LLC 풀-브릿지 컨버터 2차측 동기 정류 디지털 제어기 설계 (0) | 2025.08.26 |
TI C2000 DSP를 사용한 Boost 컨버터 디지털 제어기 설계-PCMC (0) | 2025.08.26 |
TI C2000 DSP를 사용한 Buck 컨버터 디지털 제어기 설계-VMC (0) | 2025.08.26 |
양방향 전력 전송 공진형 CLLC 컨버터 설계 절차 (1) | 2025.08.21 |
PSFB(Phase-Shifted Full-Bridge) 컨버터 설계 절차 (0) | 2025.08.19 |
양방향 전력 전송 공진형 CLLC 컨버터 설계 절차 및 제어기 분석 (2) | 2025.08.19 |
Half-Bridge LLC 공진 컨버터 설계 절차 (1) | 2025.08.11 |