📄 3_vf_main.asm
字号:
spwm_main
ldp #4h
splk #00h,table
splk #00h,cmpr1var
splk #00h,cmpr2var
splk #00h,cmpr3var
splk #00h,spwm_r_flag
splk #05h,vf_spwm_cofi
splk #07h,vf_spwm_num
splk #50h,vf_spwm_count
; splk #stable,toptable
splk #7h,vf_spwm_sel
splk #06eh,vf_spwm_varl
splk #0140h,vf_spwm_varh
splk #00h,vf_spwm_var
splk #00h,modreg
splk #50h,dpbc_var
ret
;----------------------------------------------------------------------------
spwm_start ; enable T1 timer operations
LDP #0e8h
LACL T1CON
OR #40h,0
SACL T1CON
LDP #0h
LACL IMR
OR #02h,0
SACL IMR ;set IMR bit2
LDP #0e8h
splk #0ffffh,EVIFRA
SPLK #0080H,EVIMRA
RET
;----------------------------------------------------------------------------
svpwm_ini_pwm
ldp #0E8H ; set DP
SPLK #0,T1CON
SPLK #0,T2CON
SPLK #0,T3CON
SPLK #0,DBTCON
SPLK #0,COMCON
SPLK #0,CAPCON
SPLK #0,T1CNT
SPLK #0,T2CNT
SPLK #0,T3CNT
SPLK #t1_period_,T1PR ;Init GP Timer 1 period that cetermines the pwm frequence
SPLK #t2_period_,T2PR ;Init GP Timer 2 period that determines the sampling frequence of speed loop.
SPLK #t1_period_,T3PR ;Init GP Timer 3 period for other use
SPLK #t1_period_,CMPR1 ;Kill all F.comp/pwm outputs
SPLK #t1_period_,CMPR2
SPLK #t1_period_,CMPR3
SPLK #200,T1CMPR ;Let GP Timer compare outputs toggle(to have more things I can
SPLK #200,T2CMPR ;look at with an oscilloscope).
SPLK #200,T3CMPR
SPLK #0666h,ACTR ;Define PWM output polarities
SPLK #1fe0H,DBTCON
SPLK #0,EVIMRA ;Mask pdpint to prevent it from disabling the compare output.
SPLK #0055H,GPTCON ;Define GP Timer output polarities and GP Timer actions
SPLK #0H,T3CON ; Configure GP Timer 3
SPLK #0H,T2CON ; Configure GP Timer 2
SPLK #2802H,T1CON ; Configure GP Timer 1
SPLK #0207h,COMCON
SPLK #8207h,COMCON
ret
;----------------------------------------------------------------------------
svpwm_varies_ini
LDP #04H ; Point to B1 page 0
SPLK #t_sample_,t_sample ; sampling period
SPLK #t1_periods_,t1_periods ; max compare value
SPLK #f_omega_,f_omega
SPLK #0H,set_f
splk #00h,svpwm_r_flag
splk #50h,svdpbc_var
splk #190,vf_svpwm_cofi
splk #50h,vf_svpwm_num
; set F to angular speed ratio
SPLK #omega_v_,omega_v
splk #min_v_,min_v
; angular speed to voltage ratio
SPLK #0,theta_l ; theta low byte
SPLK #0,theta_h ; theta high byte
LAR AR0,#theta_90 ; point to 1st destination
LAR AR1,#(28-1) ; 32 entries
LACC #angles_ ; point to 1st data item
LARP AR0 ;
init_tbl
TBLR *+,1 ; move and point to next destination
ADD #01H ; point to next data item
BANZ init_tbl,0
splk #theta_i_,theta_i ; theta to sin_index ratio
splk #theta_s_,theta_s ; theta to sector ratio
; init 1st and last entries of sin tb
SPLK #sin_entry_,sin_entry
SPLK #(sin_entry_+90),sin_end
ret
;----------------------------------------------------------------------------
svpwm_start
LDP #0E8H ; Enable GPT1 and PWM'ing
SPLK #2842h,T1CON
cfg_ints
ldp #0E8H ; Cfg interrupts
SPLK #0ffffh,EVIFRA ; Clear all Group A
SPLK #0ffh,EVIFRB ; Clear all Group B
SPLK #0fh,EVIFRC ; Clear all Group C
SPLK #0200h,EVIMRA ; Mask all but GPT1 UF
SPLK #0,EVIMRB ; Mask all ints
SPLK #0,EVIMRC ; Mask all Grp C ints
LDP #0 ; point to memory page 0
SPLK #0ffh,IFR ; Clear all core interrupt flags
splk #02h,IMR ; Unmask all EV
SETC OVM
SETC SXM
RET
;----------------------------------------------------------------------------
int2_isr ;main interrupt
KICK_DOG
LDP #0H
SST #ST0,ST0_save ; save status register ST0
SST #ST1,ST1_save ; save status register ST1
LDP #0H ; set DP
MAR *,AR0 ; set ARP
SACH ACCH ;
SACL ACCL ; save ACC
Sph P_hi ;
spl P_lo ; save P register
mpy #1 ; P<=T
spl T_save ; save T register
sar AR0,AR0_save ; save AR0
ldp #0e8h
lacc EVIVRA,0
SUB #029H
BCND svpwm_isr,eq
; B svpwm_isr
spwm_isr ;spwm_v/f interrupt sub_program
LDP #04H
lacc count_h,4
or count_l
sacl count_hl
sfl
sacl freqstep ;change the sine frequency
lt count_hl
mpy vf_spwm_cofi
pac
sacl vf_spwm_var ;(15Hz-50Hz) offset var=0h-50*5
ldp #04h ;mult_select
lacl vf_spwm_sel
sub #6h
bcnd vf_spwm_gt,gt
lacl count_hl
sfl
sfl
sfl
add vf_spwm_var
b vf_spwm_next
vf_spwm_gt ;decide if fre>15Hz
ldp #04h
lacl count_hl
sub #0
bcnd freq0,eq
lacl count_hl
sub #15h
bcnd high_comp,gt
lt count_hl ;if<15Hz
mpy vf_spwm_num
pac
add vf_spwm_varl ;add #6eh,can be modefied to select the v/f wave
b vf_spwm_next
freq0
lt count_hl ;if=0
mpy #7h
pac
b vf_spwm_next
high_comp ;if >15Hz and <50Hz
lacl count_hl
sub vf_spwm_count
bcnd power,geq
lt count_hl
mpy vf_spwm_num
pac
add vf_spwm_var
add #3fh
b vf_spwm_next
power ;>50Hz
ldp #04h
lt dpbc_var
mpy #7h
pac
add #1cfh
vf_spwm_next
sacl vf_cen
CALL sine_pwm
b TUICHU
;----------------------------------------------------------------------------
svpwm_isr
LDP #04H
lacc count_h,4
or count_l
sacl count_hl
lacl count_hl
sub #0
bcnd svfreqnext,neq
splk #0,set_v
b uinlolim
svfreqnext
lacl count_hl
sub vf_svpwm_num
bcnd sv_power,gt
lt count_hl
mpy vf_svpwm_cofi
pac
b vf_svpwm_next
sv_power
lt count_hl
mpy #190
pac
sacl set_f
LT set_f ; set f -> omega: D0
MPY f_omega ; D0*D10=D(10+1)
PAC ; product -> ACC: D11
SACH omega,1 ; -> set angular speed: D10
splk #29fbh,set_v
b uinlolim
vf_svpwm_next
sacl set_f
; Comment out following line to use push button to control speed
; SPLK #debug_data,set_f ; Replace with debug data
f2omega
LT set_f ; set f -> omega: D0
MPY f_omega ; D0*D10=D(10+1)
PAC ; product -> ACC: D11
SACH omega,1 ; -> set angular speed: D10
lacc omega ;
sub #min_omega_ ; compare W with its lower limit
BGZ winlimit ; continue if within limit
splk #min_omega_,omega ; saturate if not
winlimit
; Note the following implies constant v/f
omega2v
LT omega ; set angular speed -> T: D10
MPY omega_v ; D10*D-9=D(1+1)
PAC ; product -> ACC: D2
SACH set_v,1 ; -> mag of ref voltage and -> D1
lacc set_v ;
sub #max_v_ ; compare Uout w/ its upper limit
BLEZ uinuplim ; continue if within limit
splk #max_v_,set_v ; saturate if not
B uinlolim ;
uinuplim
LACC set_v ;
SUB min_v ; compare Uout with its lower limit
BGEZ uinlolim ; continue if within limit
ldp #04h
lacl min_v
sacl set_v
; splk min_v,set_v ; saturate if not
uinlolim
CALL t1uf_isr
TUICHU
LDP #0E8H
LACC EVIVRA
; SACL EVIFRA
LDP #0H ; set DP
lar AR0, AR0_save ; restore AR0
lt P_lo ; T<=P_lo
mpy #1 ; P (low byte) <=1*P_lo
lph P_hi ; P high byte <=P_hi
lt T_save ; restore T
ZALH ACCH ;
ADDS ACCL ; restore ACC
LDP #0 ; point to B2
LST #ST1,ST1_save ; restore status register ST1
LST #ST0,ST0_save ; restore status register ST0
CLRC INTM
ret
;----------------------------------------------------------------------------
sine_pwm: ;sine interrupt service program
LDP #4h
LACC modreg
add freqstep
sacl modreg
lacc modreg,8
sach table
lacc table
sub #256
bcnd a_wor1,GT
a_wor:
add #256
a_wor1:
add toptable
tblr sineval
lt sineval ;V/F Control
mpy vf_cen ;multi a coeficient: count_hl/60h
pac
sach vf_cmp1
lacc vf_cmp1,6
sacl vf_cmp1
lt vf_cmp1
mpy #normal
pac
sach comparet1,1
lacc comparet1
add #normal
ldp #4
SACL cmpr1var
;-----------------------------------------------------------------------------
ldp #4h
lacl table
add #b_phase
sub #256
bcnd b_wor1,GT
b_wor:
add #256
b_wor1:
add toptable
tblr b_sadd
lt b_sadd ;V/F Control
mpy vf_cen ;multi a coeficient: AD_SAMPLE/3FF
pac
sach vf_cmp2
lacc vf_cmp2,6
sacl vf_cmp2
lt vf_cmp2
mpy #normal
pac
sach comparet1,1
lacc comparet1
add #normal
ldp #4
SACL cmpr2var
;---------------------------------------------------------------------------------
ldp #4h
lacl table
add #c_phase
sub #256
bcnd c_wor1,GT
c_wor:
add #256
c_wor1:
add toptable
tblr c_sadd
lt c_sadd ;V/F Control
mpy vf_cen ;multi a coeficient: AD_SAMPLE/3FF
pac
sach vf_cmp3
lacc vf_cmp3,6
sacl vf_cmp3
lt vf_cmp3
mpy #normal
pac
sach comparet1,1
lacc comparet1
add #normal
ldp #4
SACL cmpr3var
lacl spwm_r_flag
sub #00h
bcnd posive_r,eq
nagative_r
lacl cmpr1var
ldp #232
sacl CMPR1
ldp #4
lacl cmpr2var
ldp #232
sacl CMPR2
ldp #4
lacl cmpr3var
ldp #232
sacl CMPR3
b fanhui
posive_r
ldp #4h
lacl cmpr1var
ldp #232
sacl CMPR2
ldp #4
lacl cmpr2var
ldp #232
sacl CMPR1
ldp #4
lacl cmpr3var
ldp #232
sacl CMPR3
fanhui
kick_dog
ldp #0E1H ;
lacc PBDATDIR ;
OR #0FFH
NOP
sacl PBDATDIR ;
RET
;----------------------------------------------------------------------------
t1uf_isr
;-------------------------------------------------------------------
; Generate revolving voltage vector Uout=trans(Ud Uq)
;-------------------------------------------------------------------
ldp #04h
lacl svpwm_r_flag
sub #00h
bcnd zhengzhuan,eq
lacc #firstfz_
sacl first_var
lacc #secondfz_
sacl second_var
b jxzd
zhengzhuan
lacc #firstzz_
sacl first_var
lacc #secondzz_
sacl second_var
jxzd
ldp #omega ; Integrate speed to get phase
LT omega ; set W -> T: D10
MPY t_sample ; D10*D-9=D(1+1)
PAC ; product -> ACC: D2
SFR ; -> D3
ADDH theta_h ; D3+D3=D3 (32 bit)
ADDS theta_l ;
SACH theta_h ; save
SACL theta_l ;
chk_lolim
bcnd chk_uplim,GEQ ; check upper limit if positive
ADDH theta_360 ; D3+D3=D3, rollover if not
SACH theta_h ; save
B rnd_theta ;
chk_uplim
SUBH theta_360 ; D3-D3=D3 compare with 2*pi
bcnd rest_theta,LEQ ; resume theta_h if within limit
SACH theta_h ; rollover if not
B rnd_theta ;
rest_theta
ADDH theta_360 ; resume theta high
rnd_theta
ADD #1,15 ; round up to upper 16 bits
SACH theta_r ;
;-------------------------------------------------------------------
; Quadrant mapping
;-------------------------------------------------------------------
LACC #1 ; assume theta (theta_h) is in quadrant 1
SACL SS ; 1=>SS, sign of SIN(theta)
SACL SC ; 1=>SC, sign of COS(theta)
LACC theta_r ;
SACL theta_m ; theta=>theta_m
SUB theta_90 ;
BLEZ E_Q ; jump to end if 90>=theta
; assume theta (theta_h) is in quadrant 2
splk #-1,SC ; -1=>SC
LACC theta_180 ;
SUB theta_r ; 180-theta
SACL theta_m ; =>theta_m
BGEZ E_Q ; jump to end if 180>=theta
; assume theta (theta_h) is in quadrant 3
splk #-1,SS ; -1=>SS
LACC theta_r ;
SUB theta_180 ; theta-180
SACL theta_m ; =>theta_m
LACC theta_270 ;
SUB theta_r ;
BGEZ E_Q ; jump to end if 270>=theta
; theta (theta_h) is in quadrant 4
splk #1,SC ; 1=>SC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -