分享一個DSP28335的SVPWM程序源碼,可供參考
單片機源程序如下:
- //***************************************************/
- //文件名:SVPWM.c
- //功能:調用28335內部PWM模塊生成SVPWM輸出測試文件
- //說明:輸入信息采用結構體,使用時改變結構體指針即可改變輸入信號。
- // InitSvpwm()函數提供PWM模塊初始化以及相應PIE中斷的配置。
- // 通過park逆變換得到靜止平面坐標系下的電壓信號。
- // 在PWM定時器下溢中斷中更新比較器的值,即每個PWM周期更新一次
- //****************************************************/
- #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
- #include "DSP2833x_Examples.h" // DSP2833x Examples Include File
- #include "math.h"
- #include "float.h"
- extern Uint16 RamfuncsRunStart;
- extern Uint16 RamfuncsLoadStart;
- extern Uint16 RamfuncsLoadEnd;
-
- typedef struct
- {
- float ds; // 靜止平面坐標系下電壓信號
- float qs;
- float ang; // 電氣角度 電氣角度=機械角度*極對數
- float de; // 旋轉坐標系下電壓信號
- 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<F28335.cmd>
- 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)
- {
- float ang;
- ang=(v->ang/360)*2*PI; //角度轉化為弧度
- v->ds=v->de*cos(ang)-v->qe*sin(ang); //得到靜止平面坐標系下d軸電壓
- v->qs=v->qe*cos(ang)+v->de*sin(ang); //得到靜止平面坐標系下q軸電壓
- }
- void svgen(IPARK *v)
- {
- float Va,Vb,Vc,t1,t2,Ta,Tb,Tc;
- Uint32 sector=0; // sector=a+2b+4c 扇區狀態標示 注意:setor的值1~6與扇區不是順序對應
- ipark(v);
- 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) // 判斷屬于哪個扇區
- sector=1; // Va>0 則 a=1;否則a=0
- if(Vb>0.0000001) //
- sector=sector+2; // Vb>0 則 b=1;否則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; // 增減計數模式
- EPwm1Regs.TBPRD = PRD; // 設置周期
- EPwm1Regs.TBCTL.bit.PHSEN = 0x0; // 禁用相位加載同步
- EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 相位初值
- EPwm1Regs.TBCTR = 0x0000; // 計數初值
- EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x1; // TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)
- EPwm1Regs.TBCTL.bit.CLKDIV = 0x1;
- // 配置比較寄存器
- EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0x0; //使用陰影寄存器
- EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0x0;
- EPwm1Regs.CMPCTL.bit.LOADAMODE = 0x0; //計數器值為0時更新比較器值
- EPwm1Regs.CMPCTL.bit.LOADBMODE = 0x0;
- // 設置比較器初值
- EPwm1Regs.CMPA.half.CMPA = 1875;
- EPwm1Regs.CMPB = 1875;
- // 模式設定
- EPwm1Regs.AQCTLA.bit.ZRO = 0x1; // 等于0時輸出低
- EPwm1Regs.AQCTLA.bit.CAU = 0x3; // 計數值=比較值時輸出取反
- EPwm1Regs.AQCTLB.bit.ZRO = 0x2; // 等于0時輸出高
- EPwm1Regs.AQCTLB.bit.CBU = 0x3; // 計數值=比較值時輸出取反
- // 配置中斷
- EPwm1Regs.ETSEL.bit.INTSEL = 0x1; // 計數值到0觸發事件
- EPwm1Regs.ETSEL.bit.INTEN = 1; // 使能中斷
- 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;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
21840266SVPWM.rar
(670.53 KB, 下載次數: 572)
2018-5-9 09:39 上傳
點擊文件名下載附件
|