• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

矢量变频器软件算法

大家好:
     没有想到在电源论坛里还有这么多的变频器爱好者和一些变频器高手,不过好象本人看到做硬件的多,做软件的几乎没有??
     不知道是没有人做软件还是因为没有开头打开这个话题,如果是后者的话,那我来开个头吧,不过也希望更多的从事硬件的朋友多来参与,毕竟没有硬件软体也是法实现的.
全部回复(16)
正序查看
倒序查看
2006-05-16 11:21
以下是采用TMS320LF2407A的主体程序算法,希望大家能来支持.
0
回复
2006-05-16 11:26
;--------------------------------------主循环程序(SET_F由外部输入)---------------------------------
MAIN_LOOP  
            LDP  #6
LT    SET_F                  ; 将频率调节比(Q15格式)转换成角频率
MPY  F_OMEGA               ; Q20
PAC                          ; 积送ACC, Q4格式
SACH  OMEGA,1               ; 保存角频率,Q5格式
LACC  OMEGA
            LT    SET_F                   ;将频率调节比(Q15格式)转换成参考电压
MPY  MAX_V                 ; Q15*Q14=Q29
PAC
SACH  SET_V,1                ; 保存参考电压幅值,Q14格式
B     MAIN_LOOP              ; 循环
;--------------------------------------假中断处理----------------------------------------------------------
PHANTOM  
            CLRC     INTM
            RET
;--------------------------------------T1下溢中断处理子程序-----------------------------------------
_C_INT2    
            SST   #ST0,ST0_SAVE          ; 保存现场ST0
SST   #ST1,ST1_SAVE          ; 保存ST1
LDP   #5
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
LDP   #224  
LACC  PIVR                  ;读偏移地址
SUB   #029H                  ; T1 下溢中断?
CC    T1UF_ISR,EQ           ;是下溢中断跳T1UF_ISR
REST      
            LDP   #5                     ;否则恢复现场
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   #0200H,EVIFRA          ; 清中断标志
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.计算查表索引
MPY     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,1                 ; UA ,Q13格式
MPY     SIN_THETA           ; Q14*Q14
PAC                           ; 存入ACC, Q12
SACH    UB,1                  ; UB, Q13格式
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                  ; Q13格式.计算UA*M(1,1)+UB*M(1,2)
MPY     *+                   ; M(1,1) UA, Q13*Q14
PAC                          ; Q11格式
LT       UB                 ; Q11
MPY      *+                 ; M(1,2) UB, Q13*Q14
APAC                         ; 0.5*C1, Q11
BCND    CMP1BIG0,GEQ      ; 如果大于0继续
LACC     #0                  ; 否则0
CMP1BIG0  
            SACH    TEMP                ; 0.5*C1,Q11格式
LT       TEMP                ; Q11格式
MPY     T1_PERIODS          ; Q11*Q5
PAC                          ; Q0格式
ADD      #1,16               ; 防止C1=0
SACH     CMP_1              ; 0.5*C1*TP,Q0格式
LT       UA                  ;计算UA*M(2,1)+UB*M(2,2)
MPY      *+                  ; M(2,1) UA,Q13*Q14
PAC                           ; Q11格式
LT       UB                   ; Q13格式
MPY     *+                   ; M(2,2) UB: Q13*Q14
APAC                          ; 0.5*C2,Q11
BCND   CMP2BIG0,GEQ        ; 如果大于0继续
LACC   #0                     ;否则0
CMP2BIG0  
            SACH   TEMP                  ; 0.5*C2,Q11格式
LT       TEMP                 ; Q11格式
MPY     T1_PERIODS          ; Q11*Q5
PAC                           ; Q0格式
ADD     #1,16                 ; 防止C2 = 0
SACH    CMP_2                ; 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
0
回复
feifeiyu
LV.3
4
2006-05-22 18:34
楼主,即然是交流,就该整理个flow chart,或者C的也行啊,发个ASM,大家没有那么多时间看啊,何况用这种DSP的有多少啊?
0
回复
yrr_2002
LV.1
5
2006-05-23 14:45
@vector_inveter
;--------------------------------------主循环程序(SET_F由外部输入)---------------------------------MAIN_LOOP              LDP  #6LT    SET_F                  ;将频率调节比(Q15格式)转换成角频率MPY  F_OMEGA              ;Q20PAC                          ;积送ACC,Q4格式SACH  OMEGA,1              ;保存角频率,Q5格式LACC  OMEGA            LT    SET_F                  ;将频率调节比(Q15格式)转换成参考电压MPY  MAX_V                ;Q15*Q14=Q29PACSACH  SET_V,1                ;保存参考电压幅值,Q14格式B    MAIN_LOOP              ;循环;--------------------------------------假中断处理----------------------------------------------------------PHANTOM              CLRC    INTM            RET;--------------------------------------T1下溢中断处理子程序-----------------------------------------_C_INT2                SST  #ST0,ST0_SAVE          ;保存现场ST0SST  #ST1,ST1_SAVE          ;保存ST1LDP  #5SACH  ACCHSACL  ACCL                ;保存ACCSPH    P_HISPL  P_LO                    ;保存PMPY  #1                      ;P
先谢谢了,楼主何不再把算法给大家讲一下,比如这个程序是如何工作的,里面的SIN表是如何得来的,基本原理是什么.
0
回复
2006-05-26 16:25
@feifeiyu
楼主,即然是交流,就该整理个flowchart,或者C的也行啊,发个ASM,大家没有那么多时间看啊,何况用这种DSP的有多少啊?
人气太低了,也没有人搞, 没意思
0
回复
2006-05-31 23:49
@vector_inveter
人气太低了,也没有人搞,没意思
**此帖已被管理员删除**
0
回复
topman
LV.2
8
2006-06-22 17:10
@vector_inveter
以下是采用TMS320LF2407A的主体程序算法,希望大家能来支持.
我们用TMS240F2812
0
回复
yaron88
LV.3
9
2006-06-22 22:27
@hejianmonk
**此帖已被管理员删除**
这个程序不是矢量控制,也不完整.只是个SVPWM实验程序而已,至多也只能用在变频空调上,不过没有PFC控制恐怕以后空调上也不能用了
0
回复
jsmmp
LV.3
10
2006-06-28 23:06
@vector_inveter
人气太低了,也没有人搞,没意思
几年前搞过,现在看这些程序还是一头雾水.

感觉还是用C语言写可读性强.

是否有试过用C写的矢量控制或直接转矩控制程序吗?

不知道是否有支持2407的C语言开发系统?
0
回复
nihaohong
LV.4
11
2006-06-29 08:13
@jsmmp
几年前搞过,现在看这些程序还是一头雾水.感觉还是用C语言写可读性强.是否有试过用C写的矢量控制或直接转矩控制程序吗?不知道是否有支持2407的C语言开发系统?
当然有.TI的CCS支持C编程.
0
回复
yaron88
LV.3
12
2006-06-29 08:35
@nihaohong
当然有.TI的CCS支持C编程.
TI 公司提供的电机控制程序很多都是汇编程序
这个程序是最简单的了!
0
回复
nihaohong
LV.4
13
2006-06-29 18:23
@yaron88
TI公司提供的电机控制程序很多都是汇编程序这个程序是最简单的了!
自己用C编程就是了,为什么一定要用TI提供的.
0
回复
yaron88
LV.3
14
2006-06-30 09:33
@nihaohong
自己用C编程就是了,为什么一定要用TI提供的.
老兄,这是2407,不是2812.你用过2407没有?
0
回复
jsmmp
LV.3
15
2006-07-01 00:17
@yaron88
TI公司提供的电机控制程序很多都是汇编程序这个程序是最简单的了!
很多人都是靠它起步的啊.

但是时间隔久了,真的容易忘的.

哪里有TI的电机控制C样本程序下载吗? 要能读读肯定长见识.
0
回复
yaron88
LV.3
16
2006-07-01 11:30
@jsmmp
很多人都是靠它起步的啊.但是时间隔久了,真的容易忘的.哪里有TI的电机控制C样本程序下载吗?要能读读肯定长见识.
/*regulator reference*/
int w_kp,w_ki;
int i_kp,i_ki;
int i_kp,i_ki;
int if_kp,if_ki;  
             
/*fundmental variables*/
int ua,ub,uc;
int ud,uq;
int ia,ib,ic;

int theta=0;  
int pos=0,pos2;

int i=0,j=0;       //用于设置缓冲时间
int ii=0,jj=0;          //用于速度给定
int iii=0,jjj=0;   //用于求出速度
int iiii=0,jjjj=0;   //用于求出id,iq

int bFirstTime=1;  
int t=5;                    /*标示程序是否在运行*/    
int bStop=0;

long int temp,temp2,temp3;  /*临时的长整数*/
int n;                /*临时的整数*/      

long int MaxU,MaxI;
int UU;
int error=0;

  
int K[2][5]={{100,200,300,500,1000},  
               {10,15,20,30,50}     /* i_kp*/
              };  
            
int a=0,b=0,c=0,d=0;  

int bAuto=0;
int direct=1;
int kk=8;

void  initial()
{
   asm(" clrc      SXM"); // 符号位扩展
   asm(" clrc     OVM"); // 累加器中结果正常溢出
   asm(" clrc      CNF"); // B0被配置为数据存储空间
   *SCSR1=0x83CE; // CLKIN=6M,CLKOUT=4*CLKIN=24M
   *WDCR=0x0E8;
   *IMR=0x0001; //  允许INT1中断
   *IFR=0x0FFFF; //  清除全部中断标志,"写1清0"
}

void  ADINIT()
{
   *T4CNT=0; // T4计数器清0
   *T4CON=0X150C; // T4为连续增计数模式,32分频,且选用内部时钟源
   *T4PER=1830; // 设置T4的周期寄存器
   *GPTCONB=0X400; // T4周期中断标志触发AD转换
   *EVBIMRB=0X01; // 清除EVB中断标志,写"1"清0
   *EVBIFRB=0X0FFFF; // 清除EVB中断标志,写"1"清0
   *ADCTRL1=0X990; // 采样时间窗口预定标位ACQ PS3-ACQ PS0为0,
// 转换时间预定标位CPS为9,AD为启动/停止模式,排
// 序器为级连工作方式,且禁止特殊的两种工作模式
   *ADCTRL2=0X8404; // 可以用EVB的一个事件信号触发AD转换,
// 且用中断模式1
   *MAXCONV=3; // 4通道
   *CHSELSEQ1=0XA720;
}
// 启动AD转换子程序(通过启动定时器4的方式间接启动)
void  ADSOC()
{
   *T4CON=*T4CON|0X40;// 启动定时器4
}
// 若是其它中断则直接返回子程序
void interrupt nothing()
{
   return;
}

void  ValueInit()
{
    
    
    if_ki=0;    /*5411.8->42*//*周期为1/1024秒时,21*/
    w_ki=0;/*2032.9->798*/ /*周期为1/1024秒时,399*/
    i_ki=0;/*654.7*->82*/ /*周期为1/1024秒时,41*/
    
    if_kp=500; /*779.853->3119*/  
    w_kp=200;/*34.56->6949*/
    i_kp=100;/*37.62->2408*/
    
    UU=970;
    w_gd=192;
    id_gd=0;                          
    if_gd=216;  /* 约1.69A */
    MaxU=6925216;
    MaxI=10240; /*20480=10A*/
    
    bAuto=0;
    kk=4;  
}


void  interrupt  adint()
{
          
            int flag;  
           int a_cos,a_sin,b_cos,b_sin,c_cos,c_sin;
           static int id_buf[M],iq_buf[M],if_buf[M],w_buf[16];  
           static long int  sumId=0,sumIq=0,sumIf=0;
            *T4CNT=0X0000;
            *MAINSTART=0;
            *RECSTART=0;
              
           flag=*EVBIFRB&0X01;
           if(flag!=0x01)
           {
             asm(" clrc INTM"); // 允许总中断
             return; // 如果不是定时器1周期中断,则直接返回
           }
           
           if(bAuto)
           {
           ii++;
            if(ii==1500)
            {
            a++;
            if(a==5)
            {
              a=0;
              b++;
            }
            if(b==5)
              b=5;
            //w_kp=K[0][a];
            //i_kp=K[1][b];  
              
            ii=0;
            if(jj            {
              w_gd=W[jj]*direct;
              if_gd=IFGD[jj];
              MaxU=MAXU[jj];
              i_kp=IKP[jj];
              kk=KK[jj];
              jj++;
            }
            else
            {
              if(jj==NUM)
              {
                jj=0;
                direct*=-1;
              }      
            }
            }
            }
            *POSITION=0xff00;
           pos=*POSITION;
          pos2=pos;
          
/********************AD采样值读取***********************************/          
     
            temp=(*RESULT0)>>6;
            temp=(temp*325)>>10;
            if_fk=temp;
              
            temp=(*RESULT1)>>6;
            temp=((temp-449)*609)>>10;
            ia=temp;  
              
              
            temp=(*RESULT2)>>6;
            temp=((temp-449)*609)>>10;
            ib=temp;
              
            temp=(*RESULT3)>>6;
            temp=((temp-449)*609)>>10;
            ic=temp;
          
/*****************************得到位置*******************************************/
            
            if(pos>N)pos-=N;  //512-1024的数处理
    theta=pos-197;
    a_sin=theta;
    a_cos=theta+128;
    b_sin=theta-171;
    b_cos=theta-43;
    c_sin=theta+171;
    c_cos=theta-214;
    if(a_sin<0)a_sin+=N;
    if(a_cos<0)a_cos+=N;
    if(b_cos<0)b_cos+=N;
    if(b_sin<0)b_sin+=N;
    if(c_cos<0)c_cos+=N;
    if(c_sin<0)c_sin+=N;
    
/*****************************得到速度*******************************************/
    
    if(iii<16)            
    {
       w_fk=0;
       w_buf[iii]=pos2;
       iii++;
    }
    else
    {
       w_fk=pos2-w_buf[jjj];
       if(w_fk>700)
         w_fk=w_fk-1024;
       if(w_fk<-700)
         w_fk=w_fk+1024;
       w_fk=w_fk<<1;
       w_buf[jjj]=pos2;
       jjj++;
       if(jjj==16) jjj=0;
    }    
    
/********************************ia,ib,ic变换为id,iq****************************/          
    
    temp=ia;
            temp=temp*MySin[a_cos];
            temp2=ib;
            temp2=temp2*MySin[b_cos];
            temp3=ic;
            temp3=temp3*MySin[c_cos];
temp=(temp+temp2+temp3)*2;
id_fk=temp>>8;    /*得到id_fk,本应移14位,定标减掉6位*/  
    
    temp=ia;
            temp=temp*MySin[a_sin];
            temp2=ib;
            temp2=temp2*MySin[b_sin];
            temp3=ic;
            temp3=temp3*MySin[c_sin];
temp=-(temp+temp2+temp3)*2;
iq_fk=temp>>8;     /*得到iq_fk*,本应移14位,定标减掉6位*/

/********************************id,iq,if滤波**************************************/
          
           if(iiii     {
       id_buf[iiii]=id_fk;
       iq_buf[iiii]=iq_fk;
       if_buf[iiii]=if_fk;
       sumId+=id_fk;
       sumIq+=iq_fk;
       sumIf+=if_fk;
       iiii++;
    }
    else
    {
       sumId=sumId+id_fk-id_buf[jjjj];
       sumIq=sumIq+iq_fk-iq_buf[jjjj];
       sumIf=sumIf+if_fk-if_buf[jjjj];
       id_fk=sumId>>MM;
       iq_fk=sumIq>>MM;
       //if_fk=sumIf>>MM;
       id_buf[jjjj]=id_fk;
       iq_buf[jjjj]=iq_fk;  
       if_buf[jjjj]=if_fk;
       jjjj++;
       if(jjjj==M) jjjj=0;
    }
    
    if(bFirstTime==1)
{
   id_fk=0;
               iq_fk=0;
               if_fk=0;
               bFirstTime=0;
            }                    
            
/************************励磁电流调节器********************************************/
        
   /*if按Q.7/10定标*/
       temp=if_gd-if_fk;
    if(temp>16||temp<-16)
    {  
        if_out=temp*if_kp;  
    }
    else
    {
        if_out=temp*if_kp+if_sum;
        if_sum+=temp*if_ki;    
        if(if_sum>20000)if_sum=20000;
        if(if_sum<0)if_sum=0;
    }
    
    if(if_out>20000)if_out=20000;
    if(if_out<1000)if_out=1000;
   /*Ufm=40V,按Q.9/16定标,=20480*/
    temp=(if_out*51)>>12;      /*(uf/Ufm*256+256)*/
n=temp+256;
*FALPHA=MyAcos[n];       /*得到FALPHA*/       
                 
/*********************************速度调节器***************************************/
    
    temp=w_gd-w_fk;
    temp2=w_fk-w_pre;  
    if((temp2<16)&&(temp2>-16))  
      if((temp>16||temp<-16))
      {
                 w_out=temp*w_kp;
              }
      else
      {
         w_out=temp*w_kp+w_sum;
                 w_sum+=temp*w_ki;
         if(w_sum>MaxI)w_sum=MaxI;
         if(w_sum<-MaxI)w_sum=-MaxI;
      }
      
    if(w_out>MaxI)w_out=MaxI;
    if(w_out<-MaxI)w_out=-MaxI;  
    w_pre=w_fk;
          
/*********************************电流调节器***************************************/     
    /*iq,id按Q.11/16定标*/  
    iq_gd=w_out;
    temp=iq_gd-iq_fk;
            if(temp>256||temp<-256)
            {
      iq_out=temp*i_kp;
    }
    else
    {
      iq_out=temp*i_kp+iq_sum;
      iq_sum+=temp*i_ki;
      if(iq_sum>MaxU)iq_sum=MaxU;
      if(iq_sum<-MaxU)iq_sum=-MaxU;
    }
    
    temp=id_gd-id_fk;
    if(temp>256||temp<-256)
            {
              id_out=temp*i_kp;
            }
    else
    {
      id_out=temp*i_kp+id_sum;
              id_sum+=temp*i_ki;
      if(id_sum>MaxU)id_sum=MaxU;
      if(id_sum<-MaxU)id_sum=-MaxU;
    }
      
/*********************************电压前馈**************************************/
          
            temp=-823;
            temp=temp*iq_gd;
            temp=temp>>9;
            temp=temp*w_gd;
            ud_qk=temp;
            
            temp=796;
            temp=temp*w_gd;
            temp=temp*if_gd;
            temp2=285;
            temp2=temp2*iq_gd;
            uq_qk=(temp>>3)+(temp2>>1);
            
/************************ud,uq/ua,ub,uc********************/     
/*Um=135 V,相电压最大值,按Q.8/16定标,=34572*/

            
   ........................
...........................
...........................
...........................

/****************************检测通讯*********************************************/

            *R_AALPHA=0xff00;
    *R_BALPHA=0xff00;
    *R_CALPHA=0xff00;
    *R_FALPHA=0xff00;
    if((*R_AALPHA!=*AALPHA)||
       (*R_BALPHA!=*BALPHA)||
       (*R_CALPHA!=*CALPHA)||
       (*R_FALPHA!=*FALPHA))
    {
         /*MAINSTOP=0xffff;
         bStop=1;
         DAC=0;*/
         error=error+1;
    }
       
/****************************观测4个量*********************************************/     
    
            if(j<5000)
            {
              j++;    
            }
            else
            {
              if(i              {    
                buffer1[i]=theta;
                buffer2[i]=w_gd;
                buffer3[i]=w_fk;
                
                buffer4[i]=iq_gd;
                buffer5[i]=iq_fk;
                buffer6[i]=iq_out>>9;
                
                buffer7[i]=id_gd;
                buffer8[i]=id_fk;
                buffer9[i]=id_out>>9;
                
                buffer10[i]=ud_qk>>9;
                buffer11[i]=uq_qk>>9;
                buffer12[i]=-ud;
                buffer13[i]=-uq;
                
                buffer14[i]=ua;
                buffer15[i]=ub;
                buffer16[i]=uc;
                
                buffer17[i]=ia;
                buffer18[i]=ib;
                buffer19[i]=ic;
                
                buffer20[i]=if_gd;
                buffer21[i]=if_fk;
                
                buffer22[i]=if_out;
                
                i++;            
              }
              if(i==SIZE)
              {
                 /*MAINSTOP=0xffff;
         /*bStop=1;*/
                 i=SIZE;
              }
            }
            
/***************************观测四路AD********************************************/     
        temp=ia<<2;
    temp=temp+2048;
    DA0=temp;
    
            temp=ia<<2;
    temp=temp+2048;
    DA1=temp;
    
    temp=ia<<2;
    temp=temp+2048;
    DA2=temp;
    
            temp=ia<<2;
    temp=temp+2048;
    DA3=temp;

    DA4=0;
/********************************************************************************/
          
            *ADCTRL2=*ADCTRL2|0X4200; // 复位SEQ1,且清除INT FLAG SEQ1标志写"1"清0
            asm(" NOP");
            asm(" NOP");
            asm(" NOP");
            asm(" NOP");
            t=15-t;
            DAC=t;
            asm(" clrc INTM");
}  

main()
{
   asm(" setc INTM");
   initial( );
   ValueInit( );
   ADINIT( );
   asm(" clrc INTM");
   ADSOC( );  
   while(!(bStop))
   {}
}
这是别人写的程序,给大家看看(这只是其中一部分)
0
回复
2006-07-08 16:59
@yaron88
/*regulatorreference*/intw_kp,w_ki;inti_kp,i_ki;inti_kp,i_ki;intif_kp,if_ki;              /*fundmentalvariables*/intua,ub,uc;intud,uq;intia,ib,ic;inttheta=0;  intpos=0,pos2;inti=0,j=0;      //用于设置缓冲时间intii=0,jj=0;          //用于速度给定intiii=0,jjj=0;  //用于求出速度intiiii=0,jjjj=0;  //用于求出id,iqintbFirstTime=1;  intt=5;                    /*标示程序是否在运行*/    intbStop=0;longinttemp,temp2,temp3;  /*临时的长整数*/intn;                /*临时的整数*/      longintMaxU,MaxI;intUU;interror=0;  intK[2][5]={{100,200,300,500,1000},                {10,15,20,30,50}    /*i_kp*/              };              inta=0,b=0,c=0,d=0;  intbAuto=0;intdirect=1;intkk=8;void  initial(){  asm("clrc      SXM");//符号位扩展  asm("clrc    OVM");//累加器中结果正常溢出  asm("clrc      CNF");//B0被配置为数据存储空间  *SCSR1=0x83CE;//CLKIN=6M,CLKOUT=4*CLKIN=24M  *WDCR=0x0E8;  *IMR=0x0001;//  允许INT1中断  *IFR=0x0FFFF;//  清除全部中断标志,"写1清0"}void  ADINIT(){  *T4CNT=0;//T4计数器清0  *T4CON=0X150C;//T4为连续增计数模式,32分频,且选用内部时钟源  *T4PER=1830;//设置T4的周期寄存器  *GPTCONB=0X400;//T4周期中断标志触发AD转换  *EVBIMRB=0X01;//清除EVB中断标志,写"1"清0  *EVBIFRB=0X0FFFF;//清除EVB中断标志,写"1"清0  *ADCTRL1=0X990;//采样时间窗口预定标位ACQPS3-ACQPS0为0,//转换时间预定标位CPS为9,AD为启动/停止模式,排//序器为级连工作方式,且禁止特殊的两种工作模式  *ADCTRL2=0X8404;//可以用EVB的一个事件信号触发AD转换,//且用中断模式1  *MAXCONV=3;//4通道  *CHSELSEQ1=0XA720;}//启动AD转换子程序(通过启动定时器4的方式间接启动)void  ADSOC(){  *T4CON=*T4CON|0X40;//启动定时器4}//若是其它中断则直接返回子程序voidinterruptnothing(){  return;}void  ValueInit(){            if_ki=0;    /*5411.8->42*//*周期为1/1024秒时,21*/    w_ki=0;/*2032.9->798*//*周期为1/1024秒时,399*/    i_ki=0;/*654.7*->82*//*周期为1/1024秒时,41*/        if_kp=500;/*779.853->3119*/      w_kp=200;/*34.56->6949*/    i_kp=100;/*37.62->2408*/        UU=970;    w_gd=192;    id_gd=0;                              if_gd=216;  /*约1.69A*/    MaxU=6925216;    MaxI=10240;/*20480=10A*/        bAuto=0;    kk=4;  }void  interrupt  adint(){                      intflag;            inta_cos,a_sin,b_cos,b_sin,c_cos,c_sin;          staticintid_buf[M],iq_buf[M],if_buf[M],w_buf[16];            staticlongint  sumId=0,sumIq=0,sumIf=0;            *T4CNT=0X0000;            *MAINSTART=0;            *RECSTART=0;                        flag=*EVBIFRB&0X01;          if(flag!=0x01)          {            asm("clrcINTM");//允许总中断            return;//如果不是定时器1周期中断,则直接返回          }                    if(bAuto)          {          ii++;            if(ii==1500)            {            a++;            if(a==5)            {              a=0;              b++;            }            if(b==5)              b=5;            //w_kp=K[0][a];            //i_kp=K[1][b];                            ii=0;            if(jj>6;            temp=(temp*325)>>10;            if_fk=temp;                          temp=(*RESULT1)>>6;            temp=((temp-449)*609)>>10;            ia=temp;                                          temp=(*RESULT2)>>6;            temp=((temp-449)*609)>>10;            ib=temp;                          temp=(*RESULT3)>>6;            temp=((temp-449)*609)>>10;            ic=temp;          /*****************************得到位置*******************************************/                        if(pos>N)pos-=N;  //512-1024的数处理    theta=pos-197;    a_sin=theta;    a_cos=theta+128;    b_sin=theta-171;    b_cos=theta-43;    c_sin=theta+171;    c_cos=theta-214;    if(a_sinMM;      id_buf[jjjj]=id_fk;      iq_buf[jjjj]=iq_fk;        if_buf[jjjj]=if_fk;      jjjj++;      if(jjjj==M)jjjj=0;    }        if(bFirstTime==1){  id_fk=0;              iq_fk=0;              if_fk=0;              bFirstTime=0;            }                                /************************励磁电流调节器********************************************/          /*if按Q.7/10定标*/      temp=if_gd-if_fk;    if(temp>16||temp20000)if_sum=20000;        if(if_sum20000)if_out=20000;    if(if_out>12;      /*(uf/Ufm*256+256)*/n=temp+256;*FALPHA=MyAcos[n];      /*得到FALPHA*/                      /*********************************速度调节器***************************************/        temp=w_gd-w_fk;    temp2=w_fk-w_pre;      if((temp2-16))        if((temp>16||tempMaxI)w_sum=MaxI;        if(w_sumMaxI)w_out=MaxI;    if(w_out256||tempMaxU)iq_sum=MaxU;      if(iq_sum256||tempMaxU)id_sum=MaxU;      if(id_sum>9;            temp=temp*w_gd;            ud_qk=temp;                        temp=796;            temp=temp*w_gd;            temp=temp*if_gd;            temp2=285;            temp2=temp2*iq_gd;            uq_qk=(temp>>3)+(temp2>>1);            /************************ud,uq/ua,ub,uc********************/    /*Um=135V,相电压最大值,按Q.8/16定标,=34572*/              ........................................................................................................./****************************检测通讯*********************************************/            *R_AALPHA=0xff00;    *R_BALPHA=0xff00;    *R_CALPHA=0xff00;    *R_FALPHA=0xff00;    if((*R_AALPHA!=*AALPHA)||      (*R_BALPHA!=*BALPHA)||      (*R_CALPHA!=*CALPHA)||      (*R_FALPHA!=*FALPHA))    {        /*MAINSTOP=0xffff;        bStop=1;        DAC=0;*/        error=error+1;    }      /****************************观测4个量*********************************************/                    if(j9;                                buffer7[i]=id_gd;                buffer8[i]=id_fk;                buffer9[i]=id_out>>9;                                buffer10[i]=ud_qk>>9;                buffer11[i]=uq_qk>>9;                buffer12[i]=-ud;                buffer13[i]=-uq;                                buffer14[i]=ua;                buffer15[i]=ub;                buffer16[i]=uc;                                buffer17[i]=ia;                buffer18[i]=ib;                buffer19[i]=ic;                                buffer20[i]=if_gd;                buffer21[i]=if_fk;                                buffer22[i]=if_out;                                i++;                          }              if(i==SIZE)              {                /*MAINSTOP=0xffff;        /*bStop=1;*/                i=SIZE;              }            }            /***************************观测四路AD********************************************/            temp=ia
还是感觉C语言 亲切啊.
0
回复