各位前辈,我做了一个基于28035的电机vf调速控制程序,运行的时候发现程序一直在中断程序中运行,却没有运行到主程序的软件保护程序中去,这会又问题吗?
电路的软件保护程序部分是在for{}循环(中断等待)内,在for{}程序内部添加了一个test++的语句,调试观察发现这个test的值恒为0,这样下面的保护程序是不是就一直没有运行而起不到保护的作用呢?
HeiHei:
你好,建议保护程序也是用中断做,如可以用TZ中断,这样的话相对于在主循环中做,处理会比较及时。
此外能否看看你主程序是怎么写的吗?你的中断运行正常吗
各位前辈,我做了一个基于28035的电机vf调速控制程序,运行的时候发现程序一直在中断程序中运行,却没有运行到主程序的软件保护程序中去,这会又问题吗?
电路的软件保护程序部分是在for{}循环(中断等待)内,在for{}程序内部添加了一个test++的语句,调试观察发现这个test的值恒为0,这样下面的保护程序是不是就一直没有运行而起不到保护的作用呢?
xiaodong li5:
回复 HeiHei:
// ##########################################################################################// Include header files.// ##########################################################################################
#include "DSP2803x_Device.h"#include "DSP2803x_Examples.h"#include <math.h>
// ==========================================================================================//#define FLASH// ==========================================================================================// Flash programming.// ##########################################################################################
//#ifdef FLASH//#pragma CODE_SECTION(ePWM1A_compare_isr,"ramfuncs"); //将程序烧写到RAM//#endif
// ##########################################################################################// External function prototypes.外部函数声明// ==========================================================================================extern void ConfigAdc(void);//AD采样设置函数声明// ==========================================================================================// Prototype statements for interrupt service routine (ISR)中断服务例程.
// ##########################################################################################interrupt void ePWM1A_compare_isr(void);//PWM中断函数声明//interrupt void ISR_ADC_INT(void);// ##########################################################################################
#ifdef PWM_CLK //for C++ code#else //for C code#define PWM_CLK 10e3 //PWM module clock,If diff freq,desired,change freq herefloat Ts=0.0001; //PWM中断时间#endif//#define VECTOR1 0 // 0 degrees//#define VECTOR2 1365 // 60 degrees//#define VECTOR3 2730 // 120 degrees//#define VECTOR4 4096 // 180 degrees//#define VECTOR5 5461 // 240 degrees//#define VECTOR6 6827 // 300 degrees//#define SIXTY_DEG 1365
// 变量定义float MD; //MD=Us/Udc1_realint PWM_FLAG=0;int k=0; //延时循环里用int Start=0; //开机动作标志位int Stop=0; //关机动作标志位int F_real=0; //把手给定频率int Fgd_given=0; //把手给定频率int dirCache[5]={0,0,0,0,0}; //数组用于把手滤波,功能为方向的确定int dirIP=0; //数组指针int direction=1;//////////////////////float f_real=0;int up_count=0;int down_count=0;int Phase=0;int A=0; //扇区标志1,2,3,4,5,6 float phase=0; float Pwm1=0; float Pwm2=0; float Pwm3=0; float C_Sqrt2 = 1.4142136;//sqrt(2) float PI = 3.141593; float t1,t2,t3,t4,t5; float Ta,Tb,Tc;int angle1, angle2;float Us=0;float Omega_ref;float CosThita;float SinThita;float DELTA_PHASE=0;int _DELTA_PHASE;void InitMotor();void runForward (int F_real);void runBackward(int F_real);void SVM(); int Frequence_down(void); int Frequence_up(void); //extern float U_Delta_calculation(void); extern float sin_table[1024];
//const float sin_table[1024]=
//extern float cos_table[2048];// ==========================================================================================// Initialization for the some pre-initialized objects.// ==========================================================================================// Global variables for single-phase inverter.AD采样变量的初始化// ##########################################################################################//float32 Iinv_AD = 0; // ADCINA0, DC bus current (ADCRESULT conversion value)float32 Udc1_AD = 0; // ADCINA2, 直流母线电压 (ADCRESULT conversion value)float32 IV1_AD = 0; // ADCINA4, V相电流 (ADCRESULT conversion value)float32 Ug_AD = 0; // ADCINA6, 把手给定信号(ADCRESULT conversion value)float32 IW1_AD = 0; // ADCINB0, W相电流 (ADCRESULT conversion value)//float32 Iin_AD = 0; // 逆变器输入电流 (ADCRESULT conversion value)
//float32 Iinv_Real = 0; // DC bus current (real value)float32 Udc1_Real=0; // 直流母线电压 (real value)float32 IV1_Real = 0; // V相电流 (real value)float32 Ug_Real = 0; // 把手给定信号 (real value)float32 IW1_Real = 0; // W相电流 (real value)//float32 Iin_Real = 0; // 逆变器输入电流(real value)float32 I_high=5; //相电流保护值float32 U_high=400; //相电压保护值//float32 IW1_max=250; //W相电流保护值
// AD 平均滤波数组定义float32 IW1Filter[4]={0,0,0,0}; // Sampling value of arithmetic mean filter (instantaneous value)float32 Udc1Filter[4]={0,0,0,0}; // Sampling value of arithmetic mean filter (instantaneous value)float32 IV1Filter[4]={0,0,0,0}; // Sampling value of arithmetic mean filter (instantaneous value)float32 UgFilter[4]={0,0,0,0}; // Sampling value of arithmetic mean filter (instantaneous value)//float32 IinFilter[4]={0,0,0,0}; // Sampling value of arithmetic mean filter (instantaneous value)Uint16 FilterPointer=0; // Counting pointer of arithmetic mean filterUint16 Filter_start=0; //当采样次数大于四次时,该变量变为1,开始平均滤波
//离线时用//extern Uint16 RamfuncsLoadStart;//离线时用//extern Uint16 RamfuncsLoadEnd; //离线时用//extern Uint16 RamfuncsRunStart; //离线时用//离线时用// ##########################################################################################//###########################################################################################//******************************main code****************************************************//###########################################################################################//float speed=1.2;
void main(void) {// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initialize System Control: PLL, WatchDog, enable Peripheral Clocks, etc..// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% InitSysCtrl(); //系统时钟设置 DINT; //关全部中断 IER = 0x0000; //关全部中断使能 IFR = 0x0000; //清除中断标志// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initalize GPIO.GPIO模块初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% InitGpio(); //普通IO口初始化 InitEPwm1Gpio(); //PWM1 IO口初始化 InitEPwm2Gpio(); //PWM2 IO口初始化 InitEPwm3Gpio(); //PWM3 IO口初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initialize the PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags are cleared.// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% InitPieCtrl(); //外设中断控制器PIE寄存器初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initialize the PIE vector table with pointers to the shell Interrupt.// Service Routines (ISR).// This will populate the entire table, even if the interrupt.// is not used in this project. This is useful for debug purposes.// The shell ISR routines are found in DSP2833x_DefaultIsr.c.// This function is found in DSP2833x_PieVect.c.// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% InitPieVectTable(); //PIE中断向量表初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Only used if running from FLASH.// Note that the variable FLASH is defined by the compiler.// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //#ifdef FLASH // Copy time critical code and Flash setup code to RAM. // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart. // symbols are created by the linker. Refer to the linker files. //MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);//离线有效时 // Call Flash Initialization to setup flash waitstates. // This function must reside in RAM. //InitFlash(); // Call the flash wrapper init function.离线有效时 // #endif //(FLASH)// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initialize PWM module.PWM模块初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; //每一个被使能的EPWM模块的基准时钟停止 EDIS; InitEPwm(); //PWM模块初始化 EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; //所有被使能的EPWM模块的基准时钟都从第一个TBCLK上升沿开始 , //使EPWM基准时钟同步 EDIS;// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Initialize ADC module. AD模块初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% InitAdc(); // AD采样时钟频率初始化 ConfigAdc(); // AD模块寄存器配置初始化// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Interrupts are re-mapped to ISR functions found within this file.// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EALLOW; PieVectTable.EPWM1_INT = &ePWM1A_compare_isr;// 将PWM中断函数的地址指向对应的PIE中断地址 EDIS;// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Enable INT in the PIE: EPWM1_INT, Group 3 interrupt 1.// Enable INT in the PIE: ADC_INT, Group 1 interrupt 6.// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // 使能PIE第三组第一个中断(即EPWM1A)// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Enable CPU INT: INT3 for EPWM1_INT.// Enable CPU INT: INT1 for ADC_INT.// 使能PWM中断// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% IER |= M_INT1; //group1 XINT1,TINT0,ADC IER |= M_INT3;// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// Enable global interrupts and higher priority real-time debug events.// Enable Global interrupt INTM.// Enable Global realtime interrupt DBGM.// 打开全局中断// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EINT; ERTM;// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%// IDLE loop. Just wait for a interrupt.// 等待PWM中断// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for (;;) //infinite loop { asm("NOP"); //这一汇编语句虽然不会导致描述性编译错误,但有时会导致无法输出out文件// —————————————————————————————————//上电初始,基于硬件保护电路的瞬态变化,该部分程序会进入执行。若无硬件故障信号,保护电路解锁,//DRIVE-EN为低电平,等待开机信号。//工作与正常开机模式,该模块程序实现软/硬件保护解锁。// ————————————————————————————————— if(GpioDataRegs.GPADAT.bit.GPIO24==1&&-I_high<IV1_Real<I_high&&-I_high<IW1_Real<I_high &&-I_high<IW1_Real+IV1_Real<I_high&&Udc1_Real<U_high) //DRIVE-EN为高电平,表明处于硬件保护状态且故障已消除,由此才会进入, { DELAY_US(5000L);//DELAY_US(5000L);DELAY_US(5000L); if(GpioDataRegs.GPADAT.bit.GPIO24==1&&-I_high<IV1_Real<I_high&&-I_high<IW1_Real<I_high &&-I_high<IW1_Real+IV1_Real<I_high&&Udc1_Real<U_high) //延时确认故障确实不再存在故障,则进入,通过软件解锁,切除硬件保护状态 { GpioDataRegs.GPACLEAR.bit.GPIO20= 1; // D-UNLOCK = Low level 和后一指令配合实现故障解锁指令 //(结合后边微秒级延时,用低电平脉冲信号实现故障状态切除) if (GpioDataRegs.GPADAT.bit.GPIO14==0) // 说明为软件保护,为保证软件保护情况下进入, //而在上电瞬间不进入而实现开机键,&&PWM_FLAG==1语句是需要的 { DELAY_US(5000L);//DELAY_US(5000L); } DELAY_US(1L); // 微妙级延时,给硬件电路一定的解锁时间(硬件反应时间) //PWM_FLAG=1; GpioDataRegs.GPASET.bit.GPIO20 =1; GpioDataRegs.GPASET.bit.GPIO14 =1; //D-LOCK = high level 实现软件引起的保护状态解锁 } } // if(GpioDataRegs.GPCDAT.bit.GPIO74 ==1&&GpioDataRegs.GPCDAT.bit.GPIO75 ==1) //GPIO74,GPIO75为把手方向端口(I/O口) // { DELAY_US(5000L);DELAY_US(5000L);DELAY_US(5000L); // if(GpioDataRegs.GPCDAT.bit.GPIO74 ==1&&GpioDataRegs.GPCDAT.bit.GPIO75 ==1) // { direction=1; //正向 EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM1死区 EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM2死区 EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM3死区 EPwm1Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM1A无效 EPwm1Regs.AQCSFRC.bit.CSFB = 0x00; //强制EPWM1B无效 EPwm2Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM2A无效 EPwm2Regs.AQCSFRC.bit.CSFB = 0x00; //强制EPWM2B无效 EPwm3Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM3A无效 EPwm3Regs.AQCSFRC.bit.CSFB = 0x00; //强制EPWM3B无效 // }
// }
if((IV1_Real>I_high)|(IV1_Real<-I_high)|(IW1_Real>I_high)|(IW1_Real<-I_high)|(IV1_Real+IW1_Real>2*I_high) |(IV1_Real+IW1_Real<-2*I_high)|(Udc1_Real>U_high)|GpioDataRegs.GPADAT.bit.GPIO24==1) { EPwm1Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM1死区 EPwm2Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM2死区 EPwm3Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM3死区 EPwm1Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM1A输出低电平 EPwm1Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM1B输出低电平 EPwm2Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM2A输出低电平 EPwm2Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM2B输出低电平 EPwm3Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM3A输出低电平 EPwm3Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM3B输出低电平 Fgd_given=0; Stop=1; f_real=0; up_count=0; down_count=0; phase=0; Phase=0; Us=0; //GpioDataRegs.GPCCLEAR.bit.GPIO77 = 0; //D-LOCK = Low level 通过软件控制LOCK,进而又硬件电路实现EN-DRIVE=1,即封锁PWM输出 } if(f_real<5) { EPwm1Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM1死区 EPwm2Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM2死区 EPwm3Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; //关闭PWM3死区 EPwm1Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM1A输出低电平 EPwm1Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM1B输出低电平 EPwm2Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM2A输出低电平 EPwm2Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM2B输出低电平 EPwm3Regs.AQCSFRC.bit.CSFA = 0x1; //强制EPWM3A输出低电平 EPwm3Regs.AQCSFRC.bit.CSFB = 0x1; //强制EPWM3B输出低电平 } else { EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM1死区 EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM2死区 EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //打开PWM3死区 EPwm1Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM1A输出低电平 EPwm1Regs.AQCSFRC.bit.CSFB = 0x00; //强制EPWM1B输出低电平 EPwm2Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM2A输出低电平 EPwm2Regs.AQCSFRC.bit.CSFB = 0x00; //强制EPWM2B输出低电平 EPwm3Regs.AQCSFRC.bit.CSFA = 0x00; //强制EPWM3A输出低电平 EPwm3Regs.AQCSFRC.bit.CSFB = 0x00;
} }
} // Main Ends Here
//###########################################################################################//**************************ePWM1A_compare_isr code******************************************//########################################################################################### interrupt void ePWM1A_compare_isr(void)
{
// AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1; //排序器立即复位到状态CONV00 //add// // AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1; //软件触发,开始AD转换 与上一语句不可更换顺序 //add// // while (AdcRegs.ADCST.bit.SEQ1_BSY != 0)//等待上一次AD采样结束后,再开始新一轮AD采样 ;//add// //SEQ1_BSY=0表示SEQ1空闲 // { //add// //asm("NOP"); // } //add//
// ——————————————————————————————// 读取采样结果// —————————————————————————————— //Iinv_AD = 3.0*AdcMirror.ADCRESULT0/4095; // ADCINA0, 直流母线电流 // 为DSP AD端口实际输入值
DELAY_US(40L);//0.1us的延时函数占空比为0.5时为25 稳压时为34 AdcRegs.ADCCTL1.bit.RESET= 0x1;//排序器立即复位到状态CONV00 AdcRegs.ADCSOCFRC1.all = 0x00FF; // 软件触发,开始AD转换 与上一语句不可更换顺序 while (AdcRegs.ADCSOCFLG1.all!= 0)//等待AD转换结束 { }
Udc1_AD = 3.3*AdcResult.ADCRESULT0/4095; // ADCINA2, 直流母线电压 IV1_AD = 3.3*AdcResult.ADCRESULT3/4095; // ADCINA4, V相电流 Ug_AD = 3.3*AdcResult.ADCRESULT7/4095; // ADCINA6, 把手给定信号,频率给定 IW1_AD = 3.3*AdcResult.ADCRESULT4/4095; // ADCINB0, W相电流// ——————————————————————————————// 平均滤波// —————————————————————————————— if(FilterPointer>3) { FilterPointer=0;Filter_start=1; } Udc1Filter[FilterPointer] = Udc1_AD; IV1Filter[FilterPointer] = IV1_AD; UgFilter[FilterPointer] = Ug_AD; IW1Filter[FilterPointer] = IW1_AD; FilterPointer++; if (Filter_start==1) {
Udc1_AD = (Udc1Filter[0]+Udc1Filter[1]+Udc1Filter[2]+Udc1Filter[3])/4; IV1_AD = (IV1Filter[0]+IV1Filter[1]+IV1Filter[2]+IV1Filter[3])/4; Ug_AD = (UgFilter[0]+UgFilter[1]+UgFilter[2]+UgFilter[3])/4; IW1_AD = (IW1Filter[0]+IW1Filter[1]+IW1Filter[2]+IW1Filter[3])/4;
}
// ——————————————————————————————// 根据实际原理图中信号处理电路的比例关系将采样信号转换成实际主电路中的信号值。// —————————————————————————————— //Udc1_Real = (Udc1_AD+0.13)*144; Udc1_Real = Udc1_AD*144; // 直流母线电压 (from ADCRESULT1) IV1_Real = (IV1_AD-1.624)*8; // V相电流 (from ADCRESULT2) IW1_Real=(IW1_AD-1.627)*8; // W相电流 (from ADCRESULT2) Ug_Real=Ug_AD ; // 把手给定电压(from ADCRESULT2)// ——————————————————————————————// 把手电压计算// ——————————————————————————————
// if(Ug_Real<80) //最小频率给定 // Ug_Real=80; // Fgd_given=Ug_Real/20; //—————上面三行屏蔽(GavinLee)——————–// //if(Fgd_given>50) //限幅50Hz //开机模块 if(Udc1_Real>100) { GpioDataRegs.GPBCLEAR.bit.GPIO32 = 1; } if(Udc1_Real<=100) { GpioDataRegs.GPBSET.bit.GPIO32 = 1; // GPIO76 = high level置位 } if(direction==1) { Fgd_given=Ug_Real*25; //把手给定电压对应频率关系,0-2.5V对应0-50 if(Fgd_given>50)//限幅50Hz { Fgd_given=50; } }// ——————————————————————————————// 把手给定积分// —————————————————————————————— if(f_real<Fgd_given) { { up_count++; if(up_count>2000) { up_count = 0; f_real = f_real+1; //频率以一定的速度上升,上升时间在5k的载波频率下约为10s if(f_real>=Fgd_given) { f_real = Fgd_given; } } } } else if(f_real>Fgd_given) { down_count++; if(down_count>2000) { down_count=0; f_real=f_real-1; //频率以一定的速度下降,下降时间在5k的载波频率下约为10s } } Us = f_real*5.6; // 电机V/F程序 DELTA_PHASE = (float)(f_real*4096/10000);//每个开关周期内磁链角变化量 //int _DELTA_PHASE=DELTA_PHASE; if(direction==1) //正向 { phase+=DELTA_PHASE; } if(phase>=4096) { phase = phase-4096; } if(phase<0) { phase = phase+4096; } Phase =phase;
MD=Us/Udc1_Real; if(MD>C_Sqrt2/2)//C_Sqrt2/2 { MD=C_Sqrt2/2; } if(Phase < 683) { A=1; //第一扇区 angle2=Phase; // Reference SVM angle to the current angle1=683-angle2; // Calculate second angle referenced to t4=sin_table[angle1]; t5=sin_table[angle2]; t1 = C_Sqrt2*MD*t4; t2 = C_Sqrt2*MD*t5; t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t1*0.5; Tc = Tb+t2*0.5; Pwm1 = Ta; Pwm2 = Tb; Pwm3 = Tc; } else if(Phase <1366) { A=2; angle2 = Phase – 683; // Reference SVM angle to the current angle1 = 683 – angle2; // Calculate second angle referenced to t1 = C_Sqrt2*MD*sin_table[angle1]; // Look up values from t2 = C_Sqrt2*MD*sin_table[angle2]; // Look up values from t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t2*0.5; Tc = Tb+t1*0.5; Pwm1 = Tb; Pwm2 = Ta; Pwm3 = Tc; } else if(Phase < 2049) { A=3; angle2 = Phase – 1366; // Reference SVM angle to the current angle1 = 683 – angle2; // Calculate second angle referenced to t1 = C_Sqrt2*MD*sin_table[angle1]; // Look up values from t2 = C_Sqrt2*MD*sin_table[angle2]; // Look up values from t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t1*0.5; Tc = Tb+t2*0.5; Pwm1 = Tc; Pwm2 = Ta; Pwm3 = Tb; } else if(Phase < 2732) { A=4; angle2 = Phase – 2049; // Reference SVM angle to the current angle1 = 683 – angle2; // Calculate second angle referenced to t1 = C_Sqrt2*MD*sin_table[angle1]; // Look up values from t2 = C_Sqrt2*MD*sin_table[angle2]; // Look up values from t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t2*0.5; Tc = Tb+t1*0.5; Pwm1 = Tc; Pwm2 = Tb; Pwm3 = Ta; } else if(Phase < 3415) { A=5; angle2 = Phase – 2732; // Reference SVM angle to the current angle1 = 683 – angle2; // Calculate second angle referenced to t1 = C_Sqrt2*MD*sin_table[angle1]; // Look up values from t2 = C_Sqrt2*MD*sin_table[angle2]; // Look up values from t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t1*0.5; Tc = Tb+t2*0.5; Pwm1 = Tb; Pwm2 = Tc; Pwm3 = Ta; } else { A=6; angle2 = Phase – 3415; // Reference SVM angle to the current angle1 = 681 – angle2; // Calculate second angle referenced to t1 = C_Sqrt2*MD*sin_table[angle1]; // Look up values from t2 = C_Sqrt2*MD*sin_table[angle2]; // Look up values from t1 = t1*Ts; t2 = t2*Ts; if((t1 + t2)>Ts) { t3=t1+t2; t1 = t1*Ts/t3; t2 = t2*Ts/t3; } Ta = (Ts-t1-t2)*0.25; Tb = Ta+t2*0.5; Tc = Tb+t1*0.5; Pwm1 = Ta; Pwm2 = Tc; Pwm3 = Tb; } // end SVM() EPwm1Regs.CMPA.half.CMPA = (Uint16)(Pwm1*PWM_CLK*1500*2); EPwm2Regs.CMPA.half.CMPA = (Uint16)(Pwm2*PWM_CLK*1500*2); EPwm3Regs.CMPA.half.CMPA = (Uint16)(Pwm3*PWM_CLK*1500*2); EPwm1Regs.ETCLR.bit.INT = 1; //EPWM中断标志位清零 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //PIE第三组中断标志位置1,表示CPU已响应中断。系统开始等待响应新的中断
}
// ——————————————————————————————// 电机软启动// ——————————————————————————————int Frequence_up(void){ up_count++; if(up_count>10) { up_count = 0; //频率以一定的速度上升,上升时间在5k的载波频率下约为10s f_real = f_real+1; if(f_real>=Fgd_given) { f_real = Fgd_given; } } return f_real;}int Frequence_down(void){ down_count++;if(down_count>1000){ down_count=0; //频率以一定的速度上升,上升时间在5k的载波频率下约为10s f_real=f_real-1;}return f_real;}// ——————————————————————————————//SVPWM程序实现// ——————————————————————————————
// ——————————————————————————————// 电机V/F程序// ——————————————————————————————/*float U_Delta_calculation(void){ int Us; Us = f_real*9.28; return Us;}*/
各位前辈,我做了一个基于28035的电机vf调速控制程序,运行的时候发现程序一直在中断程序中运行,却没有运行到主程序的软件保护程序中去,这会又问题吗?
电路的软件保护程序部分是在for{}循环(中断等待)内,在for{}程序内部添加了一个test++的语句,调试观察发现这个test的值恒为0,这样下面的保护程序是不是就一直没有运行而起不到保护的作用呢?
xiaodong li5:
回复 HeiHei:
您好,我的主程序如上,中断程序能够正常运行,程序一直在中断的程序里运行,应该是没有从中断程序跳回到主程序。