소개 (Introduction)
PSFB (Phase-Shift Full-Bridge) 컨버터는 고전력 DC-DC 변환에 적합하며, 위상 천이 PWM과 ZVS(Zero Voltage Switching)를 통해 효율을 극대화합니다 (The PSFB converter is ideal for high-power DC-DC conversion, maximizing efficiency with phase-shift PWM and ZVS). 이 글에서는 TMS320F28335를 사용한 실무 수준의 제어 코드를 제공하며, 상세한 레지스터 설정, 수식 기반 설정값, PID 제어, 보호 기능, CAN/UART 통신을 다룹니다 (This article provides practical control code for the TMS320F28335, covering detailed register settings, formula-based configurations, PID control, protection features, and CAN/UART communication). LEVEL 매크로를 통해 단계별 검증이 가능하다 (The LEVEL macro enables step-by-step verification).
1. PSFB 컨버터 설계 절차 (PSFB Converter Design Process)
1.1 설계 사양 (Design Specifications)
실무에서 PSFB 컨버터 설계는 구체적인 사양 정의로 시작됩니다 (In practice, PSFB converter design begins with defining detailed specifications):
- 입력 전압 (Vin, Input Voltage): 360V~440V (±10%)
- 출력 전압 (Vo, Output Voltage): 48V ±1%
- 출력 전력 (Po, Output Power): 2kW (정격, Rated), 2.4kW (120% 과부하, Overload, 10초, 10 seconds)
- 스위칭 주파수 (fsw, Switching Frequency): 50kHz
- 효율 (Efficiency): ≥96% (정격, Rated), ≥90% (10% 경부하, Light Load)
- 보호 기능 (Protection Features): OVP(52V), OCP(50A), OTP(85°C/90°C), UVLO(350V)
- 통신 (Communication): CAN 2.0B, UART
- 환경 (Environment): -20°C~60°C, IP54, 공냉 (Air Cooling)
1.2 주요 구성 요소 (Key Components)
- 입력 풀 브릿지 (Input Full-Bridge): Infineon IPW60R041C6 (600V, 77A, Rds(on)=41mΩ)
- 변압기 (Transformer): 7:1 턴 비율 (Turn Ratio), 10µH 누설 인덕턴스 (Leakage Inductance)
- 출력 정류기 (Output Rectifier): IRFP4568 (150V, 171A)
- 출력 필터 (Output Filter): LC 필터 (47µH, 100µF)
- 제어기 (Controller): TMS320F28335 (150MHz)
- 센서 (Sensors): LEM LV 25-P(전압, Voltage), ACS758(전류, Current), NTC 10kΩ(온도, Temperature)
- 드라이버 (Driver): UCC21520 (4kV 절연, Isolation)
1.3 변압기 설계 (Transformer Design)
변압기는 전력 전달과 ZVS의 핵심입니다 (The transformer is critical for power transfer and ZVS):
- 턴 비율 (Turn Ratio): \( N = \frac{V_{in,min}}{V_o} = \frac{360}{48} \approx 7:1 \)
- 코어 (Core): EER42/20 (PC40), \( A_e = 194mm^2 \)
- 누설 인덕턴스 (Leakage Inductance): 10µH
- 주 인덕턴스 (Magnetizing Inductance): \( L_m = \frac{V_{in,min} \cdot D_{max}}{f_{sw} \cdot \Delta I_m} \approx 1.44mH \)
1.4 출력 필터 설계 (Output Filter Design)
- 인덕터 (Inductor): \( L = \frac{V_o \cdot (1-D_{eff})}{f_{sw} \cdot \Delta I_L} \approx 47 \mu H \)
- 커패시터 (Capacitor): \( C = \frac{\Delta I_L}{8 \cdot f_{sw} \cdot \Delta V_o} \approx 100 \mu F \)
1.5 제어 전략 (Control Strategy)
- ZVS: 누설 인덕턴스와 MOSFET \( C_{oss} \) 활용 (Utilizes leakage inductance and MOSFET \( C_{oss} \))
- PID: 전압 루프 (Voltage Loop) (KP=0.6, KI=0.02, KD=0.01), 전류 제한 (Current Limit) (KP=0.4, KI=0.015)
- 소프트 스타트 (Soft Start): 100ms 램프업 (Ramp-Up)
- 보호 (Protection): OVP, OCP, OTP, UVLO
2. 제어 코드 (Control Code)
2.1 코드 개요 (Code Overview)
아래 코드는 TMS320F28335를 사용한 PSFB 컨버터 제어 코드로, 위상 천이 PWM, PID 제어, 보호 기능, CAN/UART 통신을 포함합니다 (The following code is for PSFB converter control using TMS320F28335, including phase-shift PWM, PID control, protection features, and CAN/UART communication). 레지스터 설정은 수식 기반으로 계산되었으며, LEVEL 매크로로 단계별 검증을 지원합니다 (Register settings are calculated using formulas, and the LEVEL macro supports step-by-step verification).
2.2 코드 (Code)
#include "DSP28x_Project.h"
#include "IQmathLib.h"
// 시스템 상수 정의 (System Constants)
// SYSCLK: 150MHz, PLL = 30MHz * 5 (SPRU812, 6.3절)
// PWM_FREQ: 50kHz, PSFB 스위칭 주파수 (Switching frequency for FSFB)
// TBPRD: PWM 주기 = SYSCLK / (2 * f_sw) = 150e6 / (2 * 50e3) = 1500
#define LEVEL 6 // 검증 레벨: 1(초기화) ~ 6(통신) (Verification Level: 1(Initialization) ~ 6(Communication))
#define SYSCLK 150e6 // 시스템 클럭: 150MHz (System Clock: 150MHz)
#define PWM_FREQ 50e3 // PWM 주파수: 50kHz (PWM Frequency: 50kHz)
#define TBPRD (SYSCLK / (2 * PWM_FREQ)) // PWM 주기: 1500 (PWM Period: 1500)
// DEADTIME: 200ns, ZVS 보장, 계산: 200e-9 * 150e6 = 30 (200ns for ZVS, Calculation: 200e-9 * 150e6 = 30)
#define DEADTIME 30 // 데드타임: 200ns (Dead Time: 200ns)
#define V_REF _IQ(48.0) // 기준 전압: 48V (Reference Voltage: 48V)
#define I_MAX _IQ(50.0) // 최대 전류: 50A (Maximum Current: 50A)
#define V_MAX _IQ(52.0) // 최대 전압: 52V (Maximum Voltage: 52V)
#define V_MIN _IQ(350.0) // 최소 입력 전압: 350V (Minimum Input Voltage: 350V)
#define TEMP_MAX _IQ(85.0) // 경고 온도: 85°C (Warning Temperature: 85°C)
#define TEMP_SHUTDOWN _IQ(90.0) // 셧다운 온도: 90°C (Shutdown Temperature: 90°C)
#define SOFT_START_TIME 100 // 소프트 스타트: 100ms (Soft Start: 100ms)
#define MAX_PHASE 600 // 최대 위상 천이: TBPRD * 0.4 (Maximum Phase Shift: TBPRD * 0.4)
// PID 파라미터, Ziegler-Nichols 기반 (PID Parameters, Ziegler-Nichols Based)
#define KP_V _IQ(0.6) // 전압 비례 게인 (Voltage Proportional Gain)
#define KI_V _IQ(0.02) // 전압 적분 게인 (Voltage Integral Gain)
#define KD_V _IQ(0.01) // 전압 미분 게인 (Voltage Derivative Gain)
#define KP_I _IQ(0.4) // 전류 비례 게인 (Current Proportional Gain)
#define KI_I _IQ(0.015) // 전류 적분 게인 (Current Integral Gain)
// 전역 변수 (Global Variables)
_iq feedback_voltage = 0; // 출력 전압: ADC A0, 20:1 분압 (Output Voltage: ADC A0, 20:1 Divider)
_iq feedback_current = 0; // 출력 전류: ADC A1, ACS758 (Output Current: ADC A1, ACS758)
_iq feedback_temp = 0; // 온도: ADC A2, NTC 10kΩ (Temperature: ADC A2, NTC 10kΩ)
_iq input_voltage = 0; // 입력 전압: ADC A3, 200:1 분압 (Input Voltage: ADC A3, 200:1 Divider)
_iq error_v = 0; // 전압 오차: V_REF - feedback_voltage (Voltage Error)
_iq integral_v = 0; // 전압 적분 (Voltage Integral)
_iq deriv_v = 0; // 전압 미분 (Voltage Derivative)
_iq prev_error_v = 0; // 이전 전압 오차 (Previous Voltage Error)
_iq error_i = 0; // 전류 오차: I_MAX - feedback_current (Current Error)
_iq integral_i = 0; // 전류 적분 (Current Integral)
_iq phase_shift = 0; // 위상 천이 값: EPWM2 조절 (Phase Shift Value: EPWM2 Control)
Uint16 fault_flag = 0; // 오류 플래그: OVP=0x01, OCP=0x02, OTP=0x04, UVLO=0x08, EXT=0x10 (Fault Flags)
Uint32 soft_start_counter = 0; // 소프트 스타트 카운터 (Soft Start Counter)
Uint16 soft_start_active = 1; // 소프트 스타트 플래그 (Soft Start Flag)
char debug_buffer[64]; // UART 디버깅 버퍼 (UART Debug Buffer)
// 함수 프로토타입 (Function Prototypes)
void InitSystem(void); // 시스템 초기화 (System Initialization)
void InitAdc(void); // ADC 초기화 (ADC Initialization)
void InitPwm(void); // PWM 초기화 (PWM Initialization)
void InitCan(void); // CAN 초기화 (CAN Initialization)
void InitUart(void); // UART 초기화 (UART Initialization)
interrupt void adc_isr(void); // ADC 인터럽트 (ADC Interrupt)
void update_pid(void); // PID 제어 (PID Control)
void check_protection(void); // 보호 기능 (Protection Functions)
void send_can_status(void); // CAN 상태 전송 (CAN Status Transmission)
void log_error(Uint16); // 오류 로깅 (Error Logging)
void log_status(void); // 상태 로깅 (Status Logging)
void main(void)
{
// 시스템 초기화 (LEVEL_1): 클럭, GPIO, 인터럽트 설정 (System Initialization: Clock, GPIO, Interrupts)
// SPRU812, 6.3절 참조 (Refer to SPRU812, Section 6.3)
#if LEVEL >= 1
InitSysCtrl(); // SYSCLK 150MHz 설정, PLL: 30MHz * 5 (Set SYSCLK to 150MHz, PLL: 30MHz * 5)
InitSystem(); // GPIO, 인터럽트 설정 (GPIO, Interrupt Setup)
#endif
// ADC 초기화 (LEVEL_2): 전압, 전류, 온도, 입력 전압 센싱 (ADC Initialization: Voltage, Current, Temperature, Input Voltage Sensing)
#if LEVEL >= 2
InitAdc(); // ADC 설정, PWM 트리거 동기화 (ADC Setup, PWM Trigger Synchronization)
#endif
// PWM 초기화 (LEVEL_3): 위상 천이 PWM, 50kHz (PWM Initialization: Phase-Shift PWM, 50kHz)
#if LEVEL >= 3
InitPwm(); // EPWM1/2 설정, 200ns 데드타임 (EPWM1/2 Setup, 200ns Dead Time)
#endif
// 통신 초기화 (LEVEL_6): CAN, UART 설정 (Communication Initialization: CAN, UART Setup)
#if LEVEL >= 6
InitCan(); // CAN 500kbps 설정 (CAN 500kbps Setup)
InitUart(); // UART 9600 baud 설정 (UART 9600 baud Setup)
#endif
// 인터럽트 활성화 (LEVEL_2 이상) (Interrupt Enable, LEVEL_2 and Above)
// SPRU566, 2절 참조 (Refer to SPRU566, Section 2)
#if LEVEL >= 2
EALLOW;
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADC INT1 활성화 (Enable ADC INT1)
IER |= M_INT1; // CPU 인터럽트 그룹 1 활성화 (Enable CPU Interrupt Group 1)
EINT; // 글로벌 인터럽트 활성화 (Enable Global Interrupts)
EDIS;
#endif
// 메인 루프: 오류 처리 및 상태 전송 (Main Loop: Error Handling and Status Transmission)
// 주의: 오류 발생 시 PWM 정지 (Note: PWM stops on error)
for(;;)
{
if (fault_flag)
{
#if LEVEL >= 3
EALLOW;
EPwm1Regs.TBCTL.bit.SWFSYNC = 0; // EPWM1 정지 (Stop EPWM1)
EPwm2Regs.TBCTL.bit.SWFSYNC = 0; // EPWM2 정지 (Stop EPWM2)
EDIS;
#endif
#if LEVEL >= 6
log_error(fault_flag); // UART 오류 출력 (UART Error Output)
send_can_status(); // CAN 오류 전송 (CAN Error Transmission)
#endif
}
else
{
#if LEVEL >= 6
log_status(); // UART 상태 출력 (UART Status Output)
send_can_status(); // CAN 상태 전송 (CAN Status Transmission)
#endif
}
}
}
void InitSystem(void)
{
// 시스템 초기화 (LEVEL_1): GPIO 및 인터럽트 설정 (System Initialization: GPIO and Interrupt Setup)
// 목적: PWM 출력, 오류 입력, 상태 LED 설정 (Purpose: Configure PWM outputs, error input, status LED)
// 하드웨어: GPIO0~3 (EPWM1A/B, EPWM2A/B), GPIO34 (오류 입력), GPIO32 (LED) (Hardware: GPIO0~3 for EPWM1A/B, EPWM2A/B, GPIO34 for error input, GPIO32 for LED)
// SPRU812, 6.3절 참조 (Refer to SPRU812, Section 6.3)
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.EPWM1A = 1; // GPIO0: EPWM1A, 레그 1 상단 MOSFET (Leg 1 Upper MOSFET)
GpioCtrlRegs.GPAMUX1.bit.EPWM1B = 1; // GPIO1: EPWM1B, 레그 1 하단 MOSFET (Leg 1 Lower MOSFET)
GpioCtrlRegs.GPAMUX2.bit.EPWM2A = 1; // GPIO2: EPWM2A, 레그 2 상단 MOSFET (Leg 2 Upper MOSFET)
GpioCtrlRegs.GPAMUX2.bit.EPWM2B = 1; // GPIO3: EPWM2B, 레그 2 하단 MOSFET (Leg 2 Lower MOSFET)
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO34: 외부 오류 입력, 저전위 활성화 (External Error Input, Active Low)
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 0; // 입력 설정 (Input Configuration)
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // GPIO32: 상태 LED (Status LED)
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1; // 출력 설정 (Output Configuration)
GpioDataRegs.GPBCLEAR.bit.GPIO32 = 1;// LED 초기 OFF (LED Initially OFF)
EDIS;
}
void InitAdc(void)
{
// ADC 초기화 (LEVEL_2): 4채널 센싱 (ADC Initialization: 4-Channel Sensing)
// 목적: PWM 동기화로 전압, 전류, 온도, 입력 전압 읽기 (Purpose: Read voltage, current, temperature, and input voltage with PWM synchronization)
// 하드웨어: A0(출력 전압, 20:1 분압), A1(전류, ACS758), A2(온도, NTC), A3(입력 전압, 200:1 분압)
// (Hardware: A0(Output Voltage, 20:1 Divider), A1(Current, ACS758), A2(Temperature, NTC), A3(Input Voltage, 200:1 Divider))
// SPRU812, 10절 참조 (Refer to SPRU812, Section 10)
// 계산: ADCCLK = SYSCLK / 2^ADCCLKPS = 150e6 / 2^1 = 75MHz (Calculation: ADCCLK = SYSCLK / 2^ADCCLKPS = 150e6 / 2^1 = 75MHz)
EALLOW;
AdcRegs.ADCTRL1.bit.ACQ_PS = 0x1; // 샘플링 윈도우: 1 SYSCLK, 약 6.67ns (Sampling Window: 1 SYSCLK, ~6.67ns)
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 순차 샘플링: 4채널 변환 (Sequential Sampling: 4-Channel Conversion)
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; // A0: 출력 전압 (Output Voltage)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; // A1: 출력 전류 (Output Current)
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; // A2: 온도 (Temperature)
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; // A3: 입력 전압 (Input Voltage)
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1; // ADC 클럭: 75MHz (ADC Clock: 75MHz)
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // PWM 트리거: EPWM1 SOCA (PWM Trigger: EPWM1 SOCA)
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // ADC 인터럽트 활성화 (ADC Interrupt Enable)
EDIS;
}
void InitPwm(void)
{
// PWM 초기화 (LEVEL_3): 위상 천이 PWM, 50kHz, 200ns 데드타임 (PWM Initialization: Phase-Shift PWM, 50kHz, 200ns Dead Time)
// 목적: 풀 브릿지 레그 1(EPWM1)과 레그 2(EPWM2) 설정 (Purpose: Configure Full-Bridge Leg 1 (EPWM1) and Leg 2 (EPWM2))
// 하드웨어: EPWM1A/B(레그 1), EPWM2A/B(레그 2), UCC21520 드라이버 (Hardware: EPWM1A/B (Leg 1), EPWM2A/B (Leg 2), UCC21520 Driver)
// SPRU566, 3절 참조 (Refer to SPRU566, Section 3)
// 계산: TBPRD = SYSCLK / (2 * f_sw) = 150e6 / (2 * 50e3) = 1500 (Calculation: TBPRD = SYSCLK / (2 * f_sw) = 150e6 / (2 * 50e3) = 1500)
// 데드타임: DEADTIME = 200e-9 * 150e6 = 30 (Dead Time: 200e-9 * 150e6 = 30)
EALLOW;
EPwm1Regs.TBPRD = TBPRD; // PWM 주기: 1500, 50kHz (PWM Period: 1500, 50kHz)
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 업다운 카운트: 대칭 PWM (Up-Down Count: Symmetric PWM)
EPwm1Regs.CMPA.bit.CMPA = TBPRD / 2; // 초기 듀티 50% (Initial Duty Cycle 50%)
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // 카운터 0에서 PWM1A 세트 (Set PWM1A at Counter Zero)
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // CMPA에서 PWM1A 클리어 (Clear PWM1A at CMPA)
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 데드타임 활성화 (Dead Time Enable)
EPwm1Regs.DBRED = DEADTIME; // 상승 데드타임: 200ns (Rising Dead Time: 200ns)
EPwm1Regs.DBFED = DEADTIME; // 하강 데드타임: 200ns (Falling Dead Time: 200ns)
EPwm2Regs.TBPRD = TBPRD; // 동일 주기 (Same Period)
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm2Regs.TBPHS.bit.TBPHS = 0; // 초기 위상: 0 (Initial Phase: 0)
EPwm2Regs.CMPA.bit.CMPA = TBPRD / 2; // 초기 듀티 50% (Initial Duty Cycle 50%)
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm2Regs.DBRED = DEADTIME;
EPwm2Regs.DBFED = DEADTIME;
EDIS;
}
void InitCan(void)
{
// CAN 초기화 (LEVEL_6): 500kbps 상태 전송 (CAN Initialization: 500kbps Status Transmission)
// 목적: 전압, 전류, 오류 상태 전송 (Purpose: Transmit voltage, current, error status)
// 하드웨어: SN65HVD230 트랜시버, GPIO30(RX), GPIO31(TX) (Hardware: SN65HVD230 Transceiver, GPIO30(RX), GPIO31(TX))
// SPRU566, 7절 참조 (Refer to SPRU566, Section 7)
// 계산: BRP = SYSCLK / (BaudRate * (1 + TSEG1 + TSEG2)) = 150e6 / (500e3 * (1 + 5 + 4)) = 30
// (Calculation: BRP = SYSCLK / (BaudRate * (1 + TSEG1 + TSEG2)) = 150e6 / (500e3 * (1 + 5 + 4)) = 30)
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO30 = 1; // GPIO30: CANRX
GpioCtrlRegs.GPBMUX1.bit.GPIO31 = 1; // GPIO31: CANTX
ECanaRegs.CANME.all = 0; // 메일박스 비활성화 (Disable Mailboxes)
ECanaRegs.CANMD.bit.MD0 = 0; // 메일박스 0: 송신 (Mailbox 0: Transmit)
ECanaRegs.CANMIM.all = 0; // 인터럽트 마스크 비활성화 (Disable Interrupt Mask)
ECanaRegs.CANBTC.bit.BRPREG = 29; // 비트 레이트: 500kbps, BRP=30-1 (Bit Rate: 500kbps, BRP=30-1)
ECanaRegs.CANBTC.bit.TSEG1REG = 4; // TSEG1: 5 TQ
ECanaRegs.CANBTC.bit.TSEG2REG = 3; // TSEG2: 4 TQ
ECanaRegs.CANME.bit.ME0 = 1; // 메일박스 0 활성화 (Enable Mailbox 0)
EDIS;
}
void InitUart(void)
{
// UART 초기화 (LEVEL_6): 9600 baud 디버깅 (UART Initialization: 9600 baud Debugging)
// 목적: 상태 및 오류를 PC 터미널로 출력 (Purpose: Output status and errors to PC terminal)
// 하드웨어: SCI-A, GPIO28(TX), GPIO29(RX) (Hardware: SCI-A, GPIO28(TX), GPIO29(RX))
// SPRU566, 9절 참조 (Refer to SPRU566, Section 9)
// 계산: Baud = SYSCLK / (16 * (SCIHBAUD * 256 + SCILBAUD)) = 150e6 / (16 * 243) ≈ 9600
// (Calculation: Baud = SYSCLK / (16 * (SCIHBAUD * 256 + SCILBAUD)) = 150e6 / (16 * 243) ≈ 9600)
EALLOW;
SciaRegs.SCICCR.all = 0x0007; // 1 stop bit, No parity, 8-bit 데이터 (1 Stop Bit, No Parity, 8-bit Data)
SciaRegs.SCICTL1.all = 0x0003; // TX, RX 활성화 (Enable TX, RX)
SciaRegs.SCIHBAUD = 0x0000; // Baud rate: 9600
SciaRegs.SCILBAUD = 0x00F3; // SCILBAUD = 243
SciaRegs.SCICTL1.all = 0x0023; // 릴레이 활성화 (Enable Relay)
EDIS;
}
interrupt void adc_isr(void)
{
// ADC 인터럽트 (LEVEL_2 이상): 50kHz 제어 루프 (ADC Interrupt, LEVEL_2 and Above: 50kHz Control Loop)
// 목적: ADC 데이터 읽기, PID 제어, 보호, 통신 처리 (Purpose: Read ADC data, PID control, protection, communication)
// 주의: ISR 실행 시간 < 20µs (50kHz 주기) (Note: ISR execution time < 20µs for 50kHz cycle)
#if LEVEL >= 2
// ADC 값 읽기 및 스케일링 (Read and Scale ADC Values)
// 계산: Vout = ADCRESULT * (3.3V / 4096) * 분압비 (Calculation: Vout = ADCRESULT * (3.3V / 4096) * Divider Ratio)
feedback_voltage = _IQ(AdcRegs.ADCRESULT0 * 3.3 / 4096.0 * 20.0); // A0: 출력 전압 (Output Voltage)
feedback_current = _IQ(AdcRegs.ADCRESULT1 * 3.3 / 4096.0 * 100.0); // A1: 출력 전류 (Output Current)
feedback_temp = _IQ(AdcRegs.ADCRESULT2 * 3.3 / 4096.0 * 100.0); // A2: 온도 (Temperature)
input_voltage = _IQ(AdcRegs.ADCRESULT3 * 3.3 / 4096.0 * 200.0); // A3: 입력 전압 (Input Voltage)
#if LEVEL >= 5
check_protection(); // 보호 기능 확인 (Check Protection Functions)
#endif
if (!fault_flag)
{
#if LEVEL >= 4
// 소프트 스타트: 100ms 동안 위상 천이 선형 증가 (Soft Start: Linear phase shift increase over 100ms)
if (soft_start_active)
{
soft_start_counter++;
// 계산: phase_shift = (counter / (SOFT_START_TIME * PWM_FREQ / 1000)) * MAX_PHASE
// (Calculation: phase_shift = (counter / (SOFT_START_TIME * PWM_FREQ / 1000)) * MAX_PHASE)
phase_shift = _IQdiv(_IQ(soft_start_counter), _IQ(SOFT_START_TIME * PWM_FREQ / 1000)) * _IQ(MAX_PHASE);
if (soft_start_counter >= SOFT_START_TIME * PWM_FREQ / 1000)
{
soft_start_active = 0; // 소프트 스타트 종료 (End Soft Start)
#if LEVEL >= 6
log_status(); // 완료 로그 (Log Completion)
#endif
}
}
else
{
update_pid(); // PID 제어 (PID Control)
}
#endif
#if LEVEL >= 3
EALLOW;
EPwm2Regs.TBPHS.bit.TBPHS = _IQtoF(phase_shift); // EPWM2 위상 업데이트 (Update EPWM2 Phase)
EDIS;
#endif
}
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // ADC 인터럽트 플래그 클리어 (Clear ADC Interrupt Flag)
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // PIE 그룹 1 ACK
#endif
}
void update_pid(void)
{
// PID 제어 (LEVEL_4): 전압/전류 안정화 (PID Control, LEVEL_4: Voltage/Current Stabilization)
// 목적: 출력 전압 48V 유지, 전류 50A 이하 제한 (Purpose: Maintain 48V output voltage, limit current to 50A)
// 수학: output_v = KP*error + KI*integral + KD*deriv
#if LEVEL >= 4
error_v = V_REF - feedback_voltage; // 전압 오차 (Voltage Error)
integral_v += error_v; // 적분 업데이트 (Update Integral)
if (integral_v > _IQ(1000)) integral_v = _IQ(1000); // Windup 방지 (Prevent Windup)
if (integral_v < _IQ(-1000)) integral_v = _IQ(-1000);
deriv_v = error_v - prev_error_v; // 미분 계산 (Calculate Derivative)
prev_error_v = error_v; // 이전 오차 저장 (Store Previous Error)
_iq output_v = _IQmpy(KP_V, error_v) + _IQmpy(KI_V, integral_v) + _IQmpy(KD_V, deriv_v);
if (feedback_current > I_MAX)
{
error_i = I_MAX - feedback_current; // 전류 오차 (Current Error)
integral_i += error_i; // 전류 적분 (Current Integral)
if (integral_i > _IQ(500)) integral_i = _IQ(500); // Windup 방지 (Prevent Windup)
if (integral_i < _IQ(-500)) integral_i = _IQ(-500);
output_v = _IQmpy(KP_I, error_i) + _IQmpy(KI_I, integral_i);
}
phase_shift = output_v;
if (phase_shift > _IQ(MAX_PHASE)) phase_shift = _IQ(MAX_PHASE); // 상한 제한 (Upper Limit)
if (phase_shift < _IQ(0)) phase_shift = _IQ(0); // 하한 제한 (Lower Limit)
#endif
}
void check_protection(void)
{
// 보호 기능 (LEVEL_5): OVP, OCP, OTP, UVLO, 외부 오류 (Protection Functions, LEVEL_5: OVP, OCP, OTP, UVLO, External Error)
// 목적: 시스템 안전 보장 (Purpose: Ensure system safety)
#if LEVEL >= 5
fault_flag = 0;
if (feedback_voltage > V_MAX) fault_flag |= 0x01; // OVP
if (feedback_current > I_MAX) fault_flag |= 0x02; // OCP
if (feedback_temp > TEMP_MAX)
{
fault_flag |= 0x04; // OTP 경고 (OTP Warning)
if (feedback_temp > TEMP_SHUTDOWN) fault_flag |= 0x08; // OTP 셧다운 (OTP Shutdown)
}
if (input_voltage < V_MIN) fault_flag |= 0x10; // UVLO
if (GpioDataRegs.GPBDAT.bit.GPIO34 == 0) fault_flag |= 0x20; // 외부 오류 (External Error)
GpioDataRegs.GPBDAT.bit.GPIO32 = fault_flag ? 1 : 0; // LED 상태 (LED Status)
#endif
}
void send_can_status(void)
{
// CAN 상태 전송 (LEVEL_6): 전압, 전류, 오류 (CAN Status Transmission, LEVEL_6: Voltage, Current, Error)
// 포맷: MDL(전압), MDH(전류 16비트, 오류 16비트) (Format: MDL(Voltage), MDH(Current 16-bit, Error 16-bit))
#if LEVEL >= 6
EALLOW;
ECanaMboxes.MBOX0.MDL.all = _IQtoF(feedback_voltage);
ECanaMboxes.MBOX0.MDH.all = (_IQtoF(feedback_current) << 16) | fault_flag;
ECanaRegs.CANTRS.all = 0x00000001;
while (ECanaRegs.CANTRS.bit.TRS0);
EDIS;
#endif
}
void log_error(Uint16 fault)
{
// 오류 로깅 (LEVEL_6): UART로 오류 출력 (Error Logging, LEVEL_6: UART Error Output)
#if LEVEL >= 6
Uint16 i;
sprintf(debug_buffer, "Fault: 0x%04X, V: %.2fV, I: %.2fA, T: %.2fC\r\n",
fault, _IQtoF(feedback_voltage), _IQtoF(feedback_current), _IQtoF(feedback_temp));
for (i = 0; debug_buffer[i] != '\0'; i++)
{
SciaRegs.SCITXBUF = debug_buffer[i];
while (SciaRegs.SCICTL2.bit.TXRDY == 0);
}
#endif
}
void log_status(void)
{
// 상태 로깅 (LEVEL_6): UART로 상태 출력, 1초 주기 (Status Logging, LEVEL_6: UART Status Output, 1s Period)
#if LEVEL >= 6
static Uint32 log_counter = 0;
log_counter++;
if (log_counter >= PWM_FREQ)
{
Uint16 i;
sprintf(debug_buffer, "Status: V=%.2fV, I=%.2fA, T=%.2fC, Phase=%ld\r\n",
_IQtoF(feedback_voltage), _IQtoF(feedback_current), _IQtoF(feedback_temp), _IQtoF(phase_shift));
for (i = 0; debug_buffer[i] != '\0'; i++)
{
SciaRegs.SCITXBUF = debug_buffer[i];
while (SciaRegs.SCICTL2.bit.TXRDY == 0);
}
log_counter = 0;
}
#endif
}
2.3 코드 설명 (Code Explanation)
- LEVEL 매크로 (LEVEL Macro): 단계별 검증 (Step-by-step verification: 1=Initialization, 2=ADC, 3=PWM, 4=PID, 5=Protection, 6=Communication)
- 레지스터 설정 (Register Settings):
- GPIO: PWM 핀(GPAMUX1), 오류 입력/LED(GPBMUX1) (PWM Pins (GPAMUX1), Error Input/LED (GPBMUX1))
- ADC: ADCCLK = 75MHz, 4채널 순차 변환 (ADCCLK = 75MHz, 4-Channel Sequential Conversion)
- PWM: TBPRD = 1500, 데드타임 = 200ns (TBPRD = 1500, Dead Time = 200ns)
- CAN: 500kbps, BRP=30, TSEG1=5, TSEG2=4
- UART: 9600 baud, SCILBAUD=243
- 검증 절차 (Verification Process):
- LEVEL_1: LED 점멸 확인 (Verify LED blinking)
- LEVEL_2: UART로 ADC 데이터 확인 (Verify ADC data via UART)
- LEVEL_3: PWM 파형 확인 (Verify PWM waveform)
- LEVEL_4: 48V 출력 확인 (Verify 48V output)
- LEVEL_5: 보호 기능 테스트 (Test protection functions)
- LEVEL_6: CAN/UART 통신 확인 (Verify CAN/UART communication)
3. 실무 적용 팁 (Practical Application Tips)
3.1 디버깅 (Debugging)
- 도구 (Tools): Code Composer Studio, PuTTY, 오실로스코프 (Code Composer Studio, PuTTY, Oscilloscope)
- 방법 (Method): ADC 값, PWM 파형, PID 응답 확인 (Check ADC values, PWM waveforms, PID response)
3.2 테스트 (Testing)
- 부하 스텝 (Load Step): 10%~100%, 리플 < 0.48V (10% to 100%, Ripple < 0.48V)
- 열 테스트 (Thermal Test): 60°C, 2kW, 8시간 (60°C, 2kW, 8 hours)
- EMC: CISPR 11 Class A 준수 (Comply with CISPR 11 Class A)
3.3 최적화 (Optimization)
- 효율 (Efficiency): 동기 정류, 저 ESR 커패시터, 96.5% 목표 (Synchronous rectification, low ESR capacitors, 96.5% target)
- 데드타임 (Dead Time): \( t_{dead} = k \cdot \sqrt{L_{leak} \cdot C_{oss}} \)
- PID 튜닝 (PID Tuning): Ziegler-Nichols 방법 (Ziegler-Nichols Method)
4. 참고 자료 (References)
- TMS320F28335 Technical Reference Manual
- C2000 Peripheral Guide
- IEEE 논문: "Phase-Shifted Full-Bridge Converter Design" (IEEE Paper: "Phase-Shifted Full-Bridge Converter Design")
- TI C2000Ware
5. 결론 (Conclusion)
이 글은 PSFB 컨버터 설계와 TMS320F28335 기반 제어 코드를 상세히 다뤘습니다 (This article covers PSFB converter design and TMS320F28335-based control code in detail). 레지스터 설정은 수식 기반으로 계산되었으며, 상세 주석과 LEVEL 매크로로 실무 적용성을 높였습니다 (Register settings are calculated using formulas, with detailed comments and LEVEL macros for practical application).
주의: 이 문서와 코드는 설계 참고용입니다. 실무 적용 시 하드웨어, 부하 조건, 안전 규정을 고려하여 철저히 검증하고 조정해야 합니다.(Caution: This document and code are for reference only. For practical applications, validate and adjust thoroughly based on hardware, load conditions, and safety regulations.)
'MCU > C2000' 카테고리의 다른 글
TMS320F28388D DSP eQEP 사용법: DriverLib API로 eQEP 설정 및 코드 (0) | 2025.08.17 |
---|---|
TMS320F28388D DSP eCAP 사용법: DriverLib API로 eCAP 설정 및 코드 (1) | 2025.08.17 |
TMS320F28388D DSP ePWM 사용법: DriverLib API로 ePWM 설정 및 코드 (0) | 2025.08.16 |
AD2S1210 Resolver-to-Digital Converter with TMS320F28388D Parallel Interface (0) | 2025.08.14 |
TMS320F28335 DSP 기반 Half-Bridge LLC 공진 컨버터 설계 및 제어 코드 가이드 (0) | 2025.08.09 |
TMS320F28388D DSP ADC 사용법: DriverLib API로 ADC 설정 및 코드 (0) | 2025.08.08 |
TMS320F28388D DSP CPU 타이머 사용법 : Driverlib API로 CPU 타이머 설정과 예제 (0) | 2025.08.08 |
TMS320F28388D DSP SCI 사용법: Driverlib API로 UART 설정 및 예제 (0) | 2025.08.08 |