?? main.asm
字號:
;***********************************************************************
; File Name: TMS320x240 Example Code
; Originator:jzming
; Tianhuang technology dsp development group.
; Description
; This program implements an open-loop speed control algorithm for
; three-phase AC induction motors using constant v/f principle and
; SV PWM technique. The program allows the usage of either
; h/w or s/w determined switching patterns by changing the assembly
; directives.
;*******************************************************************
; Notes
;-------------------------------------------------------------------
; 1. This program implements an INT driven sampling and control loop
; for three-phase AC induction motor control through a three-phase
; voltage source inverter.
; 2. Constant v/f principle is used to generate the magnitude of
; reference voltage from frequency input.
; 3. SV PWM technique is employed to generate a sinusoidal
; type of three-phase voltage output from the inverter.
; 4. Both PWM and sampling frequencies are 20KHz.
; 5. Maximum scaling and 32 bit integration are used to maximize the
; accuracy of integer math.
; 6. The motor is assumed to be rated at 60Hz, i.e., maximum voltage
; output magnitude is achieved when freq (speed) input is 60Hz.
; 7. Frequency input is through push buttons connected to the IOPB6
; (UP) and IOPB7 (DOWN). Frequency range is 0-120Hz.
; 8. The D scaling notation used here is related to the popular Q
; scaling notation by Dx=Q15-x.
;===================================================================
;-------------------------------------------------------------------
; Peripheral Registers and constants of TMS320C24x/F24x
;-------------------------------------------------------------------
.include "x24x.h" ; X24x register addresses
.def PHANTOM, gpt1uf
.global _c_int0
;-------------------------------------------------------------------
; Variables
;-------------------------------------------------------------------
ST0 .set 0
ST1 .set 1
temp .usect ".blk1",1
set_f .usect ".blk1",1 ; set F: D0 (-1.0-1.0, 1.0-120Hz)
f_omega .usect ".blk1",1 ; set F to angular speed ratio: D10
omega .usect ".blk1",1 ; set angular speed: D10
omega_v .usect ".blk1",1 ; angular speed to voltage ratio:D-9
set_v .usect ".blk1",1 ; set voltage: D1
t_sample .usect ".blk1",1 ; sampling period: D-9
theta_h .usect ".blk1",1 ; phase of ref vector hi word: D3
theta_l .usect ".blk1",1 ; theta lo word
theta_r .usect ".blk1",1 ; rounded theta_h: D3
theta_m .usect ".blk1",1 ; theta mapped to 1st quadrant: D3
theta_i .usect ".blk1",1 ; theta to index for sine table: D6
SS .usect ".blk1",1 ; sin sign modification: D15
SC .usect ".blk1",1 ; cos sign modification: D15
sin_indx .usect ".blk1",1 ; index to sine table: D15
sin_entry .usect ".blk1",1 ; beginning of sin table
sin_end .usect ".blk1",1 ; end of sin table
sin_theta .usect ".blk1",1 ; sin(theta): D1
cos_theta .usect ".blk1",1 ; cos(theta): D1
Ud .usect ".blk1",1 ; voltage Ud: D2
Uq .usect ".blk1",1 ; voltage Uq: D2
theta_s .usect ".blk1",1 ; theta to sector mapping: D0
sector .usect ".blk1",1 ; sector reference U is in: D15
theta_90 .usect ".blk1",1 ; 90: D3
theta_180 .usect ".blk1",1 ; 180: D3
theta_270 .usect ".blk1",1 ; 270: D3
theta_360 .usect ".blk1",1 ; 360: D3
dec_ms .usect ".blk1",24 ; Decomposition matrices: D1
t1_periods .usect ".blk1",1 ; scaled Timer 1 period: D10
cmp_1 .usect ".blk1",1 ; decomp on 1st basic sp vector: D15
cmp_2 .usect ".blk1",1 ; decomp on 2nd basic sp vector: D15
cmp_0 .usect ".blk1",1 ; decomp on 0 basic sp vector /2: D15
first_tog .usect ".blk1",1 ; the 1st-to-toggle channel
sec_tog .usect ".blk1",1 ; the 2nd-to-toggle channel
svpat .usect ".blk1",1 ; S/V pattern for ACTR
count .usect ".blk1",1 ;read the key number which pressed
count1 .usect ".blk1",1 ;temp register
count2 .usect ".blk1",1 ;temp register
yjax_flag .usect ".blk1",1 ;set the yjax flag
count_h .usect ".blk1",1 ;high num of the led (dec)
count_l .usect ".blk1",1 ;low num of the led (dec)
count_hl .usect ".blk1",1
led_dis_h .usect ".blk1",1 ;high bit to be displayed(hex)
led_dis_l .usect ".blk1",1 ;low bit to be displayed(hex)
led_data .usect ".blk1",1 ;comb word to be displayed(hex)
;-------------------------------------------------------------------
; Context
;-------------------------------------------------------------------
ST0_save .set 060h ; saved status register ST0
ST1_save .set 061h ; saved status register ST1
ACCH .set 062h ; saved accumulator high
ACCL .set 063h ; saved accumulator low
AR0_save .set 064h ; saved AR0 content
AR1_save .set 065h ; saved AR1 content
P_hi .set 066h ; saved P high byte
P_lo .set 067h ; saved P low byte
T_save .set 068h ; saved T content
;-------------------------------------------------------------------
; Program parameters
;-------------------------------------------------------------------
debug_data .set 1000h ; 60Hz-3FFF, 30Hz-1FFF, 25Hz-1AAB
; Scaled sampling period
; Ts*D-9=Ts*2**24, Ts=50uS
t_sample_ .set 0346h ; D-9
; Set frequency to radian frequency conversion ratio
; 120*2*pi/7FFFh/D0 = 754.0052472756
; 7FFFh corresponds to 120Hz=753.9822368616 rad/sec
f_omega_ .set 24128 ; D10
; Minimum radian frequency
; min_F*2*pi*D10=12*2*pi*D10=75.39822368616*D10
; min_F=12Hz is the minimum frequency input, D10=2**5
min_omega_ .set 2413 ; D10
; Radian frequency to ref voltage conversion ratio -> V/Hz constant
; 1.0/sqrt(2)/(60*2*pi)*D24 = 0.001875658991994*D24
omega_v_ .set 31468 ; D-9
; Max magnitude of reference voltage
; 1.0/sqrt(2)*D1 = 0.7071067811865*D1
max_v_ .set 11585 ; D1. 1b less res to reduce # shiftingsa
; Min magnitude of reference voltage given by
; 1.0/sqrt(2)*min_F/60Hz*D1 = 0.1414213562373*D1
min_v_ .set 2317 ; D1
; Conversion from theta to index for sine table
; 360/(0.5pi)*D8, D8=2**(15-8)=2**7 ; 360 entry sine table
; theta_i_ .set 29335 ; D8
; 90/(0.5pi)*D6, D6=2**9 ; 90 entry sine table
theta_i_ .set 29335 ; D6
; Conversion from theta to sector
; 6/(2*pi)*D0, D0=2**(15-0)
theta_s_ .set 31291 ; D0
; No of cycles needed to qualify a button push
but_qual_ .set 60 ; 20*t_sample
;------------------------------------------------------------------
.text
;===================================================================
; Start of main body of code
;-------------------------------------------------------------------
_c_int0
setc INTM ; Set global interrupt mask
reset_wd0
LDP #0E0H ; Reset WD timer
SPLK #06FH,WDCR
KICK_DOG
SPLK #40C0h,SYSCR ;CPUCLK-->CLKOUT
SPLK #0020h,SYSSR ;
SPLK #00B1h,CKCR1 ;CPUCLK=20MHz
SPLK #0001h,CKCR0 ;Disable PLL
SPLK #00C1h,CKCR0 ;Re_enable PLL
init_io
LDP #0E1H
LACL OCRA ;configure the I/O port
AND #0FFh
SACL OCRA
SPLK #0F0H,OCRB
SPLK #0000H,PADATDIR ;set the PB as input
SPLK #00FFH,PBDATDIR
ldp #06h ;point to variables
splk #0,count_h
splk #0,count_l ;initialize the display
splk #0c0c0h,led_data
out led_data,LED_ADDR
t1_period_ .set 500 ; Tpwm/50nS/2=50uS/50nS/2=500
t1_periods_ .set 500*32 ; D10, scaled Timer 1 period
t2_period_ .set 1000 ;
init_ev
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 #10,T1CMPR ;Let GP Timer compare outputs toggle(to have more things I can
SPLK #10,T2CMPR ;look at with an oscilloscope).
SPLK #10,T3CMPR
SPLK #0666h,ACTR ;Define PWM output polarities
SPLK #01F4H,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 #0A882H,T3CON ; Configure GP Timer 3
SPLK #0A882H,T2CON ; Configure GP Timer 2
SPLK #0A802H,T1CON ; Configure GP Timer 1
SPLK #0000001100000111b,COMCON
SPLK #1000001100000111b,COMCON
init_vars
LDP #06H ; 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
; set F to angular speed ratio
SPLK #omega_v_,omega_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
enbl_pwmg
LDP #0E8H ; Enable GPT1 and PWM'ing
SPLK #1010100001000010b,T1CON
cfg_ints
ldp #0E8H ; Cfg interrupts
SPLK #0fffh,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 #00001110b,IMR ; Unmask all EV
SETC OVM
SETC SXM
CLRC INTM
;===================================================================
; Start of background loop
;-------------------------------------------------------------------
main_loop ;main program
ldp #06h
splk #00h,yjax_flag ;clear the yjax_flag
nop
call jpan ;call the jpan sub_program
loop
lacc yjax_flag ;decide if some key pressed
sub #01h
bcnd qd_yjax,eq ;yes
CLRC INTM
pbutnend
LDP #06H
lacc count_h,4
or count_l
sacl count_hl
lacc count_hl
sfl
sfl
sfl
sfl
sfl
sfl
sfl
sacl count_hl
lacc count_hl
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
splk #min_v_,set_v ; saturate if not
uinlolim
KICK_DOG
b main_loop
qd_yjax ;decide it's up_butn or dn_butn?
ldp #06h
lacc count
sub #40h ;up_butn
bcnd up_butn,eq
lacc count
sub #80h ;dn_butn
bcnd dn_butn,eq
b main_loop
up_butn ;increase button:IOPB6
ldp #06h
lacc count_h ;dicide if the count_h'number equal 6
sub #6
bcnd led_max,eq ;yes,jump led_max
lacc count_l
sub #9
bcnd led_jinwei,eq
add #9
sacl count_l
LACC count_l ; count_l +1
ADD #1
SACL count_l
b xunhuan
led_jinwei ;if count_l=9,then led_jinwei
ldp #06h
splk #0,count_l
lacc count_h ;increase the count_h
add #1
sacl count_h
lacc count_h
sub #6
bcnd led_max,eq ;if=6,then led_max
add #6 ;restore
sacl count_h
b xunhuan
led_max ;the maxim desplayed(60)
ldp #06h
splk #0,count_l
splk #6,count_h
b xunhuan
dn_butn ;decrease button:IOPB7
ldp #06h
lacc count_l
bcnd dn_next1,eq ;decide if it's "00"
b dn_next2
dn_next1
lacc count_h
bcnd led_min,eq
dn_next2 ;jiewei
lacc count_l
bcnd led_jiewei,eq
sub #1
sacl count_l
b xunhuan
led_jiewei
ldp #06h
splk #9,count_l
lacc count_h
sub #1
sacl count_h
b xunhuan
led_min ;the minimum displayed
ldp #06h
splk #0,count_l
splk #0,count_h
b xunhuan
xunhuan ;displayed based on led_table
ldp #6h
lacc count_h
and #0fh
add #led_table
tblr led_dis_h
lacc count_l
and #0fh
add #led_table
tblr led_dis_l
lacc led_dis_l,8
or led_dis_h
sacl led_data
out led_data,LED_ADDR ; update LED display
sfjx
KICK_DOG ;delay intervel
; call pjsf
; bcnd sfjx,neq
mar *,ar2
lar ar2,#10h
ysjg
call delay_time
banz ysjg
KICK_DOG
B main_loop ; End of background loop
jpan
clrc tc ;the main key program
ldp #0e1h
lacc PBDATDIR
cmpl
and #0ffh
ldp #06h
sacl count1
lacl count1
lar ar0,count1
bcnd yjaxm,neq
KICK_DOG
b loop
yjaxm ;back wobble
SETC INTM
call delay_time
CLRC INTM
ldp #0e1h
lacc PBDATDIR
cmpl
and #0ffh
ldp #06h
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -