⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svpwm.c

📁 2407DSP开发应用程序实例(有14个常用模块程序)
💻 C
字号:

//(2)主程序
//该程序用于简单的SVPWM演示,产生互差120度电角度的正统交流电压,此程序实时计算cmp1和cmp2的值
#include "register.h"
#include "float.h"
#include "math.h"
float ualfa[200],ubeta[200];
int   sector[200];
#define  PI2 2*3.1415926
#define  DETA  PI2/200
#define  INIA  3.1415926/180
#define  TP    1200               //t1的周期寄存器的值,其值等于SVPWM市制周期T的一半,
                                  //因为在该程序中2PI电角度内Uout的点数一定,帮改变此
                                  //值可以改变输出的三相正统交流电压的频率
#define  KP    0.7                //定义Uout的标么值,KP的值在0和1之间,改变此值可以改变
                                  //逆变桥输出的电压幅值

//屏蔽中断子程序
void inline disable()
{
     asm(" setc  INTM");
}                                  
//系统初始化子程序
void initial()
{
    SCSR1=0x81FE;					// CLKIN=6M,CLKOUT=4*CLKIN=24M
	WDCR=0x0E8;					    // 不使能看门狗,因为SCSR2中的WDOVERRIDE
		     						// 即WDC复位后的缺省值,故可以用
		      						// 软件禁止看门狗
	IMR=0x0000;						// 禁止所有中断
	IFR=0x0FFFF;
    T3PR=TP;                       //通用定时器1的周期=PWM的周期/指令周期/2
    T3CON=0X0802;                   //设置通用定时器1为连续增减模式,以产生对称PWM
                                    //且为了便于高度使仿真一挂起时钟就停止运行
    ACTRB=0X666;                    //PWM7、9、11高有效,PWM8、10、12低有效
    COMCONB=0X9200;                 //
    EVBIMRA=0X00;
    T3CNT=0X00;
    EVBIFRA=0X0FFFF;
    MCRC=MCRC|0X7E;                  //IOPF口和IOPE0口为一般I/O口,
    								 //IOPE其它口为复用PWM功能
    WSGR=0X0000;                     //不使能所有的等待状态
    
}   

//根据Uout的标幺值KP计算ualfa,ubeta子程序 
void calu()
{
  int i;
  for(i=0;i<200;i++)
  {
    ualfa[i]=KP*cos(INIA+i*DETA); 
    ubeta[i]=KP*sin(INIA+i*DETA);
  }
}
                                 
//各点的扇区确定子程序

void SECTOR()
{
  int i,a,b,c;
  float  vref1,vref2,vref3;
  for(i=0;i<200;i++)
  {
    vref1=ubeta[i];
    vref2=(-ubeta[i]+ualfa[i]*1.732051)/2;
    vref3=(-ubeta[i]-ualfa[i]*1.732051)/2; //计算确定扇区数需要的3个参考量
                                           //vref1,vref2,vref3
    
    if(vref1>0)  a=1;
    else a=0;
    
    if(vref2>0)  b=1;
    else b=0;
    if(vref3>0)  c=1;
    else c=0;    
    a=4*c+2*b+a;
    switch(a){
    
    case 1:sector[i]=1;break; 
    case 2:sector[i]=5;break;
    case 3:sector[i]=0;break;
    case 4:sector[i]=3;break;
    case 5:sector[i]=2;break;
    case 6:sector[i]=4;break;
    default :break;
    
    }                                  //根据相应的关系确定每个Uout所在的扇区
    
  }
}   

//主程序                              

main()
{
 int anticlk[6]={0x1666,0x3666,0x2666,0x6666,0x4666,0x5666};
                                       //逆时针旋转的6个基本矢量
 int i,k=0,cmp1,cmp2;
 float x,y,z;
 disable();
 initial();
 calu();
 SECTOR();
 
 while(1) {
   for(i=0;i<200;i++){
     ACTRB=anticlk[sector[i]];         //重新装配ACTRA,
     x=ubeta[i];
     y=(ubeta[i]+ualfa[i]*1.732051)/2;
     z=(ubeta[i]-ualfa[i]*1.732051)/2; //以上3句计算相应的参考量
     switch(sector[i]){
       case 0:cmp1=(int)(-z*TP),cmp2=(int)(x*TP);break; 
       case 1:cmp1=(int)(y*TP),cmp2=(int)(z*TP);break;
       case 2:cmp1=(int)(x*TP),cmp2=(int)(-y*TP);break;
       case 3:cmp1=(int)(z*TP),cmp2=(int)(-x*TP);break;
       case 4:cmp1=(int)(-y*TP),cmp2=(int)(-z*TP);break;
       case 5:cmp1=(int)(-x*TP),cmp2=(int)(y*TP);break; 
       default:break;
       
     } //以上根据Uout所处的扇区计算相应的cmp1和cmp2   
     CMPR4=cmp1;                      //比较寄存器4赋值
     CMPR5=cmp2+cmp1;                 //比较寄存器5赋值
     if (i+k==0)  T3CON=T3CON|0x040;  //启动定时器,且只1次
     while(1){
         k=EVBIFRA&0x0200;
         if(k==0x0200)  break;        //如果T3的中断标志建立,则停止等待
     }
   }
 }

}    

// 如果由于干扰引起的中断,则直接返回中断服务程序
void interrupt nothing( ) 
{
 	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -