simol_syh 发表于 2010-4-25 15:19

网上找的svpwm程序

该程序用于简单的SVPWM演示,产生3相互差120度电角度的正弦交流电压,未考虑其他因素,仅供参考,大家一起学习下吧,我也刚开始看……

附件为c语言编写的主程序,其他.h,.c,.cmd文件略

simol_syh 发表于 2010-4-25 15:28

// 该程序用于简单的SVPWM演示,产生3相互差120度电角度的正弦交流电压,此程序实时计算cmp1和cmp2的值
#include         "register.h"
#include         "float.h"
#include         "math.h"
float            ualfa,ubeta; // 存储电压矢量Uout的(α,β)轴分量ualfa、ubeta的数组
int            sector;            // 定义存储扇区数的数组
#define         PI2      2*3.1415926    // 定义2π的值   
#define         DETA    PI2/200         // 定义相临两个Uout之间的电角度的差值
#define         INIA      3.1415926/180 // 定义Uout的初始电角度
#define         TP       1200             // t1的周期寄存器的值,其值等于SVPWM调制周期T的一半,
                                          // 因为在该程序中2π电角度内Uout的点数一定,故改变此值
                                          // 可以改变输出的3相正弦交流电压的频率
#define         KP      0.7               // 定义Uout的标幺值,KP的值在0和1之间,改变此值可以
                                          // 改变逆变桥输出电压的幅值
//屏蔽中断子程序         
void inline disable()
{
    asm(" setc INTM");
}
// 系统初始化子程序
viodinitial()
{
    *IFR=0xFFFF;                         //清除所有的中断标志      
    *IMR=0X0;                            // 屏蔽所有中断
    *SCSR1=0x81FE;                     // CLKIN=6M,CLKOUT=24M
      *WDCR=0xE8;                      // 不使能看门狗
    *T3PER=TP;                           // 通用定时器1的周期=PWM的周期/指令周期/2
    *T3CON=0X0802;                     // 设置通用定时器1为连续增减模式,以产生对称的PWM,
                                          // 且为了便于调试,使仿真一挂起时时钟就停止运行
    *ACTRB=0X666;                        // PWM7、9、11高有效,PWM8、10、12低有效
    *COMCONB=0X9200;                     // 使能PWM输出和比较动作
   *EVBIMRA=0X00;                      // 禁止EVB和时钟及比较有关的中断
    *T3CNT=0X00;                         // T1的计数器清0
    *EVBIFRA=0x0FFFF;                  // 清除EVB相应的中断标志
    *MCRC=*MCRC|0X7E;                  // PWM7-PWM12输出使能,使能IOPE1-IOPE6第二功能      
   WSGR=0x0000;                        // 不使能所有的等待状态
}
// 根据Uout的标幺值KP计算ualfa,ubeta子程序
voidcalu()
{
    int    i;
    for(i=0;i&lt200;i++)
    {
      ualfa=KP*cos(INIA+i*DETA);
      ubeta=KP*sin(INIA+i*DETA);
    }
}
// 各点的扇区确定子程序
voidSECTOR()
{
    int    i,a,b,c;
    float    vref1,vref2,vref3;
    for(i=0;i&lt200;i++)
    {
      vref1=ubeta;
      vref2=(-ubeta+ualfa*1.732051)/2;   
      vref3=(-ubeta-ualfa*1.732051)/2;    // 计算确定扇区数需要的3个参考量
// vref1、vref2、vref3
      if(vref1&gt0)      a=1;
      else    a=0;   
      if(vref2&gt0)      b=1;
      else    b=0;
      if(vref3&gt0)      c=1;
      else    c=0;
      a=4*c+2*b+a;
      switch(a){
case 1:sector=1;break;            
            case 2:sector=5;break;
            case 3:sector=0;break;
            case 4:sector=3;break;
            case 5:sector=2;break;
            case 6:sector=4;break;
            default:break;
      }                        // 根据相应的关系确定各个Uout所在的扇区
    }
}
// 主程序
main()
{
int    anticlk={0x1666,0x3666,0x2666,0x6666,0x4666,0x5666};
// 逆时针旋转的6个基本矢量
int    i,k=0,cmp1,cmp2;
float   x,y,z;   
    disable();                            // 屏蔽所有中断
    initial();                            // 系统初始化
    calu();                               // 计算ualfa,ubeta的值
    SECTOR();                           // 确定各点的扇区,在实际应用时应该由即时
// 的ualfa和ubeta即时算出
while(1)    {
      for(i=0;i&lt200;i++)    {
            *ACTRB=anticlk;      // 重新装配ACTRA
            x=ubeta;
            y=(1.732051*ualfa+ubeta)/2;
            z=(-1.732051*ualfa+ubeta)/2;   // 以上3句计算3个相应的参考量
            switch(sector)    {
                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=cmp1+cmp2;      // 比较寄存器5赋值
            if((i+k)==0)      *T3CON=*T3CON|0X040;    // 启动定时器,只启动一次
while(1)    {
                k=*EVBIFRA&0X0200;
                if(k==0x0200)    break;    // 如果T3的中断标志建立,则停止等待
            }   
}
}
}
// 如果由于干扰引起中断,则执行此直接返回程序
void interrupt nothing()
{
    return;
}

leolilee 发表于 2010-5-23 13:30

这是开什么飞机!
有没有文本文件呀,那样可以更好的参照呀!

lbz0123 发表于 2010-5-26 10:08

很多芯片厂商的官网上都有样例代码的 美芯 TI 什么的都有

zmorphis 发表于 2010-5-27 22:36

晕倒,这样的东西还是别发的好!
页: [1]
查看完整版本: 网上找的svpwm程序