1673 views |0 replies
Last login 2024-11-13
Online Time 616 hours
Prestige 6914 points
Points 6266 points
The source program of the microcontroller is as follows: //*******************************************************/ //File name: SVPWM.c //Function: Call 28335 internal PWM module to generate SVPWM output test file //Description: The input information uses a structure. When using it, changing the structure pointer can change the input signal. // The InitSvpwm() function provides PWM module initialization and configuration of the corresponding PIE interrupt. // The voltage signal in the stationary plane coordinate system is obtained through the park inverse transformation. // Update the value of the comparator in the PWM timer underflow interrupt, that is, update once every PWM cycle //********************************************************/ #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h" // DSP2833x Examples Include File #include "math.h" #include "float.h" [color=#000 000] extern Uint16 RamfuncsRunStart; extern Uint16 RamfuncsLoadStart; extern Uint16 RamfuncsLoadEnd; [/ size] typedef struct { float ds; // Voltage signal in stationary plane coordinate system float qs; float ang; // Electrical angle Electrical angle = mechanical angle * number of pole pairs float de; // Voltage signal in rotating coordinate system float qe; }IPARK; IPARK ipark1={0,0,0,0.3,0.4};
// IPARK *v=&ipark1; //改变此处结构体指针改变输入
void InitSvpwm(void);
void InitEPwm1(void);
void InitEPwm2(void);
void InitEPwm3(void);
interrupt void epwm1_isr(void);
void ipark(IPARK *v);
void svgen(IPARK *v);
#define PRD 7500 // PWM周期寄存器
#define PI 3.1415926
float tmr1,tmr2,tmr3;
void main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); //Flash operation&RamfuncsRunStart); //Flash operation&RamfuncsRunStart); //Flash operationtmr3;
void main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); //Flash operationtmr3;
void main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); //Flash operation
InitFlash();
InitSvpwm();
for(;;)
{
asm(" NOP");
}
}
void InitSvpwm(void)
{
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
EALLOW;
PieVectTable.EPWM1_INT = &epwm1_isr;
EDIS;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1();
InitEPwm2();
InitEPwm3();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
IER |= M_INT3;
// 使能中断 EPWM INT1 位于PIE中断分组3.1
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT;
ERTM;
}
interrupt void epwm1_isr(void)
{
// 更新 CMPA 和 CMPB 寄存器值
svgen(&ipark1);
EPwm1Regs.CMPA.half.CMPA=tmr1;
EPwm2Regs.CMPA.half.CMPA=tmr2;
EPwm3Regs.CMPA.half.CMPA=tmr3;
EPwm1Regs.CMPB=tmr1;
EPwm2Regs.CMPB=tmr2;
EPwm3Regs.CMPB=tmr3;
// 清除中断标志
EPwm1Regs.ETCLR.bit.INT = 1;
// 清除中断响应
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } void ipark(IPARK *v) [backcolor= white]{ float ang; ang=(v->ang/360)*2*PI; // Angle converted to radians v ->ds=v->de*cos(ang)-v->qe*sin(ang); //Get the d-axis voltage in the stationary plane coordinate system [backcolor= white] v->qs=v->qe*cos(ang)+v->de*sin(ang); //Get the q-axis voltage in the stationary plane coordinate system[ /color] } void svgen(IPARK *v) ]{ float Va,Vb,Vc,t1,t2,Ta,Tb,Tc;[/color ] Uint32 sector=0; // sector=a+2b+4c Sector status indication Note: the value of setor is 1~ 6 does not correspond to the sectors in sequence ipark(v); [/ backcolor] Va=v->qs; // Va = Uq Vb=(-0.5) * v->qs + (0.8660254) * v->ds; // Vb = 1/2*(sqrt(3)*Ud - Uq) sqrt(3)/2=0.866 Vc=(-0.5) * v->qs - (0.8660254) * v->ds; // Vc = -1/2*(sqrt(3)Ud + Uq) if(Va>0.0000001) // Determine which sector it belongs to [size=4 ] sector=1; // Va>0 then a=1; otherwise a=0 [color= #000000] if(Vb>0.0000001) // sector=sector+2; // Vb>0 Then b=1; otherwise b=0 if(Vc>0.0000001) //
sector=sector+4; // Vc>0 则 c=1; 否则c=0
Va=v->qs;
Vb=(-0.5) * v->qs + (0.8660254) * v->ds;
Vc=(-0.5) * v->qs - (0.8660254) * v->ds;
switch(sector){
case 1: //sector==1 对应扇区II
t1=Vc;
t2=Vb;
Tb=(0.25)*(1-t1-t2);
Ta=Tb+(0.5)*t1;
Tc=Ta+(0.5)*t2;
break;
case 2: //sector==2 对应扇区VI
t1=Vb;
t2=-Va;
Ta=(0.25)*(1-t1-t2);
Tc=Ta+(0.5)*t1;
Tb=Tc+(0.5)*t2;
break;
case 3: //sector==3 对应扇区I
t1=-Vc;
t2=Va;
Ta=(0.25)*(1-t1-t2);
Tb=Ta+(0.5)*t1;
Tc=Tb+(0.5)*t2;
break;
case 4://sector==4 对应扇区IV
t1=-Va;
t2=Vc;
Tc=(0.25)*(1-t1-t2);
Tb=Tc+(0.5)*t1;
Ta=Tb+(0.5)*t2;
break;
case 5: //sector==5 对应扇区III
t1=Va;
t2=-Vb;
Tb=(0.25)*(1-t1-t2);
Tc=Tb+(0.5)*t1;
Ta=Tc+(0.5)*t2;
break;
case 6: //sector==6 对应扇区V
t1=-Vb;
t2=-Vc;
Tc=(0.25)*(1-t1-t2);
Ta=Tc+(0.5)*t1;
Tb=Ta+(0.5)*t2;
break;
default: //sector=0和sector=7时错误
Ta=0.5;
Tb=0.5;
Tc=0.5;
}
tmr1=Ta*PRD;
tmr2=Tb*PRD;
tmr3=Tc*PRD;
}
void InitEPwm1()
{
// 配置时钟
EPwm1Regs.TBCTL.bit.CTRMODE = 0x2; // Increase and decrease counting mode EPwm1Regs.TBPRD = PRD; // Set period EPwm1Regs.TBCTL.bit.PHSEN = 0x0; // Disable phase loading synchronization EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase initial value EPwm1Regs.TBCTR = 0x0000; // Initial count value EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x1; // TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV) EPw m1Regs.TBCTL.bit.CLKDIV = 0x1; //Configure comparison register [color =#000000] EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0x0; //Use shadow registers EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0x0; EPwm1Regs.CMPCTL.bit.LOADAMODE = 0x0; //Update comparator value when counter value is 0 EPwm1Regs.CMPCTL.bit.LOADBMODE = 0x0; //Set the initial value of the comparator EPwm1Regs.CMPA.half.CMPA = 1875; EPwm 1Regs.CMPB = 1875; // Mode setting EPw m1Regs.AQCTLA.bit.ZRO = 0x1; // Output low when equal to 0 EPwm1Regs.AQCTLA.bit.CAU = 0x3; // Output is inverted when count value = comparison value EPwm1Regs.AQCTLB.bit.ZRO = 0x2; // Output high when equal to 0 EPwm1Regs.AQCTLB.bit.CBU = 0x3; // Output is inverted when count value = comparison value // Configure interrupts EPwm1Regs.ETSEL.bit.INTSEL = 0x1; // The count value reaches 0 and triggers an event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable interrupts EPwm1Regs.ETPS.bit.INTPRD = 0x1; // 每次事件发生都触发中断
}
void InitEPwm2()
{
EPwm2Regs.TBCTL.bit.CTRMODE = 0x2;
EPwm2Regs.TBPRD = PRD;
EPwm2Regs.TBCTL.bit.PHSEN = 0x0;
EPwm2Regs.TBPHS.half.TBPHS = 0x0000;
EPwm2Regs.TBCTR = 0x0000;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0x1;
EPwm2Regs.TBCTL.bit.CLKDIV = 0x1;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0x0;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0x0;
EPwm2Regs.CMPCTL.bit.LOADAMODE = 0x0;
EPwm2Regs.CMPCTL.bit.LOADBMODE = 0x0;
EPwm2Regs.CMPA.half.CMPA = 1875;
EPwm2Regs.CMPB = 1875;
EPwm2Regs.AQCTLA.bit.ZRO = 0x1;
EPwm2Regs.AQCTLA.bit.CAU = 0x3;
EPwm2Regs.AQCTLB.bit.ZRO = 0x2;
EPwm2Regs.AQCTLB.bit.CBU = 0x3;
EPwm2Regs.ETSEL.bit.INTEN = 0; //屏蔽中断
}
void InitEPwm3(void)
{
EPwm3Regs.TBCTL.bit.CTRMODE = 0x2;
EPwm3Regs.TBPRD = PRD;
EPwm3Regs.TBCTL.bit.PHSEN = 0x0;
EPwm3Regs.TBPHS.half.TBPHS = 0x0000;
EPwm3Regs.TBCTR = 0x0000;
……………………