您好!
我在软件中实现三相整流器的故障保护。保护程序和控制算法均在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进行操作会不会出现问题。
请各位大佬指点一下,谢谢!!!