一、硬件初始化配置
1. 系统时钟与GPIO配置
#include "DSP28x_Project.h"
void SystemInit(void) {
// 关闭看门狗
DINT;
InitSysCtrl();
// 配置系统时钟为150MHz
InitPllSys(150, 10, 1, 0);
// 配置GPIO为外设功能
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; // ePWM1A设为输入
GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; // ePWM1B设为输入
GpioCtrlRegs.GPADIR.bit.GPIO2 = 0; // ePWM2A设为输入
GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; // ePWM2B设为输入
EDIS;
}
2. ePWM模块初始化(以ePWM1为例)
void EPwm1_Init(uint16_t period, float duty) {
// 1. 时钟分频配置
EPwm1Regs.TBPRD = period - 1; // 周期寄存器(10kHz对应1000)
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 双向计数
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // 主时钟分频
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // 系统时钟分频
// 2. 比较值配置
EPwm1Regs.CMPA.half.CMPA = (uint16_t)(duty * period); // 占空比
EPwm1Regs.CMPB = period - EPwm1Regs.CMPA; // 互补通道
// 3. 动作限定配置
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // A通道递增时置高
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // A通道递减时清零
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // B通道递增时置高
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // B通道递减时清零
// 4. 死区控制(1.5μs)
EPwm1Regs.DBCTL.bit.DBFED = 150; // 上升沿延迟
EPwm1Regs.DBCTL.bit.DBRIS = 1; // 启用死区
// 5. 启动计数器
EPwm1Regs.TBCTL.bit.ENABLE = 1; // 使能计数器
}
二、ADC同步采样配置
1. ADC模块初始化
void Adc_Init(void) {
// 关闭ADC电源
EALLOW;
AdcRegs.ADCCTL1.bit.ADCPWDNZ = 0;
DELAY_US(1000); // 等待电源稳定
AdcRegs.ADCCTL1.bit.ADCPWDNZ = 1; // 上电
// 配置ADC时钟为12MHz(SYSCLK/2)
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // 内部1.2V参考
AdcRegs.ADCCTL1.bit.ADCCLKPS = 0x3; // 分频系数
// 配置通道同步采样(ePWM1触发)
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // 通道0(电压采样)
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // ePWM1触发
AdcRegs.ADCSOC0CTL.bit.ACQPS = 14; // 采样保持时间
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; // 通道1(电流A相)
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5;
AdcRegs.ADCSOC1CTL.bit.ACQPS = 14;
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; // 通道2(电流B相)
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5;
AdcRegs.ADCSOC2CTL.bit.ACQPS = 14;
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; // 通道3(电流C相)
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 5;
AdcRegs.ADCSOC3CTL.bit.ACQPS = 14;
// 启动ADC
AdcRegs.ADCCTL1.bit.ADCEN = 1;
}
三、双闭环控制算法
1. 电压外环PI控制
typedef struct {
float Kp;
float Ki;
float integral;
float output_max;
} PI_Controller;
float Voltage_PI_Control(PI_Controller *pi, float Vref, float Vdc) {
float error = Vref - Vdc;
pi->integral += error;
// 抗积分饱和
if (pi->integral > pi->output_max) pi->integral = pi->output_max;
if (pi->integral < -pi->output_max) pi->integral = -pi->output_max;
return pi->Kp * error + pi->Ki * pi->integral;
}
2. 电流内环PR控制
typedef struct {
float Kp;
float Kr;
float alpha;
} PR_Controller;
float Current_PR_Control(PR_Controller *pr, float Iref, float Ifb, float theta) {
// Park变换
float Id = Iref * cos(theta) + Ifb * sin(theta);
float Iq = -Iref * sin(theta) + Ifb * cos(theta);
// PR调节
float Vd = pr->Kp * Id + pr->Kr * (Id - Iq);
float Vq = pr->Kp * Iq + pr->Kr * (Iq - Id);
// 逆Park变换
return Vd * cos(theta) - Vq * sin(theta);
}
四、中断服务程序(ADC触发)
interrupt void Adc_isr(void) {
// 读取ADC结果(右对齐)
float Vdc = (AdcResult.ADCRESULT0 * 3.3f) / 4096.0f;
float Ia = (AdcResult.ADCRESULT1 * 3.3f) / 4096.0f;
float Ib = (AdcResult.ADCRESULT2 * 3.3f) / 4096.0f;
float Ic = (AdcResult.ADCRESULT3 * 3.3f) / 4096.0f;
// 锁相环计算相位角
static float theta = 0.0f;
theta = SRF_PLL(Va, Vb, Vc, theta); // 基于SRF-PLL的相位同步
// 电流指令生成(单位正弦波)
float Iref_a = Iref * cos(theta);
float Iref_b = Iref * cos(theta - 2*M_PI/3);
float Iref_c = Iref * cos(theta + 2*M_PI/3);
// 电流环控制
float Duty_a = Current_PR_Control(¤t_pr, Iref_a, Ia, theta);
float Duty_b = Current_PR_Control(¤t_pr, Iref_b, Ib, theta);
float Duty_c = Current_PR_Control(¤t_pr, Iref_c, Ic, theta);
// 更新PWM占空比
EPwm1Regs.CMPA.half.CMPA = (uint16_t)(Duty_a * EPwm1Regs.TBPRD);
EPwm2Regs.CMPA.half.CMPA = (uint16_t)(Duty_b * EPwm2Regs.TBPRD);
EPwm3Regs.CMPA.half.CMPA = (uint16_t)(Duty_c * EPwm3Regs.TBPRD);
// 清除中断标志
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
五、锁相环(SRF-PLL)实现
float SRF_PLL(float Va, float Vb, float Vc, float theta_prev) {
// Clark变换到静止坐标系
float alpha = Va;
float beta = (Va + 2*Vb) / sqrt(3);
// Park变换到旋转坐标系
float vd = alpha * cos(theta_prev) + beta * sin(theta_prev);
float vq = -alpha * sin(theta_prev) + beta * cos(theta_prev);
// PI调节器
static float integral = 0.0f;
float error = 0.0f; // 目标vq=0
integral += error;
float omega = Kp_pll * error + Ki_pll * integral;
// 更新相位角
float theta = theta_prev + omega * TS_SAMPLE;
// 角度归一化
if (theta > 2*M_PI) theta -= 2*M_PI;
return theta;
}
六、保护机制实现
1. 过流保护(ePWM Trip-Zone)
void EPwm_TripConfig(void) {
// 配置TZ模块
EPwm1Regs.TZSEL.bit.CBC = 1; // 比较器B触发保护
EPwm1Regs.TZCTL.bit.TZA = 2; // 过流时强制A通道低电平
EPwm1Regs.TZCTL.bit.TZB = 2; // 过流时强制B通道低电平
// 中断配置
EPwm1Regs.TZINTSEL.bit.TZIF = 1; // 使能TZ中断
EPwm1Regs.TZINTFLG.bit.TZIF = 0; // 清除标志
}
interrupt void EPwm_TZ_ISR(void) {
// 快速关断所有PWM
EPwm1Regs.TZCTL.bit.TZA = 2;
EPwm2Regs.TZCTL.bit.TZA = 2;
EPwm3Regs.TZCTL.bit.TZA = 2;
// 记录故障
fault_flag = 1;
// 清除中断标志
EPwm1Regs.TZINTFLG.bit.TZIF = 0;
}
七、主程序流程
void main(void) {
// 系统初始化
SystemInit();
EPwm1_Init(1000, 0.5f); // 10kHz, 50%占空比
Adc_Init();
EPwm_TripConfig();
// 主循环
while(1) {
// 执行后台任务(如通信、数据记录)
}
}
// 中断向量表配置
#pragma CODE_SECTION(Adc_isr, "ramfuncs");
#pragma INTERRUPT(Adc_isr, 1);
参考代码 三相PFC数字控制代码 www.youwenfan.com/contentalh/73162.html
八、调试与验证
示波器观察点:
三相电流波形对称性(THD<5%)
PWM占空比与电流指令的跟随性
直流母线电压纹波(<2% Vdc)
性能测试数据:
| 参数 | 测试条件 | 典型值 |
| ------------ | --------- | ------ |
| 输入功率因数 | 220V/50Hz | 0.998 |
| THD | 1kW负载 | 3.2% |
| 效率 | 额定功率 | 96.5% |
九、扩展功能建议
数字预充电:通过GPIO控制继电器实现预充电回路。
CAN通信:集成CAN模块上传运行状态至上位机。
自适应PI参数:根据负载变化动态调整PI系数。