📄 svpwm.asm
字号:
*********************************
* File name: svpwm.asm
; Module Name: SVPWM_GEN
; Initialization Routine: INIT_PWM
; Description: This module calculates the appropriate duty ratios needed
; to generate a given stator reference voltage using space
; vector PWM technique. The stator reference voltage is
; described by it's (a,b) components, Ualfa and Ubeta.
;
; |~~~~~~~~~~~~~~~|
; Ualfa o----> | |----->o Ta
; | svpwm |----->o Tb
; Ubeta o----> | |----->o Tc
; |_______________|
;=====================================================================
*********************************
.include "F2407REGS.H"
;---------------------------------------------------------------------
; Global Definitions
;---------------------------------------------------------------------
.def SVPWM_GEN,INIT_PWM ;function call
.def Ualfa,Ubeta ;Inputs
.def Ta,Tb,Tc ;Outputs
.def PDP
.ref Udc
.ref DATA_CACHE ;for test
;---------------------------------------------------------------------
; Variables
;---------------------------------------------------------------------
Ualfa .usect "svpwm",1
Ubeta .usect "svpwm",1
X .usect "svpwm",1
Y .usect "svpwm",1
Z .usect "svpwm",1
Ta .usect "svpwm",1
Tb .usect "svpwm",1
Tc .usect "svpwm",1
sector .usect "svpwm",1 ;SVPWM sector
sv_temp .usect "svpwm",1
half_sqrt3 .usect "svpwm",1 ;SQRT(3) * 0.5
half_three .usect "svpwm",1 ; 1.5
PWMPRD .usect "svpwm",1 ; 2000
PDP .usect "svpwm",1 ; 3
******************************
* PWM初始化
******************************
INIT_PWM:
NOP
LDP #MCRA>>7 ;装载IO复用控制寄存器页地址
LACL MCRA
OR #0FE0H ;将A06-11设置为基本功能
SACL MCRA ;即PWM1-6输出
SPLK #0FF04H,PADATDIR
SPLK #0FF00H,PBDATDIR
SPLK #0FF00H,PCDATDIR
SPLK #0FF00H,PDDATDIR
SPLK #0FF01H,PEDATDIR
SPLK #0FF00H,PFDATDIR ;将未使用的IO口设置为输出状态且为低
LDP #EVAIMRA>>7 ;装载EVA页地址
SPLK #80H,GPTCONA ;定时器1下溢中断标志启动模数转换
;定时器2无事件启动模数转换
;禁止所有定时器比较输出
SPLK #0999H,ACTRA ;PWM1,3,5低有效,PWM2,4,6高有效
SPLK #0AECH,DBTCONA ;使能死区控制 2000ns
SPLK #1000,CMPR1
SPLK #500, CMPR2
SPLK #1500,CMPR3 ;给比较寄存器赋初值
SPLK #0AE00H,COMCONA ;使能比较操作,定时器下溢或周期匹配
;装载比较寄存器,禁止空间矢量PWM模式
;使能PWM输出
SPLK #880CH,T1CON ;定时器1为连续增/减计数模式
;预定标系数为1,禁止定时器及其比较操作
SPLK #2000,T1PR ;设置开关周期T=2000*2*25ns=0.1ms
SPLK #00H,T1CNT ;设置定时器1计数初值为0
SPLK #0FFFFH,EVAIFRA ;清EVA中断标志寄存器A
SPLK #0281H,EVAIMRA ;使能定时器1周期和下溢中断
SPLK #968CH,T2CON ;定时器2为连续增计数模式
;同定时器1使用相同的使能位
;预定标系数为64,禁止定时器及其比较操作
SPLK #0FFFFH,T2PR ;设置定时器2的周期为最大值
SPLK #0000H,T2CNT ;设置定时器2计数初值为0
LDP #half_sqrt3
SPLK #6EDAH,half_sqrt3 ;Q15
SPLK #6000H,half_three ;Q14 1.5*2^14
SPLK #1F40H,PWMPRD ;Q2 2000*2^2
SPLK #1H,PDP
NOP
RET
*********************************************
****SVPWM_GEN
*********************************************
SVPWM_GEN:
NOP
LDP #Ualfa
LACC PWMPRD,10 ; Q14
LDP #Udc
RPT #16
SUBC Udc ; Udc ( Q6 )
LDP #Ualfa
SACL sv_temp ; Q7 PWMPRT/Udc
;SPLK #301CH,sv_temp ;for test
LT half_sqrt3 ; Q15
MPY sv_temp ; Q15*Q7
LTP Ubeta ; ACC=sv_temp*half_sqrt3 and TREG=Ubeta
SACH X ; Q7, X=sv_temp*half_sqrt3
MPY X ; Q7*Q7 Ubeta*sv_temp*half_sqrt3
LTP sv_temp
SFR
SACH X ; Q14,保存 Ubeta*sv_temp*half_sqrt3的高16位
SACL Z ; 保存 Ubeta*sv_temp*half_sqrt3的低16位
;Y = sv_temp*( sqrt(3)*Ubeta + 3 * Ualfa) / 2
MPY half_three ; Q7*Q14,PREG = 3*sv_temp/2
PAC ; Q22,ACC high = 3*sv_temp/2
LTP Ualfa ; ACC high = 3*sv_temp/2
SACH Y ; Q6, Y=3*sv_temp/2
MPY Y ; Q7*Q6 3*Ualfa*sv_temp/2
LACL Z
ADD X,16 ; Q14,ACC=Ubeta*sv_temp*half_sqrt3
APAC ; Q14,ACC=Ubeta*sv_temp*half_sqrt3+3*Ualfa*sv_temp/2
SACH Y,4 ; Q2, Y=Ubeta*sv_temp*half_sqrt3+3*Ualfa*sv_temp/2
;X = 2*Ubeta*sv_temp*half_sqrt3
LACL Z
ADD X,16 ; Q14,ACC=Ubeta*sv_temp*half_sqrt3
SACH X,5 ; Q2, X=2*Ubeta*sv_temp*half_sqrt3
;Z = sv_temp*( sqrt(3)*Ubeta - 3 * Ualfa) / 2
SPAC
SACH Z,4 ; Q2, Z=Ubeta*sv_temp*half_sqrt3-3*Ualfa*sv_temp/2
;CLRC OVM
;----------------------------------------------------------
; 60 degrees sector determination
; sector = r1 + 2*r2 + 4*r3
; r1=1 if X>0
; r2=1 if Z<0
; r3=1 if Y<0
;----------------------------------------------------------
SPLK #0,sector
LACC X
BCND vref1_neg,LEQ ;If X<0 do not set bit 1 of sector
LACC sector
OR #1
SACL sector
vref1_neg:
LACC Z
BCND vref2_neg,GEQ ;If Z>0 do not set bit 2 of sector
LACC sector
OR #2
SACL sector
vref2_neg:
LACC Y
BCND vref3_neg,GEQ ;If Y>0 do not set bit 3 of sector
LACC sector
OR #4
SACL sector
vref3_neg:
;LACL Tc ;FOR TEST
;CALL DATA_CACHE ;FOR TEST
;-------------------------------------------------------------------
;Sector calculations ("case statement")
;-------------------------------------------------------------------
LACC #SECTOR_TBL
ADD sector
TBLR sector
LACC sector
BACC
SECTOR_SR1:
;----------
;sector 1: t1=Z and t2=Y, (abc --> Tb, Ta, Tc)
LACC Z,16
SUB PWMPRD,16
ADD Y,16
BCND no_saturation1,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH X ;Q2 X=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC X
SACL X ;Q15,x=1/(t1+t2)
LT X
MPY Z
PAC
SACH Z ;Q2,t1=t1/(t1+t2)
MPY Y
PAC
SACH Y ;Q2,t2=t2/(t1+t2)
no_saturation1:
LACC PWMPRD,13 ; Q16 PWMPRD/2
SUB Z,13 ; ACC high = (PWMPRD-t1)/2
SUB Y,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Tb ;Q0 Tb=(PWMPRD-t1-t2)/2
ADD Z,14
SACH Ta ;Q0 Ta=(PWMPRD+t1-t2)/2
ADD Y,14
SACH Tc ;Q0 Tc=(PWMPRD+t1+t2)/2
B SV_END
SECTOR_SR2:
;----------
;sector 2: t1=Y and t2=-X, (abc --> Ta, Tc, Tb)
LACC Y,16
SUB PWMPRD,16
SUB X,16
BCND no_saturation2,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH Z ;Q2 Z=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC Z
SACL Z ;Q15,Z=1/(t1+t2)
LT Z
MPY Y
PAC
SACH Y ;Q2,t1=t1/(t1+t2)
MPY X
PAC
SACH X ;Q2,t2=t2/(t1+t2)
no_saturation2:
LACC PWMPRD,13 ; Q16 PWMPRD/2
SUB Y,13 ; ACC high = (PWMPRD-t1)/2
ADD X,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Ta ;Q0 Ta=(PWMPRD-t1-t2)/2
ADD Y,14
SACH Tc ;Q0 Tc=(PWMPRD+t1-t2)/2
SUB X,14
SACH Tb ;Q0 Tb=(PWMPRD+t1+t2)/2
B SV_END
SECTOR_SR3:
;----------
;sector 3: t1=-Z and t2=X, (abc --> Ta, Tb, Tc)
LACC X,16
SUB PWMPRD,16
SUB Z,16
BCND no_saturation3,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH Y ;Q2 Y=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC Y
SACL Y ;Q15,Y=1/(t1+t2)
LT Y
MPY Z
PAC
SACH Z ;Q2,t1=t1/(t1+t2)
MPY X
PAC
SACH X ;Q2,t2=t2/(t1+t2)
no_saturation3:
LACC PWMPRD,13 ; Q16 PWMPRD/2
ADD Z,13 ; ACC high = (PWMPRD-t1)/2
SUB X,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Ta ;Q0 Ta=(PWMPRD-t1-t2)/2
SUB Z,14
SACH Tb ;Q0 Tb=(PWMPRD+t1-t2)/2
ADD X,14
SACH Tc ;Q0 Tc=(PWMPRD+t1+t2)/2
B SV_END
SECTOR_SR4:
;----------
;sector 4: t1=-X and t2=Z, (abc --> Tc, Tb, Ta)
LACC Z,16
SUB PWMPRD,16
SUB X,16
BCND no_saturation4,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH Y ;Q2 Y=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC Y
SACL Y ;Q15,Y=1/(t1+t2)
LT Y
MPY X
PAC
SACH X ;Q2,t1=t1/(t1+t2)
MPY Z
PAC
SACH Z ;Q2,t2=t2/(t1+t2)
no_saturation4:
LACC PWMPRD,13 ; Q16 PWMPRD/2
ADD X,13 ; ACC high = (PWMPRD-t1)/2
SUB Z,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Tc ;Q0 Tc=(PWMPRD-t1-t2)/2
SUB X,14
SACH Tb ;Q0 Tb=(PWMPRD+t1-t2)/2
ADD Z,14
SACH Ta ;Q0 Ta=(PWMPRD+t1+t2)/2
B SV_END
SECTOR_SR5:
;----------
;sector 5: t1=X and t2=-Y, (abc --> Tb, Tc, Ta)
LACC X,16
SUB PWMPRD,16
SUB Y,16
BCND no_saturation5,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH Z ;Q2 Z=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC Z
SACL Z ;Q15,Z=1/(t1+t2)
LT Z
MPY X
PAC
SACH X ;Q2,t1=t1/(t1+t2)
MPY Y
PAC
SACH Y ;Q2,t2=t2/(t1+t2)
no_saturation5:
LACC PWMPRD,13 ; Q16 PWMPRD/2
SUB X,13 ; ACC high = (PWMPRD-t1)/2
ADD Y,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Tb ;Q0 Tb=(PWMPRD-t1-t2)/2
ADD X,14
SACH Tc ;Q0 Tc=(PWMPRD+t1-t2)/2
SUB Y,14
SACH Ta ;Q0 Ta=(PWMPRD+t1+t2)/2
B SV_END
SECTOR_SR6:
;----------
;sector 6: t1=-Y and t2=-Z, (abc --> Tb, Tc, Ta)
LACC Y,16
NEG
SUB PWMPRD,16
SUB Z,16
BCND no_saturation6,LEQ ;If t1+t2<PWMPRD jump to no_saturation
ADD PWMPRD,16 ;else sturation
SACH X ;Q2 X=t1+t2
LACC PWMPRD,16 ;Q18
RPT #14
SUBC X
SACL X ;Q15,x=1/(t1+t2)
LT X
MPY Y
PAC
SACH Y ;Q2,t1=t1/(t1+t2)
MPY Z
PAC
SACH Z ;Q2,t2=t2/(t1+t2)
no_saturation6:
LACC PWMPRD,13 ; Q16 PWMPRD/2
ADD Y,13 ; ACC high = (PWMPRD-t1)/2
ADD Z,13 ; ACC high = (PWMPRD-t1-t2)/2
SACH Tc ;Q0 Tc=(PWMPRD-t1-t2)/2
SUB Y,14
SACH Ta ;Q0 Ta=(PWMPRD+t1-t2)/2
SUB Z,14
SACH Tb ;Q0 Tb=(PWMPRD+t1+t2)/2
;B SV_END
SV_END:
BLDD Ta,#CMPR1
BLDD Tb,#CMPR2
BLDD Tc,#CMPR3
DUMMY
RET
;-------------------------------------------------------
;SVPWM Sector routine jump table - used with BACC inst.
;-------------------------------------------------------
SECTOR_TBL:
.word DUMMY
.word SECTOR_SR1
.word SECTOR_SR2
.word SECTOR_SR3
.word SECTOR_SR4
.word SECTOR_SR5
.word SECTOR_SR6
.word DUMMY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -