1. 서론
LLC 공진 컨버터는 절연형 DC-DC 변환기로, 제로 전압 스위칭(ZVS)과 제로 전류 스위칭(ZCS)을 통해 높은 효율을 제공합니다. 풀-브릿지 토폴로지와 2차측 동기 정류(SR)를 사용하여 고전력 애플리케이션에 적합하며, TI의 C2000 DSP(F28379D)는 고속 PWM, ADC, CLA를 활용해 정밀한 디지털 제어를 구현합니다. 본 문서는 LLC 풀-브릿지 컨버터의 2차측 동기 정류 디지털 제어기를 설계하며, 주파수 변조(FM) 제어를 적용합니다. UART를 통한 RUN/STOP 제어, 외부 스위치 입력, 소프트 스타트, 과전압/과전류 보호(OVP/OCP)를 포함합니다.
2. 설계 요구사항
- 입력 전압 (\( V_{in} \)): 300V ~ 400V
- 출력 전압 (\( V_{out} \)): 48V
- 출력 전류 (\( I_{out} \)): 10A
- 스위칭 주파수 (\( f_{sw} \)): 100kHz ~ 200kHz (공진 주파수 \( f_r = 150kHz \))
- 샘플링 주기 (\( T_s \)): 5μs (PWM 동기화)
- 제어 모드: 연속 공진 모드 (CRM)
- 제어 방식: 주파수 변조 (FM) 및 2차측 동기 정류
- 하드웨어 플랫폼: TI Delfino F28379D LaunchPad (200MHz) + 커스터마이징된 LLC 보드
- 성능 목표:
- 출력 전압 리플: \( \Delta V_{out} \leq 480mV \) (1% 이하)
- 과도 응답 시간: \( \leq 200\mu s \) (부하/전압 스텝 응답)
- 위상 마진: 45° ~ 60°
- 대역폭: 약 10kHz (\( f_{sw}/10 \))
- 추가 요구사항:
- ADC: 12비트, 3.3V 기준
- PWM: Phase-Shift 모드, 200MHz 시스템 클럭
- 안정성: 주파수 제한 (80kHz ~ 250kHz), ADC 입력 보호
- 디버깅: UART (SCIA, 115200 baud)로 \( V_{out}, I_{out} \), 상태 모니터링
- 보호: 과전압 (\( V_{out} > 52.8V \)), 과전류 (\( I_{out} > 15A \))
- 기능: UART 명령 ('R'/'S'), 외부 스위치 (GPIO4), 소프트 스타트 (20ms)
- 최적화: CLA로 PI 연산, IQmath로 고정소수점 연산, Pre-warping
3. LLC 설계 절차
LLC 공진 컨버터 설계는 다음 단계를 따르며, 각 단계에서 필요한 수식을 명확히 제시합니다.
3.1 입력/출력 사양 정의
출력 전력 (\( P_{out} \)):
입력 전력 (효율 \( \eta = 0.95 \) 가정):
입력 전류 (최소 입력 전압 \( V_{in,min} = 300V \)):
3.2 트랜스포머 설계
3.2.1 턴 비율 (\( n \))
풀-브릿지 LLC에서 1차측 전압은 입력 전압의 절반으로 작용:
정수비로 조정하여 \( n = 3 \) (3:1) 선택.
3.2.2 이득 곡선 분석
First Harmonic Approximation (FHA)을 사용하여 이득 계산:
최소 이득 (\( V_{in,max} = 400V \)):
최대 이득 (\( V_{in,min} = 300V \)):
이득 곡선 공식:
여기서 \( R = V_{out} / I_{out} = 48 / 10 = 4.8 \, \Omega \).
3.2.3 코어 및 턴 수
코어: ETD49 페라이트 (N87, \( A_e = 2.11 \times 10^{-4} \, \text{m}^2 \), \( l_e = 0.114 \, \text{m} \)).
실용적 턴 수: \( N_1 = 30 \), \( N_2 = 10 \) (n = 3).
3.2.4 자화 인덕턴스 (\( L_m \))
요구사항: \( L_m = 300 \, \mu H \).
에어 갭 (\( l_g \)) 계산:
대입: \( \mu_0 = 4\pi \times 10^{-7} \), \( N_1 = 30 \), \( A_e = 2.11 \times 10^{-4} \, \text{m}^2 \), \( l_e = 0.114 \, \text{m} \), \( \mu_r = 2000 \), \( L_m = 300 \times 10^{-6} \, \text{H} \)
결과: 에어 갭 약 0.8mm로 조정하여 \( L_m \approx 300 \, \mu H \).
3.2.5 와이어 선택
1차측 전류: \( I_{1,rms} \approx 2.38 \, \text{A} \), AWG 20.
2차측 전류: \( I_{2,rms} \approx 6.366 \, \text{A} \), AWG 16.
Litz wire 권장 (스킨 효과 감소).
3.3 공진 탱크 설계
공진 인덕터 (\( L_r \)): 50μH
공진 커패시터 (\( C_r \)): 22nF
공진 주파수 (\( f_r \)):
품질 인자 (\( Q \)):
3.4 출력 커패시터 설계
리플 전압:
안정성을 위해: \( C_{out} = 1000 \, \mu F \) (ESR ≤ 5mΩ, 63V, 예: Panasonic EEH-ZA1J101P).
3.5 스위치 및 정류기
1차측 MOSFET: N-채널, 600V, 20A (TI CSD19536KCS, \( R_{DS(on)} \leq 5m\Omega \)), ePWM1A/B, ePWM2A/B (GPIO0~3).
2차측 SR MOSFET: N-채널, 100V, 50A (TI CSD19535KCS), ePWM3A/B (GPIO4~5), 데드타임 100ns.
게이트 드라이버: UCC27211, 4A 듀얼 채널, 3.3V 로직 호환.
3.6 센싱 및 제어 회로
전압 센싱:
ADC 입력: ADCINA0 (GPIO6), 12비트, 3.3V 기준.
전류 센싱:
ADC 입력: ADCINA1 (GPIO7), CMPSS1 사용. INA240 앰프(옵션, 게인 20: 0.05V → 1V).
외부 스위치: GPIO8, 풀업 10kΩ, Low=RUN, High=STOP.
UART: SCIA, GPIO28(TX), GPIO29(RX), 115200 baud.
3.7 하드웨어 플랫폼
F28379D LaunchPad: 200MHz, 12비트 ADC, 16채널 PWM, CLA.
LLC 보드: 풀-브릿지 MOSFET, SR MOSFET, \( L_r = 50\mu H \), \( C_r = 22nF \), \( L_m = 300\mu H \), \( C_{out} = 1000\mu F \).
외부 장비: 400V/5A 전원, Tektronix TBS2000 오실로스코프, 4.8Ω 부하.
4. 아날로그 모델링
4.1 State-Space 평균화 모델
상태 변수: 공진 전류 (\( i_r \)), 공진 전압 (\( v_{Cr} \)), 자화 전류 (\( i_m \)).
Extended Describing Function (EDF) 모델:
매트릭스 형태:
4.2 소신호 모델
FM 소신호 전달 함수:
4.3 MATLAB 모델링
% LLC 컨버터 플랜트 모델
Vout = 48; fr = 150000; Lr = 50e-6; Cr = 22e-9; n = 3; R = 4.8;
Req = 8 * n^2 * R / pi^2;
K = Vout / fr;
Gvf = tf(K, [Lr*Cr, Lr/Req, 1]);
figure; bode(Gvf); grid on;
figure; step(Gvf); grid on;
5. 디지털 제어기 설계
5.1 아날로그 PI 제어기
MATLAB pidTuner로 튜닝: \( K_p = 0.2 \), \( K_i = 2000 \).
5.2 이산화 (Tustin 변환 with Pre-warping)
Pre-warping 주파수: \( \omega_p = 2 \pi \times 10000 = 62831.85 \, \text{rad/s} \).
이산 PI 제어기:
차분 방정식:
Ts = 5e-6;
Gc = tf([0.2 2000], [1 0]);
Gc_d = c2d(Gc, Ts, 'tustin', 'PrewarpFrequency', 2*pi*10000);
[num, den] = tfdata(Gc_d, 'v');
5.3 2차측 SR 설계
CMPSS로 전류 제로 크로싱 감지.
데드타임: 100ns (200MHz에서 20 클럭).
주파수 제한: 80kHz ~ 250kHz.
dead_time = 100e-9;
f_min = 80e3; f_max = 250e3;
t = 0:1e-9:1e-5;
pwm = square(2*pi*150e3*t, 50);
pwm_sr = [zeros(1, dead_time/1e-9) pwm(1:end-dead_time/1e-9)];
plot(t, pwm, t, pwm_sr);
6. TI C2000 DSP 구현
#include "F28x_Project.h" // F28379D 헤더 파일: 시스템 레지스터 및 함수 정의
#include "IQmathLib.h" // 고정소수점 연산을 위한 IQmath 라이브러리
// 상수 정의: 시스템 파라미터 및 제어 설정
#define VREF _IQ(48.0) // 출력 전압 기준값: 48V
#define KP _IQ(0.2) // PI 제어기 비례 게인
#define KI _IQ(2000.0) // PI 제어기 적분 게인
#define TS _IQ(0.000005) // 샘플링 주기: 5us (200kHz)
#define ADC_VREF _IQ(3.3) // ADC 기준 전압: 3.3V
#define ADC_MAX _IQ(4095.0) // 12비트 ADC 최대값: 4095
#define FSW_INIT _IQ(150000.0) // 초기 스위칭 주파수: 150kHz
#define FSW_MIN _IQ(80000.0) // 최소 스위칭 주파수: 80kHz
#define FSW_MAX _IQ(250000.0) // 최대 스위칭 주파수: 250kHz
#define DEAD_TIME _IQ(0.0000001) // 데드타임: 100ns
#define SHUNT_R _IQ(0.005) // 션트 저항: 5mΩ
#define V_OVP _IQ(52.8) // 과전압 보호 임계값: 52.8V
#define I_OCP _IQ(15.0) // 과전류 보호 임계값: 15A
#define SOFT_START_TIME _IQ(0.02) // 소프트 스타트 시간: 20ms
#define SOFT_START_STEPS 4000 // 소프트 스타트 단계 수: 4000
#define ERROR_COUNT_MAX 10 // 최대 에러 카운터 임계값
// 전역 변수: 시스템 상태 및 제어 변수
volatile _iq g_Vout = _IQ(0.0); // 현재 출력 전압 (IQ 포맷)
volatile _iq g_Iout = _IQ(0.0); // 현재 출력 전류 (IQ 포맷)
volatile _iq g_error = _IQ(0.0); // PI 제어기 오차
volatile _iq g_fsw = _IQ(0.0); // 현재 스위칭 주파수
volatile _iq g_error_prev = _IQ(0.0); // 이전 오차 (PI 제어용)
volatile _iq g_fsw_prev = _IQ(0.0); // 이전 스위칭 주파수
volatile Uint16 g_error_count = 0; // ADC 에러 카운터
volatile Uint16 g_system_state = 0; // 시스템 상태 (0: STOP, 1: RUN, 2: FAULT)
volatile Uint16 g_soft_start_count = 0; // 소프트 스타트 카운터
volatile _iq g_fsw_target = FSW_INIT; // 목표 스위칭 주파수
// 이동 평균 필터용 변수
#define FILTER_SIZE 4
volatile _iq g_Vout_buffer[FILTER_SIZE];
volatile _iq g_Iout_buffer[FILTER_SIZE];
volatile Uint16 g_filter_index = 0;
// CLA 메모리 할당: 고속 연산을 위한 CLA 데이터
#pragma DATA_SECTION(CLA_Vout, "Cla1DataRam0"); // CLA용 출력 전압
#pragma DATA_SECTION(CLA_Iout, "Cla1DataRam0"); // CLA용 출력 전류
#pragma DATA_SECTION(CLA_error, "Cla1DataRam0"); // CLA용 오차
#pragma DATA_SECTION(CLA_fsw, "Cla1DataRam0"); // CLA용 스위칭 주파수
volatile _iq CLA_Vout, CLA_Iout, CLA_error, CLA_fsw;
// 시스템 초기화: 클럭, 인터럽트, 메모리 설정
void initSystem(void) {
InitSysCtrl(); // 시스템 클럭 및 PLL 초기화 (200MHz)
DINT; // 글로벌 인터럽트 비활성화
InitPieCtrl(); // PIE (Peripheral Interrupt Expansion) 초기화
IER = 0x0000; IFR = 0x0000; // 인터럽트 레지스터 초기화
InitPieVectTable(); // 인터럽트 벡터 테이블 설정
InitCla(); // CLA (Control Law Accelerator) 초기화
}
// GPIO 초기화: PWM, ADC, 외부 스위치, UART 핀 설정
void initGPIO(void) {
EALLOW; // 보호된 레지스터 접근 허용
// PWM 출력 (ePWM1, ePWM2: 1차측, ePWM3: 2차측 SR)
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // ePWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // ePWM1B
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0; // ePWM2A
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; // ePWM2B
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0; // ePWM3A (SR)
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; GpioCtrlRegs.GPADIR.bit.GPIO5 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // ePWM3B (SR)
// ADC 입력 (ADCA 모듈 사용)
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; GpioCtrlRegs.GPADIR.bit.GPIO6 = 0; GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 0; // ADCINA0 (전압)
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 0; GpioCtrlRegs.GPADIR.bit.GPIO7 = 0; GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 0; // ADCINA1 (전류)
// 외부 스위치
GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; GpioCtrlRegs.GPADIR.bit.GPIO8 = 0; GpioCtrlRegs.GPAPUD.bit.GPIO8 = 1; // GPIO8 (RUN/STOP)
// UART (SCIA)
GpioCtrlRegs.GPBMUX1.bit.GPIO28 = 1; GpioCtrlRegs.GPBDIR.bit.GPIO28 = 1; GpioCtrlRegs.GPBPUD.bit.GPIO28 = 0; // SCIA TX
GpioCtrlRegs.GPBMUX1.bit.GPIO29 = 1; GpioCtrlRegs.GPBDIR.bit.GPIO29 = 0; GpioCtrlRegs.GPBPUD.bit.GPIO29 = 1; // SCIA RX
EDIS; // 보호된 레지스터 접근 비활성화
}
// ADC 초기화: ADCA 모듈로 전압/전류 센싱
void initADC(void) {
EALLOW;
AdcaRegs.ADCCTL2.bit.PRESCALE = 8; // ADC 클럭 분주: 200MHz/8 = 25MHz
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0: ADCINA0 (전압 센싱)
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14; // 샘플링 윈도우: 14 클럭
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // 트리거: ePWM1 SOCA
AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; // SOC1: ADCINA1 (전류 센싱)
AdcaRegs.ADCSOC1CTL.bit.ACQPS = 14; // 샘플링 윈도우: 14 클럭
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 5; // 트리거: ePWM1 SOCA
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // 인터럽트: SOC0 완료 시
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // ADC 인터럽트 1 활성화
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 초기화
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // 인터럽트 펄스 위치 설정
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // ADC 전원 활성화
DELAY_US(1000); // ADC 안정화 대기: 1ms
EDIS;
}
// PWM 초기화: 1차측 풀-브릿지 및 2차측 SR PWM 설정
void initPWM(void) {
EALLOW;
// ePWM1 설정 (1차측 풀-브릿지 상단)
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // 업카운트 모드
EPwm1Regs.TBCTL.bit.PHSEN = 1; // 페이즈 동기화 활성화
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // 고속 클럭 분주: 200MHz
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 클럭 분주: 1
EPwm1Regs.TBPRD = (Uint16)(200e6 / (2 * _IQtoF(FSW_INIT))); // 주기: 150kHz
EPwm1Regs.CMPA.bit.CMPA = EPwm1Regs.TBPRD / 2; // 듀티 사이클: 50%
EPwm1Regs.TBCTR = 0; // 타이머 카운터 초기화
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 활성화 (ADC 트리거)
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // SOCA 트리거: 카운터=0
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // SOCA 주기: 매 사이클
EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // 데드밴드 활성화
EPwm1Regs.DBRED.bit.DBRED = (Uint16)(_IQtoF(DEAD_TIME) * 200e6); // 상승 데드타임: 100ns
EPwm1Regs.DBFED.bit.DBFED = (Uint16)(_IQtoF(DEAD_TIME) * 200e6); // 하강 데드타임: 100ns
EPwm1Regs.TBCTL.bit.SYNCOSEL = 0; // 동기화 출력: CTR=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // 프리-런 모드
// ePWM2 설정 (1차측 풀-브릿지 하단)
EPwm2Regs = EPwm1Regs; // ePWM1 설정 복사
EPwm2Regs.TBPHS.bit.TBPHS = 0; // 페이즈 오프셋: 0
// ePWM3 설정 (2차측 SR)
EPwm3Regs = EPwm1Regs; // ePWM1 설정 복사
EPwm3Regs.TBPHS.bit.TBPHS = (Uint16)(EPwm1Regs.TBPRD / 2); // SR 페이즈 오프셋: 180도
EDIS;
}
// CMPSS 초기화: 2차측 SR 전류 제로 크로싱 감지
void initCMPSS(void) {
EALLOW;
Cmpss1Regs.COMPCTL.bit.COMPDACE1 = 1; // 비교기 1 활성화
Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // 하이 사이드 소스: DAC
Cmpss1Regs.COMPDACCTL.bit.DACSOURCE = 0; // DAC 소스: 내부 DAC
Cmpss1Regs.DACHVALS.bit.DACVAL = 0; // DAC 기준: 0V (제로 크로싱)
Cmpss1Regs.COMPCTL.bit.ASYNCHEN = 1; // 비동기 출력 활성화
EDIS;
}
// CLA 초기화: PI 제어 연산을 위한 CLA 설정
void initCLA(void) {
EALLOW;
Cla1Regs.MVECT1 = (Uint16)((Uint32)&cla_task1_isr); // CLA 태스크 1 인터럽트 벡터
Cla1Regs.MCTL.bit.IACKE = 1; // CLA 인터럽트 활성화
Cla1Regs.MIER.bit.MINT1 = 1; // 태스크 1 인터럽트 활성화
EDIS;
}
// UART 초기화: 디버깅 및 상태 모니터링 (115200 baud)
void initUART(void) {
EALLOW;
SciaRegs.SCICCR.all = 0x0007; // 8비트 데이터, 패리티 없음, 1 스톱 비트
SciaRegs.SCICTL1.all = 0x0023; // 송수신 활성화, SWRESET
SciaRegs.SCIHBAUD.all = 0x0000; // Baud rate: 115200 (200MHz 기준)
SciaRegs.SCILBAUD.all = 216; // Baud rate 설정
SciaRegs.SCICTL2.bit.RXBKINTENA = 1; // 수신 인터럽트 활성화
SciaRegs.SCIFFTX.bit.TXFIFORST = 1; // 송신 FIFO 리셋
SciaRegs.SCIFFRX.bit.RXFIFORST = 1; // 수신 FIFO 리셋
SciaRegs.SCIFFTX.bit.TXFFIENA = 1; // 송신 FIFO 인터럽트 활성화
SciaRegs.SCIFFRX.bit.RXFFIENA = 1; // 수신 FIFO 인터럽트 활성화
EDIS;
}
// UART 데이터 전송: 전압/전류 데이터 전송
void scia_xmit(_iq data) {
Uint16 val = (Uint16)(_IQtoF(data) * 1000); // IQ 포맷을 정수로 변환 (mV 단위)
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // 송신 버퍼가 비어질 때까지 대기
SciaRegs.SCITXBUF.all = val; // 데이터 전송
}
// UART 상태 전송: 시스템 상태 전송
void scia_xmit_status(Uint16 status) {
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // 송신 버퍼가 비어질 때까지 대기
SciaRegs.SCITXBUF.all = status; // 상태 전송 (0: STOP, 1: RUN, 2: FAULT)
}
// 이동 평균 필터: ADC 입력 노이즈 감소
_iq movingAverageFilter(_iq new_value, volatile _iq *buffer) {
buffer[g_filter_index] = new_value;
g_filter_index = (g_filter_index + 1) % FILTER_SIZE;
_iq sum = _IQ(0.0);
Uint16 i;
for (i = 0; i < FILTER_SIZE; i++) {
sum = _IQmpy(sum, buffer[i]);
}
return _IQdiv(sum, _IQ(FILTER_SIZE));
}
// 소프트 스타트: 부팅 시 전류 충격 방지를 위한 주파수 점진적 감소
void softStart(void) {
if (g_soft_start_count < SOFT_START_STEPS) { // 소프트 스타트 진행 중
g_fsw = FSW_MAX - _IQmpy(_IQdiv(_IQ(g_soft_start_count), _IQ(SOFT_START_STEPS)), (FSW_MAX - g_fsw_target));
Uint16 prd = (Uint16)(200e6 / (2 * _IQtoF(g_fsw))); // PWM 주기 계산
EPwm1Regs.TBPRD = prd; EPwm1Regs.CMPA.bit.CMPA = prd / 2; // ePWM1 업데이트
EPwm2Regs.TBPRD = prd; EPwm2Regs.CMPA.bit.CMPA = prd / 2; // ePWM2 업데이트
EPwm3Regs.TBPRD = prd; EPwm3Regs.CMPA.bit.CMPA = prd / 2; // ePWM3 업데이트
g_soft_start_count++; // 카운터 증가
} else {
g_fsw = g_fsw_target; // 목표 주파수로 전환
Uint16 prd = (Uint16)(200e6 / (2 * _IQtoF(g_fsw))); // 최종 PWM 주기
EPwm1Regs.TBPRD = prd; EPwm1Regs.CMPA.bit.CMPA = prd / 2;
EPwm2Regs.TBPRD = prd; EPwm2Regs.CMPA.bit.CMPA = prd / 2;
EPwm3Regs.TBPRD = prd; EPwm3Regs.CMPA.bit.CMPA = prd / 2;
}
}
// 보호 기능: 과전압/과전류 감지 및 시스템 정지
void checkProtection(void) {
if (_IQtoF(g_Vout) > _IQtoF(V_OVP) || _IQtoF(g_Iout) > _IQtoF(I_OCP)) { // OVP/OCP 조건 확인
updateSystemState(2); // FAULT 상태로 전환
EALLOW;
EPwm1Regs.TBCTL.bit.CTRMODE = 3; EPwm1Regs.CMPA.bit.CMPA = 0; // PWM1 정지
EPwm2Regs.TBCTL.bit.CTRMODE = 3; EPwm2Regs.CMPA.bit.CMPA = 0; // PWM2 정지
EPwm3Regs.TBCTL.bit.CTRMODE = 3; EPwm3Regs.CMPA.bit.CMPA = 0; // PWM3 정지
g_soft_start_count = 0; g_fsw = _IQ(0.0); g_fsw_prev = _IQ(0.0); // 변수 초기화
EDIS;
}
}
// 시스템 상태 업데이트: RUN/STOP/FAULT 상태 관리
void updateSystemState(Uint16 new_state) {
if (new_state == g_system_state) return; // 동일 상태면 무시
g_system_state = new_state; // 상태 업데이트
EALLOW;
if (g_system_state == 1) { // RUN 상태
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // PWM1 활성화
EPwm2Regs.TBCTL.bit.CTRMODE = 0; // PWM2 활성화
EPwm3Regs.TBCTL.bit.CTRMODE = 0; // PWM3 활성화
g_soft_start_count = 0; g_fsw = FSW_MAX; // 소프트 스타트 초기화
} else { // STOP 또는 FAULT
EPwm1Regs.TBCTL.bit.CTRMODE = 3; EPwm1Regs.CMPA.bit.CMPA = 0; // PWM1 정지
EPwm2Regs.TBCTL.bit.CTRMODE = 3; EPwm2Regs.CMPA.bit.CMPA = 0; // PWM2 정지
EPwm3Regs.TBCTL.bit.CTRMODE = 3; EPwm3Regs.CMPA.bit.CMPA = 0; // PWM3 정지
g_soft_start_count = 0; g_fsw = _IQ(0.0); g_fsw_prev = _IQ(0.0); // 변수 초기화
}
EDIS;
scia_xmit_status(g_system_state); // 상태 UART 전송
}
// 인터럽트 초기화: ADC, CLA, UART 인터럽트 설정
void initInterrupts(void) {
EALLOW;
PieVectTable.ADCA1_INT = &adc_isr; // ADC 인터럽트 벡터
PieVectTable.CLA1_1_INT = &cla_task1_isr; // CLA 태스크 1 벡터
PieVectTable.SCIA_RX_INT = &scia_rx_isr; // UART 수신 벡터
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADC 인터럽트 활성화
PieCtrlRegs.PIEIER11.bit.INTx1 = 1; // CLA 인터럽트 활성화
PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // UART 인터럽트 활성화
IER |= M_INT1 | M_INT9 | M_INT11; // CPU 인터럽트 활성화
EDIS;
}
// ADC 인터럽트: 전압/전류 센싱 및 보호 로직
__interrupt void adc_isr(void) {
// SOC 완료 확인
if (AdcaRegs.ADCSOCFLG1.bit.SOC0 && AdcaRegs.ADCSOCFLG1.bit.SOC1) {
_iq Vout_raw = _IQmpy(_IQ(AdcaResultRegs.ADCRESULT0), _IQdiv(ADC_VREF, ADC_MAX));
_iq Iout_raw = _IQmpy(_IQ(AdcaResultRegs.ADCRESULT1), _IQdiv(ADC_VREF, _IQmpy(ADC_MAX, SHUNT_R)));
// 이동 평균 필터 적용
g_Vout = movingAverageFilter(Vout_raw, g_Vout_buffer);
g_Iout = movingAverageFilter(Iout_raw, g_Iout_buffer);
// ADC 입력 범위 검증
if (_IQtoF(g_Vout) < 0.0f || _IQtoF(g_Vout) > 60.0f || _IQtoF(g_Iout) < 0.0f || _IQtoF(g_Iout) > 20.0f) {
g_error_count++;
if (g_error_count >= ERROR_COUNT_MAX) {
g_Vout = _IQ(0.0); g_Iout = _IQ(0.0); // 지속적 오류 시 초기화
}
} else {
g_error_count = 0; // 정상 입력 시 에러 카운터 리셋
}
CLA_Vout = g_Vout; CLA_Iout = g_Iout; // CLA로 데이터 전달
}
checkProtection();
if (g_system_state == 1) {
softStart();
Cla1Regs.MIFRC.bit.INT1 = 1; // CLA 태스크 트리거
}
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // 인터럽트 플래그 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 ACK
}
// CLA 태스크: PI 제어 및 주파수 업데이트
__interrupt void cla_task1_isr(void) {
if (g_system_state != 1) return; // RUN 상태가 아니면 종료
CLA_error = _IQmpy(VREF - CLA_Vout, _IQ(1.0)); // 오차 계산: Vref - Vout
// PI 제어기: u[n] = u[n-1] + 0.205*e[n] - 0.195*e[n-1]
CLA_fsw = g_fsw_prev + _IQmpy(_IQ(0.205), CLA_error) - _IQmpy(_IQ(0.195), g_error_prev);
// 주파수 제한: 80kHz ~ 250kHz
if (CLA_fsw > FSW_MAX) CLA_fsw = FSW_MAX;
if (CLA_fsw < FSW_MIN) CLA_fsw = FSW_MIN;
// 소프트 스타트 완료 후 PWM 업데이트
if (g_soft_start_count >= SOFT_START_STEPS) {
Uint16 prd = (Uint16)(200e6 / (2 * _IQtoF(CLA_fsw))); // PWM 주기 계산
EPwm1Regs.TBPRD = prd; EPwm1Regs.CMPA.bit.CMPA = prd / 2; // ePWM1 업데이트
EPwm2Regs.TBPRD = prd; EPwm2Regs.CMPA.bit.CMPA = prd / 2; // ePWM2 업데이트
EPwm3Regs.TBPRD = prd; EPwm3Regs.CMPA.bit.CMPA = prd / 2; // ePWM3 업데이트
}
Cmpss1Regs.DACHVALS.bit.DACVAL = 0; // SR 제로 크로싱 기준
g_error_prev = CLA_error; g_fsw_prev = CLA_fsw; // 이전 값 업데이트
Cla1Regs.MIRUN.bit.INT1 = 0; // CLA 인터럽트 클리어
}
// UART 수신 인터럽트: 'R' (RUN), 'S' (STOP) 명령 처리
__interrupt void scia_rx_isr(void) {
Uint16 rx_data = SciaRegs.SCIRXBUF.all; // 수신 데이터 읽기
if (rx_data == 'R' && g_system_state == 0) { // 'R' 명령: STOP → RUN
updateSystemState(1);
} else if (rx_data == 'S' && g_system_state == 1) { // 'S' 명령: RUN → STOP
updateSystemState(0);
} else {
scia_xmit_status(0xFFFF); // 잘못된 명령어: 에러 상태 전송
}
SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1; // 오버플로우 클리어
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; // 수신 인터럽트 클리어
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; // PIE 그룹 ACK
}
// 메인 함수: 시스템 초기화 및 메인 루프
void main(void) {
initSystem(); // 시스템 초기화
initGPIO(); // GPIO 설정
initADC(); // ADC 설정
initPWM(); // PWM 설정
initCMPSS(); // CMPSS 설정
initCLA(); // CLA 설정
initUART(); // UART 설정
initInterrupts(); // 인터럽트 설정
EALLOW; EINT; ERTM; EDIS; // 글로벌 인터럽트 활성화
updateSystemState(0); // 초기 상태: STOP
// 이동 평균 필터 버퍼 초기화
Uint16 i;
for (i = 0; i < FILTER_SIZE; i++) {
g_Vout_buffer[i] = _IQ(0.0);
g_Iout_buffer[i] = _IQ(0.0);
}
while(1) { // 메인 루프
// 외부 스위치 (GPIO8)로 RUN/STOP 제어
if (GpioDataRegs.GPADAT.bit.GPIO8 == 0 && g_system_state == 0) {
updateSystemState(1); // Low: RUN
} else if (GpioDataRegs.GPADAT.bit.GPIO8 == 1 && g_system_state == 1) {
updateSystemState(0); // High: STOP
}
// 주기적 상태 모니터링 (100ms 간격)
scia_xmit(g_Vout); scia_xmit(g_Iout); scia_xmit_status(g_system_state);
DELAY_US(100000); // 100ms 대기
}
}
7. 시뮬레이션 및 검증
7.1 MATLAB/Simulink 시뮬레이션
파라미터: \( L_r = 50 \, \mu H \), \( C_r = 22 \, \text{nF} \), \( L_m = 300 \, \mu H \), \( R = 4.8 \, \Omega \).
제어기: Discrete Transfer Function [0.205, -0.195], [1, -1].
테스트: 부하 스텝 (5A → 10A), 전압 스텝 (48V → 50V), 소프트 스타트 (20ms).
기준: 리플 \( \leq 480mV \), 과도 응답 \( \leq 200\mu s \), 위상 마진 \( \geq 45^\circ \).
7.2 하드웨어 테스트
장비: F28379D LaunchPad, LLC 보드, 400V/5A 전원, 오실로스코프, 4.8Ω 부하.
절차:
- CCS v12로 빌드/플래시.
- Simulink External Mode로 \( K_p \), \( K_i \), \( f_{sw} \) 튜닝.
- UART로 \( V_{out}, I_{out} \), 상태 모니터링 ('R'/'S' 명령).
- 외부 스위치 (GPIO8)로 RUN/STOP 테스트.
- 소프트 스타트, OVP, OCP 확인.
기준: \( V_{out} = 48V \pm 480mV \), 위상 마진 \( \geq 45^\circ \), 과도 응답 \( \leq 200\mu s \).
8. 참고 자료
- TI 문서: SPRUHM8I, C2000Ware Digital Power SDK.
- Infineon: "Design Guide for LLC Converter with ICE2HS01G".
- STMicroelectronics: AN2644.
- IEEE 논문: Yang, B., 2003; Lee, J.-B., 2010.
- MATLAB: Power Electronics Control Design, C2000 Microcontroller Blockset.
'Power Electronics > DC-DC변환' 카테고리의 다른 글
TI C2000 DSP를 사용한 양방향 CLLC 컨버터의 디지털 제어기 설계 (1) | 2025.08.27 |
---|---|
TI C2000 DSP를 사용한 PSFB 컨버터 2차측 동기 정류 디지털 제어기 설계 (2) | 2025.08.26 |
TI C2000 DSP를 사용한 Boost 컨버터 디지털 제어기 설계-PCMC (0) | 2025.08.26 |
TI C2000 DSP를 사용한 Buck 컨버터 디지털 제어기 설계-VMC (0) | 2025.08.26 |
TI C2000 DSP를 사용한 Buck 컨버터 디지털 제어기 설계-PCMC (2) | 2025.08.26 |
양방향 전력 전송 공진형 CLLC 컨버터 설계 절차 (1) | 2025.08.21 |
PSFB(Phase-Shifted Full-Bridge) 컨버터 설계 절차 (0) | 2025.08.19 |
양방향 전력 전송 공진형 CLLC 컨버터 설계 절차 및 제어기 분석 (2) | 2025.08.19 |