⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svpwm.asm

📁 利用2407编写的PWM整流器控制程序
💻 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 + -