GIAO TIẾP LED 7 ĐOẠN: QUA IC GIẢI MÃ 7447 VÀ PHƯƠNG PHÁP QUÉT LED-
GIẢI THUẬT VƠI LED 7 ĐOẠN CŨNG GIỐNG VỚI GIẢI THUẬT CỦA 8051, NHƯNG XỬ LÝ SẼ PHỨC TẠP HƠN.VÌ VẬY NÊN KHI LẬP TRÌNH AVR, VIẾT BẰNG ASM VỚI NHỮNG CHƯƠNG TRÌNH PHỨC TẠP THÌ NHỮNG BẠN KHI MỚI HỌC SẼ CẢM THẤY CHÓNG NẢN.* 7447 CÁC BẠN VÀO TRANG
HOCAVR.COM THAM KHẢO
- CÁC CÂU LỆNH THAM KHẢO DATASHEET:
[You must be registered and logged in to see this link.]** PHƯƠNG PHÁP QUÉT LED 7 ĐOẠN.;=========================================================================
.include "m16def.inc"
;=========================================================================
;
KHAI BAO BIEN;=========================================================================
;
32 Reg;------------------------------------------------------------
.def X0 =R2 ;toan hang thu nhat(LSB)
.def X1 =R3
.def X2 =R4
.def X3 =R5 ;toan hang thu nhat(MSB)
.def Y0 =R6 ;toan hang thu hai(MSB)
.def Y1 =R7
.def Y2 =R8
.def Y3 =R9 ;toan hang thu hai(MSB)
.def Z0 =R10 ;ket qua(LSB)
.def Z1 =R11
.def Z2 =R12
.def Z3 =R13 ;ket qua(MSB)
.def PR0 =R14 ;so du cua phep chia(LSB)
.def PR1 =R15 ;so du cua phep chia(MSB)
.def temp =R16
.def dem =R17 ;bien dem vong lap cua cac phep chia
; SRAM
;------------------------------------------------------------;
;
cac bien dung cho subr hextodec;------------------------------------------------------------
.equ Digit0 =0x60 ;Digit0 la chu so hang don vi
.equ Digit1 =0x61 ;Digit1 la chu so hang chuc
.equ Digit2 =0x62 ;Digit2 la chu so hang tram
.equ Digit3 =0x63 ;Digit3 la chu so hang nghin
.equ Digit4 =0x64 ;Digit4 la chu so hang van
.org 0
rjmp start
;=========================================================================
; MAIN PROGRAM
;=========================================================================
.org 100 ;#s
start:
cli
ldi temp,low(RAMEND) ;init stack
out spl,temp
ldi temp,high(RAMEND)
out sph,temp
rcall Init_port ;init chieu cua cac port
rcall delay2ms
sei
here:
rjmp here
;=========================================================================
; SUB : test_quetled
; function :
; in :
;=========================================================================
test_quetled:
lds temp,digit0
rcall decto7seg
out portd,temp
ldi temp,0x02
out portb,temp
rcall delay2ms
ldi temp,0x00
out portb,temp
rcall delay2ms
lds temp,digit1
rcall decto7seg
out portd,temp
ldi temp,0x04
out portb,temp
rcall delay2ms
ldi temp,0x00
out portb,temp
rcall delay2ms
lds temp,digit2
rcall decto7seg
out portd,temp
ldi temp,0x08
out portb,temp
rcall delay2ms
ldi temp,0x00
out portb,temp
rcall delay2ms
ret
;=========================================================================
; SUB : test_led
;function :
;=========================================================================
test_led:
ldi temp,0x00 ; led on
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xc0 ; 0
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xc0 ; 0
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xf9 ; 1
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xa4 ; 2
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xb0 ; 3
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0x99 ; 4
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0x92 ; 5
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0x82 ; 6
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xf8 ; 7
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0x80 ; 8
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0x90 ; 9
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ldi temp,0xff ; led off
out portd,temp
ldi temp,0xff
out portb,temp
rcall delay1s
ret
;=========================================================================
; SUB :init_port
;function :khoi tao cac chieu cho cac Port
;=========================================================================
init_port:
ldi temp,0xff
out ddrd,temp
ldi temp,0xff
out ddrb,temp
ret
;=========================================================================
;
CAC SUBR TINH TOAN CHO VDK ATMEGA 16;=========================================================================
;add8u :8+8 bit unsigned
;sub8u :8-8 bit unsigned
;mul8u :8*8 bit unsigned
;div8u :8/8 bit unsigned
;add16u :16+16 bit unsigned
;sub16u :16-16 bit unsigned
;mul16u :16*16 bit unsigned
;div16u :16/16 bit unsigned
;add32u :32+32 bit unsigned
;sub32u :32-32 bit unsigned
;mul32u :32*32 bit unsigned
;div32u :32/32 bit unsigned
;=========================================================================
; subr :add8u
; Z(Z0) = X(X0) + Y(Y0); zov =1 neu tran
;=========================================================================
add8u:
push temp
clc
mov temp,X0
add temp,Y0 ;X0+Y0-->temp
mov Z0,temp ;temp -->Z0
brcc clear_zov_add8u ;skip neu carry =0
rcall set_zov ;set zov neu carry =1
rjmp end_add8u
clear_zov_add8u:
rcall clear_zov ;clear zov neu khong tran
end_add8u:
pop temp
ret
;=========================================================================
; subr :set_zov
; :set co zov
;=========================================================================
set_zov:
set ;set bit T
bld co_tinhtoan,zov ;T -->zov
ret
;=========================================================================
; subr :clear_zov
; :clear co zov
;=========================================================================
clear_zov:
clt ;clear bit T
bld co_tinhtoan,zov ;T -->zov
ret
;=========================================================================
;sub :sub8u
; :Z(Z0)=X(X0)-Y(Y0)
; :neu Y>X thi zov=1
;=========================================================================
sub8u:
push temp
clc
mov temp,X0 ;chuyen X0 vao temp
sub temp,Y0 ;X0 - Y0-->temp
mov Z0,temp ;Z0 =temp
brcs set_zov_sub8u ;nhay toi set_zov neu C=1
rcall clear_zov ;neu tru duoc thi clear zov
rjmp end_sub8u
set_zov_sub8u:
rcall set_zov ;neu Y>X thi zov =1
end_sub8u:
pop temp
ret
;=========================================================================
;sub :mul8u
;input :X0,Y0
;output :Z(Z1:Z0) =X0*Y0
;=========================================================================
mul8u:
mul X0,Y0
movw Z1:Z0,R1:R0
ret
;=========================================================================
;sub :div8u
;input :so bi chia =X0
; ;so chia =Y0
;output : thuong =Z0
; :zov =1 neu Y0 =0,..
;=========================================================================
div8u:
push temp
push R0 ;R0 chua so bi chia ban dau
push R1 ;R1 =thuong chay
mov temp,Y0
cpi temp,0
brne div8_ok ;neu Y0#0 thi thuc hien chia
set ;set T
bld co_tinhtoan,zov ;zov =1
rjmp end_div8
div8_ok:
mov R0,X0 ;chuyen X0 vao R0
clr X0 ;clear X0
clr R1 ;clear thuong chay
clr Z0 ;clear Z0
clr PR0 ;clear PR0
ldi dem,8 ;nap so dem
div8_loop:
clc ;clear carry
rol R0
rol X0
rcall sub8u
sbrc co_tinhtoan,zov ;skip neu zov=0
rjmp khong_tru_duoc ;zov=1
sec ;lam cho c=1(tru duoc)
mov X0,Z0 ;update so du
rjmp rol_R1
khong_tru_duoc:
clc ;lam cho c=0
rol_R1:
rol R1
dec dem ;giam dem
cpi dem,0 ;dem =0?
brne div8_loop ;nhay toi neu dem#0
mov Z0,R1 ;duoc so thuong
mov PR0,X0 ;duoc so du
clt ;clear T
bld co_tinhtoan,zov ;clear zov
end_div8:
pop R1
pop R0
pop temp
ret
;=========================================================================
;subroutine add16u
;input : X (X1:X0),Y:(Y1:Y0)
;output : Z (Z1:Z0),ZOV =1 neu tran so
;=========================================================================
add16u:
push temp
clc
mov temp,X0
add temp,Y0
mov Z0,temp
mov temp,X1
adc temp,Y1
mov Z1,temp
brcs set_zov_add16u ;set zov neu tran
rcall clear_zov ;clear zov neu khong tran
rjmp end_add16u
set_zov_add16u:
rcall set_zov
end_add16u:
pop temp
ret
;=========================================================================
;sub :sub16u
; :Z(Z1:Z0)=X(X1:X0)-Y(Y1:Y0)
; :neu Y>X thi zov=1
;=========================================================================
sub16u:
push temp
mov temp,X0 ;nap byte thap cua X vao temp
clc ;clear c
sbc temp,Y0 ;tru hai byte thap
mov Z0,temp ;cat ket qua vao Z0
mov temp,X1 ;nap byte cao cua X vao temp
sbc temp,Y1 ;tru hai byte cao
mov Z1,temp ;cat ket qua vao Z1
brcs set_zov_sub16u ;nhay toi set_zov neu C=1
clt ;clear T
bld co_tinhtoan,zov ;neu tru duoc thi clear zov
rjmp end_sub16u
set_zov_sub16u:
set ;set T
bld co_tinhtoan,zov
end_sub16u:
pop temp
ret
;=========================================================================
;sub :div16u
;input :X(X1:X0),Y(Y1:Y0)
;output :thuong =Z(Z1:Z0)
; :so du =PR(PR1:PR0)
; zov=1 neu Y=0,..
; r1:r0 store the high and low bytes of partial
; remainder(so bi chia ban dau). r5:r4 la thuong chay
;=========================================================================
div16u:
push temp
push R1 ;R1:R0 chua so bi chia ban dau
push R0
push R5 ;R5:R4 la so thuong chay
push R4
mov temp,Y1
or temp,Y0
cpi temp,0
brne div_ok ;neu Y#0 thi thuc hien chia
set ;set T
bld co_tinhtoan,zov ;zov =1
rjmp end_div16u
div_ok:
push X1
push X0
mov r1,X1 ;cat so bi chia vao R1:R0
mov r0,X0
clr X1 ;clear so bi chia chay
clr X0
clr r5 ;clear thuong chay
clr r4
ldi dem,16 ;set loop count
div16_loop:
clc ;clear carry
rol r0 ;shift the highest bit of the dividend...
rol r1 ;...into...
rol X0 ;...the lowest bit of the partial...
rol X1 ;...remainder
rcall sub16u
sbrc co_tinhtoan,zov ;skip neu zov=0(tru duoc)
rjmp clear_c ;khong tru duoc thi zov=1
sec ;C=1
mov X1,Z1 ;dua ket qua phep tru vao X1:X0
mov X0,Z0
rjmp div_1
clear_c:
clc ;C=0
div_1:
rol r4
rol r5
dec dem
cpi dem,0
brne div16_loop
mov Z1,r5
mov Z0,r4
mov PR0,X0
mov PR1,X1
pop X0
pop X1
clt ;clear T
bld co_tinhtoan,zov ;clear zov
end_div16u:
pop r4
pop r5
pop r0
pop r1
pop temp
ret
;=========================================================================
; subroutine mul16u
; nhan hai so 16 bit khong dau
; :Z(Z3:Z2:Z1:Z0) = X(X1:X0) * Y(Y1:Y0)
; input :X(X1: X0),Y(Y1: Y0)
; output :Z3, Z2, Z1, Z0
; :Z3 is the most significant byte.
; :Z0 is the least significant byte.
;rcall :BMW
;=========================================================================
mul16u:
push temp
push R20 ;R20 dung lam thanh ghi tam thoi
rcall mul8_16u ;X0*Y(Y1:Y0)
push Z2 ;push Z2_1
push Z1 ;push Z1_1
push Z0 ;push Z0_1
push X0
mov X0,X1 ;chuyen X1 vao X0
rcall mul8_16u ;X1*Y(Y1:Y0)
pop X0
mov R20,Z0 ;cat Z02 vao R20
pop Z0 ;Z0 =Z01
pop temp ;lay Z11 tu stack
add temp,R20 ;temp =Z11+Z02
mov R20,Z1 ;cat Z12 vao R20
mov Z1,temp ;Z1 =temp
pop temp ;temp =Z21
adc temp,R20 ;temp =Z21+Z12+Carry
mov R20,Z2 ;cat Z22 vao R20
mov Z2,temp ;duoc Z2
clr temp ;temp =0
adc temp,R20 ;temp =0+Z22+carry
mov Z3,temp ;duoc Z3
pop R20 ;phuc hoi lai R20
pop temp ;va temp tu stack
ret
;=========================================================================
; subroutine mul8_16u
;function :nhan mot so 8 bits voi mot so 16 bits
; :Z(Z2:Z1:Z0) = X0 * Y(Y1:Y0)
; input : X0, Y1,,Y0
; output : Z(Z2:Z1:Z0)
; :Z2 is the most significant byte.
; :Z0 is the least significant.
;=========================================================================
mul8_16u:
push temp
mul X0,Y0 ;ket qua-->R1:R0
mov Z0,R0 ;save result low byte
push R1 ;push result high byte
mul X0,Y1 ;ket qua-->R1:R0
pop temp ;pop temp to recall X0*Y0 high byte
add temp,R0 ;add X0*Y0 high byte and X0*Y1 low byte
mov Z1,temp ;save result
clr temp
adc temp,R1 ;temp = R1+carry
mov Z2,temp
pop temp ;phuc hoi lai temptu stack
ret
;=========================================================================
; subroutine div32u
;function :chia hai so 32 bits khong dau
; input :so bi chia =X(X3:X2:X1:X0)
; :so chia =Y(Y3:Y2:Y1:Y0)
; output :thuong =Z(Z3:Z2:Z1:Z0)
; :so du =PR(PR3:PR2:PR1:PR0)
; ZOV is set if Y=0, i.e., the result is out of range.
;rcall :sub32u
;=========================================================================
div32u:
push temp
push R31 ;R31:R30:R29:R28 chua so bi chia ban dau
push R30
push R29
push R28
push R27 ;R27:R26:R25:R24 =thuong chay
push R26
push R25
push R24
mov temp,Y1
or temp,Y0
cpi temp,0 ;Y=0?
brne div32u_ok ;neu Y#0 thi thuc hien chia
set ;set T
bld co_tinhtoan,zov ;zov =1 neu Y=0
rjmp end_div32u
div32u_ok:
clr Y3 ;Y3 =0
clr Y2 ;Y2 =0
push X3 ;cat so bi chia vao stack
push X2
push X1
push X0
mov R31,X3 ;cat so bi chia ban dau
mov R30,X2 ;vao so du ban dau
mov R29,X1
mov R28,X0
clr X3 ;clear partial remainder
clr X2
clr X1
clr X0
clr R27 ;clear thuong chay
clr R26
clr R26
clr R25
ldi dem,32 ;nap so dem
div32u_loop:
clc
rol R28 ;rol so du ban dau
rol R29
rol R30
rol R31
rol X0 ;rol X
rol X1
rol X2
rol X3
rcall sub32u
sbrc co_tinhtoan,zov ;skip neu zov=0
rjmp khong_tru_duoc_div32u
sec ;lam cho C=1
mov X3,Z3 ;update so du
mov X2,Z2
mov X1,Z1
mov X0,Z0
rjmp rol_thuongchay
khong_tru_duoc_div32u:
clc ;lam cho C=0
rol_thuongchay:
rol R24
rol R25
rol R26
rol R27
dec dem
cpi dem,0 ;dem =0?
brne div32u_loop
mov Z3,R27 ;cat thuong so
mov Z2,R26
mov Z1,R25
mov Z0,R24
mov PR1,X1 ;cat so du
mov PR0,X0
pop X0 ;lay lai so bi chia tu stack
pop X1
pop X2
pop X3
clt ;clear T
bld co_tinhtoan,zov ;divisor is not 0
end_div32u:
pop R24
pop R25
pop R26
pop R27
pop R28
pop R29
pop R30
pop R31
pop temp
ret
;=========================================================================
;subroutine sub32u
;function :tru hai so 32 bits khong dau
;input :so bi tru =X(X3:X2:X1:X0)
; :so tru =Y(Y3:Y2:Y1:Y0)
;output :Z(Z3:Z2:Z1:Z0) =X-Y.
; if Y > X then ZOV = 1
;=========================================================================
sub32u:
push temp ;cat temp vao stack
mov temp,X0 ;X0-->temp
clc ;clear carry
sbc temp,Y0 ;X0-Y0-0 -->temp
mov Z0,temp ;duoc Z0
mov temp,X1 ;X1-->temp
sbc temp,Y1 ;X1-Y1-c -->temp
mov Z1,temp ;duoc Z1
mov temp,X2 ;X2-->temp
sbc temp,Y2 ;X2-Y2-C -->temp
mov Z2,temp ;duoc Z2
mov temp,X3 ;X3-->temp
sbc temp,Y3 ;X3-Y3-C -->temp
mov Z3,temp ;duoc Z3
brcs set_zov_sub32u ;neu c=1 thi set zov
clt ;clear T
bld co_tinhtoan,zov ;zov=0
rjmp end_sub32u
set_zov_sub32u:
set ;set T
bld co_tinhtoan,zov ;set zov
end_sub32u:
pop temp ;lay lai temp tu stack
ret
;=========================================================================
; MODULE CONVERT
; sub : hectodec
; sub : decto7seg (A chung)
;=========================================================================
; subr :hextodec
;function :doi hai byte so hex ra 4 byte so dec
;input :X(X1:X0) o dang hex
;output :Digit3:Digit2:Digit1:Digit0
; Digit3 la chu so hang nghin
; Digit2 la chu so hang tram
; Digit1 la chu so hang chuc
; Digit0 la chu so hang don vi
;=========================================================================
hextodec: ;#htd_nd
push temp
push X0
push X1
ldi temp,high(500)
mov Y1,temp
ldi temp,low(500)
mov Y0,temp
rcall mul16u ;N*1000
mov X0,Z0
mov X1,Z1
mov X2,Z2
mov X3,Z3
ldi temp,low(1023)
mov Y0,temp
ldi temp,high(1023)
mov Y1,temp
ldi temp,0
mov Y2,temp
ldi temp,0
mov Y3,temp
rcall div32u ;(N*1000)/1023
mov X0,Z0
mov X1,Z1
ldi temp,10
mov Y0,temp
ldi temp,0
mov Y1,temp
rcall div16u
sts led0,PR0
mov X0,Z0
mov X1,Z1
ldi temp,10
mov Y0,temp
ldi temp,0
mov Y1,temp
rcall div16u
sts led1,PR0
sts led2,Z0
pop X1
pop X0
pop temp
ret
;=========================================================================
; subr :hextodec
;function :doi hai byte so hex ra 4 byte so dec
;input :X(X1:X0) o dang hex
;output :Digit3:Digit2:Digit1:Digit0
; Digit3 la chu so hang nghin
; Digit2 la chu so hang tram
; Digit1 la chu so hang chuc
; Digit0 la chu so hang don vi
;=========================================================================
hextodec_da: ;#htda
push temp
push X0
push X1
ldi temp,0x00
mov Y1,temp
ldi temp,100
mov Y0,temp
rcall mul16u ;N*100
mov X0,Z0
mov X1,Z1
mov X2,Z2
mov X3,Z3
ldi temp,low(1023)
mov Y0,temp
ldi temp,high(1023)
mov Y1,temp
ldi temp,0
mov Y2,temp
ldi temp,0
mov Y3,temp
rcall div32u ;(N*100)/1023
mov X0,Z0
ldi temp,10
mov Y0,temp
rcall div8u
sts led4,Z0
sts led3,PR0
pop X1
pop X0
pop temp
ret
;=========================================================================
; Sub : decto7seg
; in : temp dang dec
; out : temp dang 7seg
;=========================================================================
decto7seg: ;#dt7
cpi temp,0
brne num1
ldi temp,0xc0 ; 0
rjmp quit
num1:
cpi temp,1
brne num2
ldi temp,0xf9 ; 1
rjmp quit
num2:
cpi temp,2
brne num3
ldi temp,0xa4 ; 2
rjmp quit
num3:
cpi temp,3
brne num4
ldi temp,0xb0 ; 3
rjmp quit
num4:
cpi temp,4
brne num5
ldi temp,0x99 ; 4
rjmp quit
num5:
cpi temp,5
brne num6
ldi temp,0x92 ; 5
rjmp quit
num6:
cpi temp,6
brne num7
ldi temp,0x82 ; 6
rjmp quit
num7:
cpi temp,7
brne num8
ldi temp,0xf8 ; 7
rjmp quit
num8:
cpi temp,8
brne num9
ldi temp,0x80 ; 8
rjmp quit
num9:
cpi temp,9
brne quit
ldi temp,0x90 ; 9
quit:
nop
ret
;=========================================================================
; CAC SUBR DELAY
;=========================================================================
; subr :delay1s
;function :tao khoang tre 1s
;=========================================================================
delay1s:
push r19
ldi R17, $09
LOOP0_1s: ldi R18, $BC
LOOP1_1s: ldi R19, $C4
LOOP2_1s: dec R19
brne LOOP2_1s
dec R18
brne LOOP1_1s
dec R17
brne LOOP0_1s
pop r19
ret
;=========================================================================
; subr :delay2ms
;function :2000 cycles
; delaying 1998 cycles:
;=========================================================================
delay2ms:
; delaying 498 cycles:
ldi R17, $AA
WGLOOP0: dec R17
brne WGLOOP0
; -----------------------------
; delaying 2 cycles:
nop
nop
ret
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++