打印

SVPWM源程序

[复制链接]
13999|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fengyeu|  楼主 | 2007-12-23 20:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第15章  用TMS320LF2407 实现空间矢量PWM(SVPWM)
15.3  利用TMS320LF240x实现SVPWM算法的程序
下面给出了利用TMS320LF2407实现SVPWM算法的一个应用程序。在该程序中,我们假设有200个电压矢量Uout 平均分布在电角度为2π的范围内,通过改变SVPWM的调制周期T可以改变输出的3相正弦波的频率。
源程序代码:
(1)    所需的复位和中断矢量定义文件“vectors.asm”请读者参考本书相关章节。
(2)    主程序
// 该程序用于简单的SVPWM演示,产生3相互差120度电角度的正弦交流电压,此程序实
// 时计算cmp1和cmp2的值 
#include         "register.h"  
#include         "float.h" 
#include         "math.h"
float            ualfa[200],ubeta[200]; // 存储电压矢量Uout的(α,β)轴分量ualfa、ubeta的数组 
int            sector[200];          // 定义存储扇区数的数组 
#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");
}
// 系统初始化子程序 
viod  initial()
{
    *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子程序 
void  calu()
{
    int    i;
    for(i=0;i<200;i++)
    {
        ualfa=KP*cos(INIA+i*DETA);
        ubeta=KP*sin(INIA+i*DETA);
    }
}
// 各点的扇区确定子程序 
void  SECTOR()
{
    int    i,a,b,c;
    float    vref1,vref2,vref3;
    for(i=0;i<200;i++)
    {
        vref1=ubeta
        vref2=(-ubeta+ualfa*1.732051)/2;    
        vref3=(-ubeta-ualfa*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=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[6]={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<200;i++)    {
            *ACTRB=anticlk[sector];        // 重新装配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;
}

相关帖子

沙发
fengyeu|  楼主 | 2007-12-23 20:46 | 只看该作者

从刘和平光盘里拷贝的?

从刘和平光盘里拷贝的?
不知道能不能用!
请高手看看。有问题的话帮我改下,
刚接触这行,
按的专业是电子技术。
先谢过了

使用特权

评论回复
板凳
fengyeu|  楼主 | 2007-12-23 20:55 | 只看该作者

在贴一个

使用TI TMS2407 实现SVPWM同步电机控制算法。源代码在闻廷科技的2407开发板上已经调试成功


#include "register.h"
#define  Fs  2                        //Fs为采样频率kHz(载波频率)

#define PI 180 
const int csin[180]={0,                   //查表法计算正弦值
174,
348, 
523, 
697, 
871, 
1045,  
1218, 
1391, 
1564, 
1736, 
1908, 
2079, 
2249, 
2419, 
2588, 
2756,
2923, 
3090, 
3255, 
3420, 
3583, 
3746, 
3907, 
4067, 
4226, 
4383, 
4539, 
4694, 
4848, 
5000, 
5150, 
5299, 
5446, 
5591, 
5735, 
5877, 
6018, 
6156, 
6293, 
6427, 
6560, 
6691, 
6819, 
6946, 
7071, 
7193, 
7313, 
7431, 
7547, 
7660, 
7771, 
7880, 
7986, 
8090, 
8191, 
8290, 
8386, 
8480, 
8571, 
8660, 
8746, 
8829, 
8910, 
8987, 
9063, 
9135, 
9205, 
9271, 
9335, 
9396, 
9455, 
9510, 
9563, 
9612, 
9659, 
9702, 
9743, 
9781, 
9816, 
9848, 
9876, 
9902, 
9925, 
9945, 
9961, 
9975, 
9986, 
9993, 
9998, 
10000,
9998, 
9993, 
9986, 
9975, 
9961, 
9945, 
9925, 
9902, 
9876, 
9848, 
9816, 
9781, 
9743, 
9702, 
9659, 
9612, 
9563, 
9510, 
9455, 
9396, 
9335, 
9271, 
9205, 
9135, 
9063, 
8987, 
8910, 
8829, 
8746, 
8660, 
8571, 
8480, 
8386, 
8290, 
8191, 
8090, 
7986, 
7880, 
7771, 
7660, 
7547, 
7431, 
7313, 
7193, 
7071, 
6946, 
6819, 
6691, 
6560, 
6427, 
6293, 
6156, 
6018, 
5877, 
5735, 
5591, 
5446, 
5299, 
5150, 
5000, 
4848, 
4694, 
4539, 
4383, 
4226, 
4067, 
3907, 
3746, 
3583, 
3420, 
3255, 
3090, 
2923, 
2756, 
2588, 
2419, 
2249, 
2079, 
1908, 
1736, 
1564, 
1391, 
1218, 
1045, 
871,
697, 
523, 
348, 
174, 
};                                        //存储sin函数的91个单元,每
个单元存递增一度的sin值,放大了100000倍;
unsigned int i=0,j=0;
unsigned long int k=0,t=0,N=0,M=9;          //M值的大小和Fc有关系, Ud
不变,Uc随着Fc的改变而改变,
所以M=Uc/Us值改变。
unsigned long int tm1=0,tm2=0,tm3=0;
unsigned int ADAcount=0,ischange=0,result=0,Fc=25; 

void initial(void);
void sysinit(void);
void intinit(void);
void evainit(void);
void ADInit(void);
void interrupt gptime1(void);
void interrupt nothing(void);
unsigned long int gettime(unsigned long int);

main()
{   
    initial();                               //系统初始化
    sysinit();
    intinit(); 
    ADInit();
    evainit();
    N=1000*Fs/Fc;
       while(1)
    {
        if ( ADAcount>=200 )                   // 如果ADAcount>=200,以下
开始转换和保存转换结果 
        {
            ADAcount=0;                       //清保存标志 
             result=(*RESULT0);                //取ADCINT0通道转换结果 
             result>>=6;                       //取有效位
             if(result!=0)
             {
                 Fc=result*50/1024;             //将采进的电压值Uc转换为频率Fc
                 if(Fc<=2)
                     Fc=2;
                M=10*Fc/50;  
                   if(M<=1)
                       M=1;
                   if(M>=10)
                       M=10;
                   ischange=1;
               }
                *ADCTRL2= 0x2000;
        }
    }
}

void initial(void)
{
     asm(" setc INTM");                  //禁止中断
     asm(" clrc SXM");                   //清标志位
     asm(" clrc OVM");                       //OVM清零,累加器中结果正常溢出
     asm(" clrc CNF");                   //CNF清零,B0被设置为数据存储区
}

void sysinit(void)    
{
     *WDCR=0x68 ;                    //看门狗定时控制寄存器
     *SCSR1=0x81fe;                   //系统控制及状态寄存器1,CPU时
钟频率设置,设为40MHZ
     *XINT1CR=*XINT2CR=0x8006;      //禁止外部中断
     //*WSGR=0x0000;                  //设置外部存储器的接口
}

void intinit(void)
{
              
     *IFR=0x003f;                       //清所有系统中断标志
     *IMR=0x0002;                       //开 INT2  中断   
    
     *EVAIFRA=0xffff;                      //清事件管理器A所有中断标志 
     *EVAIFRB=0xffff;                       //清事件管理器A所有中断标志 
     *EVAIFRC=0xffff;                      //清事件管理器A所有中断标志 
     *EVAIMRA=0x0200;                   //T1下溢中断  使能T1PINT 
     *EVAIMRB=0;                          //屏蔽所有中断
     *EVAIMRC=0;                          //屏蔽所有中断
}

void evainit(void)
{
     
     *MCRA=*MCRA|0X0fc0;             //设置PWM1~6引脚
     *ACTRA=0X0999;                    //引脚PWM1、3、5低有效,
PWM2、4、6高有效。
     *T1PR=10000;                        //T1周期寄存器 值为10000
     *CMPR1=10000;                      //比较器的比较值,开始为10000,展空比0
     *CMPR2=10000;
     *CMPR3=10000;
     *T1CNT=0;                           //定时器1计数寄存器   
     *DBTCONA=0X08f4;                   //死区周期值为8,是能比较单元1、2、3
的死区操作;死区预分频系数为32,死区
值为7×32=224个CPU时钟周期,CPU时钟周期为50ns,定时器周期为7×32×25ns 
     *COMCONA=0X8200;                 //比较控制寄存器A 允许比较,下溢重载
     *T1CON=0x0842;                  //定时器1控制寄存器 F=1,连续增减计数方式
     asm(" clrc INTM");                     //开总中断                               
}

void ADInit(void)                            //初始化设置
{
    *ADCTRL1= 0x0900;                      //设置连续转换模式
    *MAXCONV = 0x0;                          //每次完成转换1个通道
    *CHSELSEQ1=0x0;                          // ADCIN0
    *ADCTRL2= 0x2000;                     //启动转换 
}

void interrupt nothing(void)
{
  asm(" clrc INTM");                           //开总中断
  return;
  }                               
     

void interrupt gptime1(void)
{
    if(k>=N){                            //如果完成了一个完整的正弦脉冲的转换,
重新开始转换一个新的脉冲,从0度开始
        k=0; 
        if(ischange=1){                    //如果ischange被置1,重新计算载波比N
            N=1000*Fs/Fc; 
            ischange=0;
        }                             
    }
    t=k*360/N;                             //计算采样时间点tp的角度
       tm1=gettime(t%360);                     //计算第一相的开启时间ton
    tm2=gettime((t+120)%360);                //计算第二相的开启时间
    tm3=gettime((t+240)%360);                //计算第三相的开启时间
    k++;                                   //用来计算下一个开启时间点
    ADAcount++;                           //计到200,ADC重新采样,计算给定的
                       正弦调制波的频率 
    if(tm1<80)                              //消除窄脉冲
        tm1=0;
    if(tm1>19920)
        tm1=20000;
    *CMPR1=(20000-tm1)/2;               //将开启时间赋给比较寄存器

    if(tm2<80)
        tm2=0;    
    if(tm2>19920)
        tm2=20000; 
    *CMPR2=(20000-tm2)/2; 
    if(tm3<80)
        tm3=0;
    if(tm3>19920)
        tm3=20000;
    *CMPR3=(20000-tm3)/2;

    *EVAIFRA=0xffff;                        // 清事件管理器A所有中断标志 
    asm(" clrc INTM");                      //开总中断 
}

unsigned long int gettime(unsigned long int angle)
{                                            //计算开启时间
    unsigned long int num=0;
    if (angle>=180)
        num=(100000-M*csin[angle-180])/Fs/5;     //其中/5是为了除去放大做法的影响,
包括 sin值放大和计时放大。
    else
        num=(100000+M*csin[angle])/Fs/5; 
    if(num>=20000)
        num=20000;
    if(num<=0)
        num=0;
    return num;
}

使用特权

评论回复
地板
fengyeu|  楼主 | 2007-12-23 21:20 | 只看该作者

在贴个汇编的

《三相交流异步电动机SVPWM开环调速控制程序(硬件法)》

《三相交流异步电动机SVPWM开环调速控制程序(硬件法)》
.include "240x.h"          ; 寄存器地址
.global  _c_int0               ;全局化标号
;--------------------------------------以下定义变量-----------------------------------------------------------
ST0 .set 0                    ;状态寄存器ST0
ST1 .set 1                    ;状态寄存器ST1
.bss TEMP,1                  ;临时变量
.bss SET_F,1                 ;频率调节比,Q16格式(值为0-1,对应0-50Hz)
.bss F_OMEGA,1             ;频率调节比-角频率转换率,Q5格式
.bss OMEGA,1               ;调制波角频率,Q5格式
.bss SET_V,1                 ;参考电压,Q14格式
.bss MAX_V,1                ;最大参考电压幅值1/  ,Q14格式
.bss T_SAMPLE,1             ;采样周期,Q24格式
.bss THETA_H,1              ;参考电压相位角高字,Q12格式
.bss THETA_L,1              ;参考电压相位角低字,Q12格式
.bss THETA_R,1              ;相位角的圆整值,Q12格式
.bss THETA_M,1             ;相位查表值(0-90度),Q12格式
.bss THETA_I,1              ;相角查表索引,Q9格式
.bss SS,1                    ;SIN符号,Q0格式
.bss SC,1                    ;COS符号,Q0格式
.bss SIN_INDX,1             ;SIN表索引,Q0格式
.bss SIN_ENTRY,1            ;SIN表入口地址
.bss SIN_END,1              ;SIN表结束地址
.bss SIN_THETA,1            ;SINθ值,Q14格式
.bss COS_THETA,1            ;COSθ值,Q14格式
.bss UA,1                    ;参考电压D轴分量UA,Q12格式
.bss UB,1                    ;参考电压Q轴分量UB,Q12格式
.bss THETA_S,1               ;θ-扇区数转换系数,Q15格式
.bss SECTOR,1                ;参考电压所在的扇区数,Q0格式
.bss THETA_90,1               ;90度,Q12格式
.bss THETA_180,1              ;180度,Q12格式
.bss THETA_270,1              ;270度,Q12格式
.bss THETA_360,1              ;360度,Q12格式
.bss DEC_MS,24               ;6个逆阵,Q14格式
.bss T1_PERIODS,1            ;定时器1周期值,Q5格式
.bss CMP_1,1                 ;第1基本矢量,Q0格式
.bss CMP_2,1                 ;第2基本矢量,Q0格式
.bss SVPAT,1                  ; ACTRA的空间矢量字
            .bss  ACCH,1                  ;ACC高字保存单元
            .bss  ACCL,1                   ;ACC低字保存单元
            .bss  AR0_SAVE,1              ;AR0保存单元
            .bss  P_HI,1                   ;P寄存器高字保存单元
            .bss  P_LO,1                   ;P寄存器低字保存单元
; -------------------------------------CONTEXT段,定义保护现场数据区---------------------------
ST0_SAVE  .usect ".context",1   ;状态寄存器ST0保存单元
ST1_SAVE  .usect ".context",1   ;状态寄存器ST1保存单元
;--------------------------------------定义主向量段------------------------------------------------------
.sect  ".vectors"              ;定义主向量段
RESET  B  _c_int0           ;地址0000H,复位,优先级1
INT1   B  PHANTOM        ;地址0002H,INT1,优先级4
INT2   B  _C_INT2           ;地址0004H,INT2,优先级5
INT3   B  PHANTOM        ;地址0006H,INT3,优先级6
INT4   B  PHANTOM        ;地址0008H,INT4,优先级7
INT5   B  PHANTOM        ;地址000AH,INT5,优先级8
INT6   B  PHANTOM        ;地址000CH,INT6,优先级9 
RESERVED  B  PHANTOM            ;地址000EH,测试,优先级10
SW_INT8   B  PHANTOM        ;地址0010H,自定义软中断
SW_INT9   B  PHANTOM        ;地址0012H,自定义软中断
SW_INT10  B  PHANTOM        ;地址0014H,自定义软中断
SW_INT11  B  PHANTOM        ;地址0016H,自定义软中断
SW_INT12  B  PHANTOM        ;地址0018H,自定义软中断
SW_INT13  B  PHANTOM        ;地址001AH,自定义软中断
SW_INT14  B  PHANTOM        ;地址001CH,自定义软中断
SW_INT15  B  PHANTOM        ;地址001EH,自定义软中断
SW_INT16  B  PHANTOM        ;地址0020H,自定义软中断
TRAP       B  PHANTOM            ;地址0022H,TRAP矢量
NMI             B  PHANTOM            ;地址0024H,NMI,优先级3
EMU_TRAP B  PHANTOM            ;地址0026H,仿真Trap,优先级2
SW_INT20  B  PHANTOM        ;地址0028H,自定义软中断
SW_INT21  B  PHANTOM        ;地址002AH,自定义软中断
SW_INT22  B  PHANTOM        ;地址002CH,自定义软中断
SW_INT23  B  PHANTOM        ;地址002EH,自定义软中断
SW_INT24  B  PHANTOM        ;地址0030H,自定义软中断
SW_INT25  B  PHANTOM        ;地址0032H,自定义软中断
SW_INT26  B  PHANTOM        ;地址0034H,自定义软中断
SW_INT27  B  PHANTOM        ;地址0036H,自定义软中断
SW_INT28  B  PHANTOM        ;地址0038H,自定义软中断
SW_INT29  B  PHANTOM        ;地址003AH,自定义软中断
SW_INT30  B  PHANTOM        ;地址003CH,自定义软中断
SW_INT31  B  PHANTOM        ;地址003EH,自定义软中断
;--------------------------------------定义子向量段----------------------------------------------------------
.sect  ".pvecs"                ;定义子向量段
PVECTORS    B    PHANTOM            ;偏移地址0000H 
            B    PHANTOM              ;偏移地址0001H
            B    PHANTOM            ;偏移地址0002H
            B    PHANTOM            ;偏移地址0003H
            B    PHANTOM            ;偏移地址0004H
            B    PHANTOM            ;偏移地址0005H
            B    PHANTOM            ;偏移地址0006H
            B    PHANTOM            ;偏移地址0007H
            B    PHANTOM            ;偏移地址0008H
            B    PHANTOM            ;偏移地址0009H
            B    PHANTOM            ;偏移地址000AH
            B    PHANTOM            ;偏移地址000BH
            B    PHANTOM            ;偏移地址000CH
            B    PHANTOM            ;偏移地址000DH
            B    PHANTOM            ;偏移地址000EH
            B    PHANTOM            ;偏移地址000FH  
            B    PHANTOM            ;偏移地址0010H
            B    PHANTOM            ;偏移地址0011H
            B    PHANTOM            ;偏移地址0012H
            B    PHANTOM            ;偏移地址0013H
            B    PHANTOM            ;偏移地址0014H
            B    PHANTOM            ;偏移地址0015H
            B    PHANTOM            ;偏移地址0016H
            B    PHANTOM            ;偏移地址0017H 
            B    PHANTOM            ;偏移地址0018H
            B    PHANTOM            ;偏移地址0019H 
            B    PHANTOM            ;偏移地址001AH
            B    PHANTOM            ;偏移地址001BH
            B    PHANTOM            ;偏移地址001CH
            B    PHANTOM            ;偏移地址001DH
            B    PHANTOM            ;偏移地址001EH
            B    PHANTOM            ;偏移地址001FH
            B    PHANTOM            ;偏移地址0020H
            B    PHANTOM            ;偏移地址0021H 
            B    PHANTOM            ;偏移地址0022H
            B    PHANTOM            ;偏移地址0023H
            B    PHANTOM            ;偏移地址0024H
            B    PHANTOM            ;偏移地址0025H
            B    PHANTOM            ;偏移地址0026H 
            B    PHANTOM            ;偏移地址0027H 
            B    PHANTOM            ;偏移地址0028H
            B    T1UF_ISR            ;偏移地址0029H
            B    PHANTOM            ;偏移地址002AH
            B    PHANTOM            ;偏移地址002BH
            B    PHANTOM            ;偏移地址002CH
            B    PHANTOM            ;偏移地址002DH
            B    PHANTOM            ;偏移地址002EH
            B    PHANTOM            ;偏移地址002FH 
            B    PHANTOM            ;偏移地址0030H
            B    PHANTOM            ;偏移地址0031H
            B    PHANTOM            ;偏移地址0032H
            B    PHANTOM            ;偏移地址0033H
            B    PHANTOM            ;偏移地址0034H
            B    PHANTOM            ;偏移地址0035H
            B    PHANTOM            ;偏移地址0036H
            B    PHANTOM            ;偏移地址0037H
            B    PHANTOM            ;偏移地址0038H
            B    PHANTOM            ;偏移地址0039H
            B    PHANTOM            ;偏移地址003AH
            B    PHANTOM            ;偏移地址003BH
            B    PHANTOM            ;偏移地址003CH
            B    PHANTOM            ;偏移地址003DH
            B    PHANTOM            ;偏移地址003EH
            B    PHANTOM            ;偏移地址003FH
            B    PHANTOM            ;偏移地址0040H
            B    PHANTOM            ;偏移地址0041H
;--------------------------------------以下是主程序------------------------------------------------------
.text
;--------------------------------------系统初始化程序--------------------------------------------------
_c_int0    
            SETC   INTM               ; 禁止中断
CLRC  CNF                 ;B0为数据存储区
LDP    #224
SPLK   #0000001000000100B,SCSR1 ;CLKIN 10M,CLKOUT 20M
SPLK   #68H,WDCR            ;不用看门狗
LDP    #225
LACC  MCRA
OR     #0FC0H             ;设置PWM1-6引脚
SACL   MCRA
;--------------------------------------中断初始化程序--------------------------------------------------
LDP    #0  
SPLK   #0FFH,IFR            ; 清所有系统中断标志
SPLK   #00000010B,IMR      ; 开INT2中断
LDP    #232         
SPLK   #0FFFH,EVAIFRA     ; 清事件管理器A所有中断标志
SPLK   #0FH,EVAIFRB 
SPLK   #0FH,EVAIFRC 
SPLK   #0200H,EVAIMRA     ; 开T1下溢中断
SPLK   #0,EVAIMRB          ; 屏蔽所有中断
SPLK   #0,EVAIMRC          ; 屏蔽所有中断
;--------------------------------------初始化事件管理器A程序--------------------------------------
SPLK   #500,T1PR           ; T1周期值=50 us/50ns/2=500
SPLK   #500,CMPR1         ; 占空比初值 0%
SPLK   #500,CMPR2
SPLK   #500,CMPR3
SPLK   #0000011001100110B,ACTRA  ; 引脚PWM1,3,5高有效,2,4,6低有效
SPLK   #01F4H,DBTCONA     ; 死区时间1*32*50ns=1.6us
SPLK   #1001001000000000B,COMCONA  ;允许比较,使用硬件空间矢量
SPLK   #1000100000000010B,T1CON ;连续增减计数方式,预分频=1
;--------------------------------------变量初始化程序--------------------------------------------------
            LDP    #6                       ; 指向B1
SPLK   #0347H,T_SAMPLE      ;采样周期=50us *224=839秒=347H, Q24格式
SPLK   #16000,T1_PERIODS       ;T1周期值的Q5格式,500*32
SPLK   #11585,MAX_V           ; 最大参考电压幅值1/ ,Q14格式
SPLK   #0,SET_F                ; SET F=0
SPLK   #10053,F_OMEGA        ;频率调节比-角频率转换率,Q5格式
                      ;当SET_F=1时,对应最大角频率2π50Hz*25=10053
SPLK   #0,THETA_L             ;θ低字,Q12格式
SPLK   #0,THETA_H             ; θ高字,Q12格式
LAR   AR0,#THETA_90          ; 传送常用角度和逆阵数据
LAR   AR1,#(28-1)              ; 28个
LACC  #ANGLES_              ; 指向源
LARP  AR0 
INIT_TBL   
            TBLR  *+,AR1                  ; 下一个
ADD   #1                       ; 下一个地址
BANZ  INIT_TBL,AR0            ;AR1=0结束 
SPLK   #29335,THETA_I           ; 相角查表索引,180/π,Q9格式
SPLK   #31291,THETA_S          ; θ-扇区数转换系数,6/(2π),Q15格式
SPLK  #SIN_ENTRY_,SIN_ENTRY    ;SIN表起始地址
SPLK  #(SIN_ENTRY_+90),SIN_END  ;SIN表结束地址
LDP   #232
SPLK   #0000100001000010B,T1CON  ;使能T1
CLRC  INTM                     ; 开总中断
;--------------------------------------主循环程序(SET_F由外部输入)---------------------------------
MAIN_LOOP   
            LDP  #6
LT    SET_F                  ; 将频率调节比(Q16格式)转换成角频率
MPYU  F_OMEGA               ; Q21
PAC                          ; 积送ACC, Q5格式
SACH  OMEGA               ; 保存角频率,Q5格式
            LT    SET_F                   ;将频率调节比(Q16格式)转换成参考电压
MPYU  MAX_V                 ; Q16*Q14=Q30
PAC 
SACH  SET_V                ; 保存参考电压幅值,Q14格式
B     MAIN_LOOP              ; 循环
;--------------------------------------假中断处理----------------------------------------------------------
PHANTOM  
            CLRC     INTM 
            RET
;--------------------------------------T1下溢中断处理子程序-----------------------------------------
_C_INT2    
            SST   #ST0,ST0_SAVE          ; 保存现场ST0
SST   #ST1,ST1_SAVE          ; 保存ST1
LDP   #6 
SACH  ACCH 
SACL  ACCL                 ; 保存ACC
SPH    P_HI 
SPL   P_LO                    ; 保存 P
MPY   #1                      ; P<=T
SPL   T_SAVE                 ; 保存 T 
SAR   AR0,AR0_SAVE          ; 保存AR0
CLRC  SXM
LDP   #224  
LACC  PIVR                  ;读偏移地址
SUB   #029H                  ; T1 下溢中断?
BCND    T1UF_ISR,EQ           ;是下溢中断跳T1UF_ISR
REST       
            LDP   #6                     ;否则恢复现场
LAR   AR0, AR0_SAVE          ; 恢复AR0
LT    P_LO                     ;恢复P
MPY   #1  
LPH   P_HI  
LT    T_SAVE                  ;恢复T
LACC  ACCH,16 
ADDS  ACCL                  ;恢复ACC
LDP   #0                      ;指向B2
LST   #ST1,ST1_SAVE           ; 恢复ST1
LST   #ST0,ST0_SAVE           ; 恢复ST0
CLRC  INTM                   ; 开中断
RET                            ; 返回
T1UF_ISR   
            LDP   #232
SPLK   #0FFFH,EVAIFRA          ; 清中断标志
LDP    #6                      ; 计算转角增量
LT     OMEGA                  ; Q5
MPY    T_SAMPLE               ;Q5*Q24
PAC                            ;积存ACC, Q13
SFR                            ; 右移一位成Q12格式
ADD     THETA_H,16            ; Q12 
ADDS    THETA_L               ;计算绝对位置
SACH    THETA_H               ;保存
SACL    THETA_L 
BCND   CHK_UPLIM,GEQ         ;如果大于0检查上限
ADD     THETA_360,16           ;否则与2π比较,Q12 
SACH     THETA_H               ; 保存
B        RND_THETA     
CHK_UPLIM  
            SUB     THETA_360,16           ;与2π比较,Q12 
BCND   REST_THETA,LEQ        ; 如果在范围内恢复THETA_H
SACH    THETA_H     
B        RND_THETA 
REST_THETA  
            ADD    THETA_360,16         ; 恢复THETA_H
RND_THETA  
            ADD     #1,15                  ; 圆整并保留高字
SACH     THETA_R               ;保存
LACC     #1                      ;假设THETA_H在第一象限
SACL     SS                     ; SIN符号=1
SACL     SC                     ; COS符号=1
LACC     THETA_R 
SACL     THETA_M               ; 存入THETA_M
SUB      THETA_90 ;
BCND    E_Q,LEQ              ;在第一象限则跳转
SPLK     #-1,SC                ; COS符号=-1
LACC     THETA_180 
SUB      THETA_R              ; 180-θ
SACL    THETA_M              ;存入THETA_M
BCND    E_Q,GEQ             ;在第二象限则跳转
SPLK     #-1,SS                ;SIN符号=-1
LACC    THETA_R 
SUB      THETA_180           ;THETA-180
SACL    THETA_M             ;存入THETA_M
LACC    THETA_270 
SUB      THETA_R 
BCND    E_Q,GEQ             ;在第三象限则跳转
SPLK    #1,SC                 ; COS符号=1
LACC    THETA_360
SUB      THETA_R 
SACL    THETA_M             ; 在第四象限
E_Q        
            LT       THETA_M             ; Q12.计算查表索引
MPYU     THETA_I              ; Q12*Q9
PAC                           ; Q5
SACH    SIN_INDX            ; Q5
LACC    SIN_INDX,11          ;左移11位
SACH    SIN_INDX            ;相当于右移5位变成Q0格式,即整数
LACC    SIN_ENTRY           ;查SIN表
ADD     SIN_INDX
TBLR    SIN_THETA 
LACC    SIN_END 
SUB      SIN_INDX ;
TBLR    COS_THETA ;
LT       SS                    ;查COS表
MPY     SIN_THETA            ;修改符号,Q14
PAC 
SACL    SIN_THETA            ; 左移16位保存,Q14
LT       SC 
MPY     COS_THETA           ; 修改符号, Q14
PAC 
SACL    COS_THETA           ;左移16位保存,Q14
LT       SET_V                ;开始计算UA , UB 
MPY     COS_THETA            ; Q14*Q14
PAC                           ;存入ACC, Q12
SACH    UA                  ; UA ,Q12格式
MPY     SIN_THETA           ; Q14*Q14
PAC                           ; 存入ACC, Q12
SACH    UB                  ; UB, Q12格式
LT      THETA_R               ; Q12格式.确定扇区
MPY     THETA_S              ; Q12*Q15
PAC
SACH    SECTOR 
LACC    SECTOR,5 
SACH    SECTOR              ; 相当于右移11位变成Q0格式(整数)
LACC    #DEC_MS            ;逆阵数据首地址
ADD     SECTOR,2 
SACL    TEMP               ;产生地址指针
LAR     AR0,TEMP           ; 指向逆阵表
LT       UA                  ; Q12格式.计算UA*M(1,1)+UB*M(1,2)
MPY     *+                   ; M(1,1) UA, Q12*Q14
PAC                          ; Q10格式
LT       UB                 ; Q12
MPY      *+                 ; M(1,2) UB, Q12*Q14
APAC                         ; 0.5*C1, Q10
BCND    CMP1BIG0,GEQ      ; 如果大于0继续
LACC     #0                  ; 否则0
CMP1BIG0  
            SACH    TEMP                ; 0.5*C1,Q10格式
LT       TEMP                ; Q10格式
MPY     T1_PERIODS          ; Q10*Q5
PAC                          ; Q15格式
ADD      #1,15               ; 防止C1=0
SACH     CMP_1,1            ; 0.5*C1*TP,Q0格式
LT       UA                  ;计算UA*M(2,1)+UB*M(2,2)
MPY      *+                  ; M(2,1) UA,Q12*Q14
PAC                           ; Q10格式
LT       UB                   ; Q12格式
MPY     *+                   ; M(2,2) UB: Q12*Q14
APAC                          ; 0.5*C2,Q10
BCND   CMP2BIG0,GEQ        ; 如果大于0继续
LACC   #0                     ;否则0
CMP2BIG0  
            SACH   TEMP                  ; 0.5*C2,Q10格式
LT       TEMP                 ; Q10格式
MPY     T1_PERIODS          ; Q10*Q5 
PAC                           ; Q15格式
ADD     #1,15                 ; 防止C2 = 0
SACH    CMP_2,1               ; 0.5*C2*TP,Q0格式
LACC    #CCKWISE_          ; ACTRA寄存器值表首地址
ADD      SECTOR            ; 查表地址
TBLR     SVPAT     
LAR      AR0,#ACTRA        ;指向ACTRA
LACC     *                ; 读ACTRA
AND      #0FFFH          ; 清高四位
OR       SVPAT             ; 高四位赋新值
SACL     *                ; 更新ACTRA
LAR      AR0,#CMPR1     ; 指向CMPR1
LACC     CMP_1
SACL     *+               ; 更新CMPR1, 指向CMPR2
ADD      CMP_2 
SACL     *                ; 更新CMPR2
SUB      #500              ;减T1周期值,CMPR2是否超限
BCND    IN_LMT,LEQ       ;没超跳转
SPLK     #500,*            ;否则赋T1周期值
IN_LMT     
            B         REST              ; 返回
.data                      
;--------------------------------------数据段------------------------------------------------------------------
ANGLES_   
            .word 01922H                ; π/2,     Q12格式
.word 03244H                ; π, Q12格式
.word 04B66H                ; 3π/2, Q12格式
.word 06488H                ; 2π, Q12格式
.word 20066           ; 矩阵A的逆阵数据,每一个逆阵有4个数据,Q14格式
.word –11585               ; 按参考电压所在的扇区索引
.word 0
.word 23170
.word 20066
.word 11585
.word -20066
.word 11585
.word 0
.word 23170
.word -20066
.word -11585
.word -20066
.word 11585
.word 0
.word -23170
.word -20066
.word -11585
.word 20066
.word -11585
.word 0
.word -23170
.word 20066
.word 11585
CCKWISE_   
             .word 0001000000000000B      ;逆时针旋转时ACTR高4位值,按扇区索引
 .word 0011000000000000B
             .word 0010000000000000B
             .word 0110000000000000B
             .word 0100000000000000B
             .word 0101000000000000B
SIN_ENTRY_ 
             .word 0                       ; 0-90度SIN值表,Q14格式
             .word 286,572,857,1143,1428
             .word 1713,1997,2280,2563,2845
           .word 3126,3406,3686,3964,4240
           .word 4516,4790,5063,5334,5604
           .word 5872,6138,6402,6664,6924
           .word 7182,7438,7692,7943,8192
           .word 8438,8682,8923,9162,9397
           .word 9630,9860,10087,10311,10531
           .word 10749,10963,11174,11381,11585
           .word 11786,11982,12176,12365,12551
           .word 12733,12911,13085,13255,13421
           .word 13583,13741,13894,14044,14189
           .word 14330,14466,14598,14726,14849
           .word 14968,15082,15191,15296,15396
           .word 15491,15582,15668,15749,15826
           .word 15897,15964,16026,16083,16135
           .word 16182,16225,16262,16294,16322
           .word 16344,16362,16374,16382,16384
 .end


使用特权

评论回复
5
snakeemail| | 2007-12-24 09:01 | 只看该作者

还有本dsp2000入门与提高,也看看吧

使用特权

评论回复
6
是学生| | 2007-12-28 16:22 | 只看该作者

ddddd

ddddd

使用特权

评论回复
7
iprogramer| | 2011-4-4 17:08 | 只看该作者
谢谢谢

使用特权

评论回复
8
jobo007| | 2011-5-27 13:16 | 只看该作者
非常感谢

使用特权

评论回复
9
xiaofei191| | 2011-6-7 15:30 | 只看该作者
不错

使用特权

评论回复
10
eydj2008| | 2011-6-8 09:45 | 只看该作者
看了半天没理解  不知道网上搜了一个 对不对
SPWM与SVPWM的比较  
SPWM原理  正弦PWM的信号波为正弦波,就是正弦波等效成一系列等幅不等宽的矩形脉冲波形,其脉冲宽度是由正弦波和三角波自然相交生成的.正弦波波形产生的方法有很多种,但较典型的主要有:对称规则采样法、不对称规则采样法和平均对称规则采样法三种.第一种方法由于生成的PWM脉宽偏小,所以变频器的输出电压达不到直流侧电压的倍;第二种方法在一个载波周期里要采样两次正弦波,显然输出电压高于前者,但对于微处理器来说,增加了数据处理量当载波频率较高时,对微机的要求较高;第三种方法应用最为广泛的,它兼顾了前两种方法的优点. SPWM虽然可以得到三相正弦电压,但直流侧的电压利用率较低, 最大是直流侧电压的倍,这是此方法的最大的缺点.


SVPWM原理   电压空间矢量PWM(SVPWM)的出发点与SPWM不同,SPWM调制是从三相交流电源出发,其着眼点是如何生成一个可以调压调频的三相对称正弦电源.而SVPWM是将逆变器和电动机看成一个整体,用八个基本电压矢量合成期望的电压矢量,建立逆变器功率器件的开关状态,并依据电机磁链和电压的关系,从而实现对电动机恒磁通变压变频调速.若忽略定子电阻压降,当定子绕组施加理想的正弦电压时,由于电压空间矢量为等幅的旋转矢量,故气隙磁通以恒定的角速度旋转,轨迹为圆形. SVPWM比SPWM的电压利用率高15%,这是两者最大的区别,但两者并不是孤立的调制方式,典型的SVPWM是一种在SPWM的相调制波中加入了零序分量后进行规则采样得到的结果,因此SVPWM有对应SPWM的形式.反之,一些性能优越的SPWM方式也可以找到对应的SVPWM算法,所以两者在谐波的大致方向上是一致的,只不过SPWM易于硬件电路实现,而SVPWM更适合于数字化控制系统.

使用特权

评论回复
11
hxy6951| | 2011-6-8 12:46 | 只看该作者
看看

使用特权

评论回复
12
lvgyl| | 2012-8-27 20:40 | 只看该作者
多谢楼主

使用特权

评论回复
13
uuniao| | 2012-8-29 08:46 | 只看该作者
这个太老了,还是汇编的,TI网上有C语言的,更适合学习……

使用特权

评论回复
14
hit1008102| | 2012-9-2 13:24 | 只看该作者
好东西,留着有用

使用特权

评论回复
15
hit1008102| | 2012-9-2 13:24 | 只看该作者
好东西,留着有用:)

使用特权

评论回复
16
x125852095| | 2013-5-22 14:51 | 只看该作者
辛苦楼主,必须力顶

使用特权

评论回复
17
zhangmangui| | 2013-5-23 09:05 | 只看该作者
x125852095 发表于 2013-5-22 14:51
辛苦楼主,必须力顶

看到过有人找过这方面的资料

使用特权

评论回复
18
zhouwei0823| | 2013-5-29 17:39 | 只看该作者
曾经也做过这个!

使用特权

评论回复
19
zdw976047749| | 2014-3-5 15:40 | 只看该作者
好东西啊,多谢楼主。

使用特权

评论回复
20
188598686| | 2014-3-6 16:32 | 只看该作者
可以用?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

446

帖子

0

粉丝