312|0

3612

帖子

0

资源

纯净的硅(初级)

TI TMS320F28335程序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;          
        


回复
您需要登录后才可以回帖 登录 | 注册

关闭
站长推荐上一条 1/1 下一条

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表