sfenail 发表于 2010-8-2 10:48

永磁同步电机FOC控制求助

在永磁同步电机FOC控制中,计算得到的电压Valfa和Vbeta经过极坐标变换得到|V|和sita,然后在第一扇区(0-60°)里面计算得到VT1和VT2(见计算1),再得到VTA,VTB,VTC(计算2),分配给定时器(决定中占空比)寄存器的比较值。请问下在其他象限中,这个VT1和VT2还需要计算吗?看分配图3中就是根据象限A~F直接分配即可?迷惑中。。。。由于是汇编语言,比较难看。我把汇编程序发上来吧,大家分析下:
CV_SectorA:
djnz guc_sector,CV_SectorB
movCCU6_CC60RH,r2
movCCU6_CC60RL,r3                ; CC60CR = V_TB
movCCU6_CC61RL,a
movCCU6_CC61RH,r4                ; CC61CR = V_TC
movCCU6_CC62RH,r0
movCCU6_CC62RL,r1                ; CC60CR = V_TA
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r7                           ; A= AD_TRIGGER_CM_L + T2/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,r6                           ; A= AD_TRIGGER_CM_H + T2/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r5                           ; A= AD_TRIGGER_PM_L + T1/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,b                            ; A= AD_TRIGGER_PM_H + T1/2_H
movCCU6_T13PRH,a
ljmp compare_values_end

CV_SectorB:
djnz guc_sector,CV_SectorC
movCCU6_CC60RL,a
movCCU6_CC60RH,r4                ; CC60CR = V_TC
movCCU6_CC61RH,r2
movCCU6_CC61RL,r3                ; CC61CR = V_TB
movCCU6_CC62RH,r0
movCCU6_CC62RL,r1                ; CC60CR = V_TA
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r5                           ; A= AD_TRIGGER_CM_L + T1/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,b                            ; A= AD_TRIGGER_CM_H + T1/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r7                           ; A= AD_TRIGGER_PM_L + T2/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,r6                           ; A= AD_TRIGGER_PM_H + T2/2_H
movCCU6_T13PRH,a
ljmp compare_values_end

CV_SectorC:
djnz guc_sector,CV_SectorD
movCCU6_CC60RH,r0
movCCU6_CC60RL,r1                ; CC60CR = V_TA
movCCU6_CC61RH,r2
movCCU6_CC61RL,r3                ; CC60CR = V_TB
movCCU6_CC62RL,a
movCCU6_CC62RH,r4                ; CC61CR = V_TC
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r7                           ; A= AD_TRIGGER_CM_L + T2/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,r6                           ; A= AD_TRIGGER_CM_H + T2/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r5                           ; A= AD_TRIGGER_PM_L + T1/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,b                            ; A= AD_TRIGGER_PM_H + T1/2_H
movCCU6_T13PRH,a
ljmp compare_values_end

CV_SectorD:
djnz guc_sector,CV_SectorE
movCCU6_CC60RH,r0
movCCU6_CC60RL,r1                ; CC60CR = V_TA
movCCU6_CC61RL,a
movCCU6_CC61RH,r4                ; CC61CR = V_TC
movCCU6_CC62RH,r2
movCCU6_CC62RL,r3                ; CC60CR = V_TB
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r5                           ; A= AD_TRIGGER_CM_L + T1/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,b                            ; A= AD_TRIGGER_CM_H + T1/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r7                           ; A= AD_TRIGGER_PM_L + T2/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,r6                           ; A= AD_TRIGGER_PM_H + T2/2_H
movCCU6_T13PRH,a
ljmp compare_values_end

CV_SectorE:
djnz guc_sector,CV_SectorF
movCCU6_CC60RL,a
movCCU6_CC60RH,r4                ; CC61CR = V_TC
movCCU6_CC61RH,r0
movCCU6_CC61RL,r1                ; CC60CR = V_TA
movCCU6_CC62RH,r2
movCCU6_CC62RL,r3                ; CC60CR = V_TB
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r7                           ; A= AD_TRIGGER_CM_L + T2/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,r6                           ; A= AD_TRIGGER_CM_H + T2/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r5                           ; A= AD_TRIGGER_PM_L + T1/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,b                            ; A= AD_TRIGGER_PM_H + T1/2_H
movCCU6_T13PRH,a
ljmp compare_values_end

CV_SectorF:
mov CCU6_CC60RH,r2
mov CCU6_CC60RL,r3               ; CC61CR = V_TB
mov CCU6_CC61RH,r0
mov CCU6_CC61RL,r1               ; CC60CR = V_TA
mov CCU6_CC62RL,a
mov CCU6_CC62RH,r4               ; CC60CR = V_TC
movCCU6_PAGE,#0x00
mova,#AD_TRIGGER_CM_L             ; A= AD_TRIGGER_CM_L
adda,r5                           ; A= AD_TRIGGER_CM_L + T1/2_L
movCCU6_CC63RL,a
mova,#AD_TRIGGER_CM_H             ; A= AD_TRIGGER_CM_H
addc a,b                            ; A= AD_TRIGGER_CM_H + T1/2_H
movCCU6_CC63RH,a
movCCU6_PAGE,#0x01
mova,#AD_TRIGGER_PM_L             ; A= AD_TRIGGER_PM_L
adda,r7                           ; A= AD_TRIGGER_PM_L + T2/2_L
movCCU6_T13PRL,a
mova,#AD_TRIGGER_PM_H             ; A= AD_TRIGGER_PM_H
addc a,r6                           ; A= AD_TRIGGER_PM_H + T2/2_H
movCCU6_T13PRH,a

compare_values_end:
另外,扇区判断怎么在程序里面实现,难道按照simulink仿真里面的方法?请指点。

archdevil 发表于 2010-8-2 16:42

算一次就好了,其他扇区里计算公式也是一样的,所以可以直接用,顶多符合不同.

sfenail 发表于 2010-8-2 20:08

感谢archdevil 回答。另外扇区判断在程序中是怎么实现的?是不是也要和simulink模型那样跟据电压符号判断扇区?如果FOC是从第一扇区开始执行的,是不是在接下来就不需要判断扇区了,直接在上个扇区基础上加1就行了?另外上面的汇编语言中:CV_SectorA:~CV_SectorF: 是什么东西?我对汇编不了解,看程序都很费劲。请大侠们指点小弟了。

archdevil 发表于 2010-8-2 20:22

随便着个2407或者2812的dsp的书,书后面都有附带的svpwm的例程的。一般扇区是每次计算判断的,因为你不知道什么时候该加1。

sfenail 发表于 2010-8-4 15:48

电机所处扇区是不是可以通过转子位置角得到呢?看下面一段程序:
movMDU_MD4,CD_CORDZL            ; MD4 = Z = Angle
movMDU_MD5,CD_CORDZH            ; MD5 = Z = Angle
movMDU_MDUCON,#0x10;               ; start Multiplikation (gi_angle * 6) -> Sector,gamma

movMDU_MD4,r7                     ;4 MD4 = amp_L
movMDU_MD5,r6                     ;8 MD5 = amp_H
_MD_01:
clra                              ;10
movCD_STATC,a                     ;12 clear keep bits- interrupt disabled
movCD_CORDZL,a                  ;14 Z = 0
movdptr,#Sinus60_tab            ; MDU ready / get pointer at Sinustable

movr2,MDU_MR1                     ; R2 = gamma 8bit
movguc_sector,MDU_MR2               ; R3 = guc_sector0 ... 5
通过(gi_angle * 6) -> Sector,gamma,在其他的地方根本没看到有扇区判断程序。。。。好迷惑
页: [1]
查看完整版本: 永磁同步电机FOC控制求助