您好!
我在软件中实现三相整流器的故障保护。保护程序和控制算法均在CPU定时器中断0中运行。
当检测到系统过压、过流时,使用:EPwmxRegs.TZFRC.bit.OST = 1;产生单次触发信号,强制关闭PWM,使对应的ePWMxA和ePWMxB均输出低电平。
使用EPwm1Regs.TZCLR.bit.OST = 1;清除触发信号,使能PWM。
PWM初始化程序如下:
//PWM初始化
void EPwm_Set_up()//用于控制三相逆变器
{
//EPWM1
EPwm1Regs.TBPRD=SP; //设置PWM周期,PWM周期=SP个TB_CLK周期
EPwm1Regs.TBPHS.all=0; //相位寄存器清零
EPwm1Regs.TBCTL.bit.CTRMODE=TB_COUNT_UPDOWN; //增减计数模式
EPwm1Regs.TBCTL.bit.PHSEN=TB_DISABLE; //禁止相位装载功能
EPwm1Regs.TBCTL.bit.PRDLD=TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL=TB_CTR_ZERO; //CTR=ZERO时发出同步信号
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1; //使TB_CLK=100MHz
EPwm1Regs.TBCTL.bit.HSPCLKDIV= TB_DIV1; //使TB_CLK=100MHz
EPwm1Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE=CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm1Regs.CMPCTL.bit.LOADBMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm1Regs.AQCTLA.bit.CAU=AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD=AQ_CLEAR;
EPwm1Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //使能DB子模块
EPwm1Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //死区方式为AHC
EPwm1Regs.DBFED.bit.DBFED=Dead_Time; //Rising Edge Delay
EPwm1Regs.DBRED.bit.DBRED=Dead_Time; //Falling Edge Delay
EALLOW;
EPwm1Regs.TZCTL.bit.TZA=TZ_FORCE_LO; //触发事件发生后,EPWMxA强制为低电平
EPwm1Regs.TZCTL.bit.TZB=TZ_FORCE_LO; //触发事件发生后,EPWMxB强制为低电平
EPwm1Regs.TZFRC.bit.OST=1; //PWM闭锁
EDIS;
//EPWM2
EPwm2Regs.TBPRD=SP; //设置PWM周期,PWM周期=SP个TB_CLK周期
EPwm2Regs.TBPHS.all=0; //相位寄存器清零
EPwm2Regs.TBCTL.bit.CTRMODE=TB_COUNT_UPDOWN; //增减计数模式
EPwm2Regs.TBCTL.bit.PHSEN=TB_ENABLE; //禁止相位装载功能
EPwm2Regs.TBCTL.bit.PRDLD=TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL=TB_SYNC_IN; //接收同步信号
EPwm2Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE=CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm2Regs.CMPCTL.bit.LOADBMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm2Regs.TBCTL.bit.CLKDIV=TB_DIV1; //使TB_CLK=100MHz
EPwm2Regs.TBCTL.bit.HSPCLKDIV= TB_DIV1; //使TB_CLK=100MHz
EPwm2Regs.AQCTLA.bit.CAU=AQ_SET;
EPwm2Regs.AQCTLA.bit.CAD=AQ_CLEAR;
EPwm2Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //使能DB子模块
EPwm2Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //死区方式为AHC
EPwm2Regs.DBFED.bit.DBFED=Dead_Time; //Rising Edge Delay
EPwm2Regs.DBRED.bit.DBRED=Dead_Time; //Falling Edge Delay
EALLOW;
EPwm2Regs.TZCTL.bit.TZA=TZ_FORCE_LO; //触发事件发生后,EPWMxA强制为低电平
EPwm2Regs.TZCTL.bit.TZB=TZ_FORCE_LO; //触发事件发生后,EPWMxB强制为低电平
EPwm2Regs.TZFRC.bit.OST=1; //PWM闭锁
EDIS;
//EPWM3
EPwm3Regs.TBPRD=SP; //设置PWM周期,PWM周期=SP个TB_CLK周期
EPwm3Regs.TBPHS.all=0; //相位寄存器清零
EPwm3Regs.TBCTL.bit.CTRMODE=TB_COUNT_UPDOWN; //增减计数模式
EPwm3Regs.TBCTL.bit.PHSEN=TB_ENABLE; //禁止相位装载功能
EPwm3Regs.TBCTL.bit.PRDLD=TB_SHADOW;
EPwm3Regs.TBCTL.bit.SYNCOSEL=TB_SYNC_IN; //接收同步信号
EPwm3Regs.CMPCTL.bit.SHDWAMODE=CC_SHADOW;
EPwm3Regs.CMPCTL.bit.SHDWBMODE=CC_SHADOW;
EPwm3Regs.CMPCTL.bit.LOADAMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm3Regs.CMPCTL.bit.LOADBMODE=CC_CTR_ZERO; //在CTR=ZERO时装载
EPwm3Regs.TBCTL.bit.CLKDIV=TB_DIV1; //使TB_CLK=100MHz
EPwm3Regs.TBCTL.bit.HSPCLKDIV= TB_DIV1; //使TB_CLK=100MHz
EPwm3Regs.AQCTLA.bit.CAU=AQ_SET;
EPwm3Regs.AQCTLA.bit.CAD=AQ_CLEAR;
EPwm3Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //使能DB子模块
EPwm3Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //死区方式为AHC
EPwm3Regs.DBFED.bit.DBFED=Dead_Time; //Rising Edge Delay
EPwm3Regs.DBRED.bit.DBRED=Dead_Time; //Falling Edge Delay
EALLOW;
EPwm3Regs.TZCTL.bit.TZA=TZ_FORCE_LO; //触发事件发生后,EPWMxA强制为低电平
EPwm3Regs.TZCTL.bit.TZB=TZ_FORCE_LO; //触发事件发生后,EPWMxB强制为低电平
EPwm3Regs.TZFRC.bit.OST=1; //PWM闭锁
EDIS;
}
中断程序如下:
__interrupt void cpu_timer0_isr(void)
{
//用于测试中断中采样和整个控制算法所消耗的时间,高电平持续的时间即是算法执行时间
GpioDataRegs.GPADAT.bit.GPIO20 =1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//清除中断标志位,便于下一次进中断
UartRxMonitorSK(1);//Mudbus RS485串口接收监控
MemCopy2(readFPGA, readFPGA+13, &Data_From_FPGA[0]);
ADIN_A0=(int)Data_From_FPGA[0];//三相电压
ADIN_A1=(int)Data_From_FPGA[1];
ADIN_A2=(int)Data_From_FPGA[2];
ADIN_A3=(int)Data_From_FPGA[3];////三相电流
ADIN_A4=(int)Data_From_FPGA[4];
ADIN_A5=(int)Data_From_FPGA[5];
ADIN_B0=(int)Data_From_FPGA[6];//直流侧电压
ADIN_B1=(int)Data_From_FPGA[7];//超级电容电压
ADIN_B2=(int)Data_From_FPGA[8];//超级电容电流
ADIN_B3=(int)Data_From_FPGA[9];//未使用
ADIN_B4=(int)Data_From_FPGA[10];//未使用
ADIN_B5=(int)Data_From_FPGA[11];//未使用
e_a=(double)(ADIN_A0*0.016458918539);
e_b=(double)(ADIN_A1*0.016458918539);
e_c=(double)(ADIN_A2*0.016458918539);
i_a=(double)(ADIN_A3*0.000462387547348);
i_b=(double)(ADIN_A4*0.000462387547348);
i_c=(double)(ADIN_A5*0.000462387547348);
V_dc=(double)(ADIN_B0*0.027373342803+15.0);
V_o=150.0;//超级电容电压////////////////////////////////////////////////测试
////--------------- 按键与保护程序 --------------------////
if((i_a>15)||(i_a<-15)||(i_b>15)||(i_b<-15)||(i_c>15)||(i_c<-15))
{
Fault_AC_Side_Over_Current=1;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
else
Fault_AC_Side_Over_Current=Fault_AC_Side_Over_Current;
if(V_dc>780)
{
Fault_V_dc_Over_Voltage=1;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
else
Fault_V_dc_Over_Voltage=Fault_V_dc_Over_Voltage;
if(V_dc<550)
{
Fault_V_dc_Under_Voltage=1;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
else
Fault_V_dc_Under_Voltage=Fault_V_dc_Under_Voltage;
if(V_o>170)
{
Fault_V_o_Over_Voltage=1;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
else
Fault_V_o_Over_Voltage=Fault_V_o_Over_Voltage;
if(V_o<80)
{
Fault_V_o_Under_Voltage=1;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
else
Fault_V_o_Under_Voltage=Fault_V_o_Under_Voltage;
if(Key_1==1)//总复位,启动前复位所有故障标志位
{
reset=1;
Fault_AC_Side_Over_Current=0;
Fault_V_dc_Over_Voltage=0;
Fault_V_dc_Under_Voltage=0;
Fault_V_o_Over_Voltage=0;
Fault_V_o_Under_Voltage=0;
LED1_OFF;
LED2_OFF;
}
if((Key_5==1)&&(Fault_AC_Side_Over_Current==0)&&(Fault_V_dc_Over_Voltage==0)\
&&(Fault_V_dc_Under_Voltage==0)&&(Fault_V_o_Over_Voltage==0)&&(Fault_V_o_Under_Voltage==0))
{
Start_AC_DC_Flag=1;
}
else
{
Start_AC_DC_Flag=0;
EALLOW;
EPwm1Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm2Regs.TZFRC.bit.OST=1;//PWM闭锁
EPwm3Regs.TZFRC.bit.OST=1;//PWM闭锁
EDIS;
}
//---------------------- AC/DC控制程序 ------------------------------------///
//if((Start_AC_DC_Flag==1)&&(Start_DAB_Flag==1))
if(Start_AC_DC_Flag==1)
{
//电压外环PI控制器设计
Kp_OuterLoop=0.03;
Ki_OuterLoop=0.01;
V_dc_error=V_dc_reference-V_dc;
V_dc_error_Integral+=V_dc_error;//计算偏差的累加求和,即是积分
if(V_dc_error_Integral>30000000)//积分限幅
V_dc_error_Integral=30000000;
else if(V_dc_error_Integral<-30000000)
V_dc_error_Integral=-30000000;
else
V_dc_error_Integral=V_dc_error_Integral;
id_ref=Kp_OuterLoop*V_dc_error+Ki_OuterLoop*Ts*V_dc_error_Integral;
if(id_ref>15)
id_ref=15;
else if(id_ref<-15)
id_ref=-15;
else
id_ref=id_ref;
//d轴电流控制器设计
// iq_ref=0;
Kp_inerLoop_id=15;//最开始是15
Ki_inerLoop_id=20;//最开始是20
i_d_error=id_ref-i_d;
i_d_error_Integral+=i_d_error;//计算偏差的累加求和,即是积分
if(i_d_error_Integral>500000)
i_d_error_Integral=500000;
else if(i_d_error_Integral<-500000)
i_d_error_Integral=-500000;
else
i_d_error_Integral=i_d_error_Integral;
ud_PIcontroler=Kp_inerLoop_id*i_d_error+Ki_inerLoop_id*Ts*i_d_error_Integral;
//q轴电流控制器设计
Kp_inerLoop_iq=Kp_inerLoop_id;
Ki_inerLoop_iq=Ki_inerLoop_id;
i_q_error=iq_ref-i_q;
i_q_error_Integral+=i_q_error;//计算偏差的累加求和,即是积分
if(i_q_error_Integral>500000)
i_q_error_Integral=500000;
else if(i_q_error_Integral<-500000)
i_q_error_Integral=-500000;
else
i_q_error_Integral=i_q_error_Integral;
uq_PIcontroler=Kp_inerLoop_iq*i_q_error+Ki_inerLoop_iq*Ts*i_q_error_Integral;
//控制器输出Vd,Vq,给SPWM模块进行调制,2*pi*50Hz=314.15926
if(e_d>350)
e_d=350;
else if(e_d<300)
e_d=300;
else
e_d=e_d;
if(e_q>400)
e_q=400;
else if(e_q<-400)
e_q=-400;
else
e_q=e_q;
Vd=-ud_PIcontroler+e_d-314.159265359*Lg*i_q;
Vq=-uq_PIcontroler+e_q+314.159265359*Lg*i_d;
if(Vd>400)
Vd=400;
else
Vd=Vd;
if(Vq<-400)
Vq=-400;
else if(Vq>400)
Vq=400;
else
Vq=Vq;
V_alpha=Vd*sin_theta_k_1-Vq*cos_theta_k_1;
V_beta=-Vd*cos_theta_k_1-Vq*sin_theta_k_1;
V_a=V_alpha;
V_b=-0.5*V_alpha+0.8660254037844386*V_beta;
V_c=-0.5*V_alpha-0.8660254037844386*V_beta;
//使用 DSP 10kHz,归一化:除以325,直流侧电压为650V
//参数5000是因为DSP的PWM外设时钟是100MHz,IGBT开关频率10kHz,三角载波的最大值是5000.
V_a_1=(1+V_a*0.003076923077)*0.5*5000;
V_b_1=(1+V_b*0.003076923077)*0.5*5000;
V_c_1=(1+V_c*0.003076923077)*0.5*5000;
if(V_a_1>5000)
V_a_1=5000;
else if(V_a_1<0)
V_a_1=0;
else
V_a_1=V_a_1;
if(V_b_1>5000)
V_b_1=5000;
else if(V_b_1<0)
V_b_1=0;
else
V_b_1=V_b_1;
if(V_c_1>5000)
V_c_1=5000;
else if(V_c_1<0)
V_c_1=0;
else
V_c_1=V_c_1;
EALLOW;
EPwm1Regs.TZCLR.bit.OST=1;//启动PWM
EPwm2Regs.TZCLR.bit.OST=1;//启动PWM
EPwm3Regs.TZCLR.bit.OST=1;//启动PWM
EDIS;
//使用DSP进行SPWM调制程序段开始
EPwm1Regs.CMPA.bit.CMPA =(int)(V_a_1);
EPwm2Regs.CMPA.bit.CMPA =(int)(V_b_1);
EPwm3Regs.CMPA.bit.CMPA =(int)(V_c_1);
//使用DSP进行SPWM调制程序段结束
}
else
{
V_dc_error_Integral=0;
i_d_error_Integral=0;
i_q_error_Integral=0;
V_a_1=0;
V_b_1=0;
V_c_1=0;
}
//用于测试中断中采样和整个控制算法所消耗的时间,高电平持续的时间即是算法执行时间
GpioDataRegs.GPADAT.bit.GPIO20 =0;
}
算法没问题,使用FPGA进行调制可以正常工作。
使用DSP调制时,在启动闭环控制瞬间,系统直接过流保护。
目前不明白的地方是:
(1)上面程序在寄存器配置时,是否存在问题;
(2)在中断中对寄存器TZCLR和TZFRC进行操作会不会出现问题。
请各位大佬指点一下,谢谢!!!