e đang làm đèn giao thông sử dụng AT89c52..e mắc phải lỗi sau: bắt đầu chạy e đặt cột 1 sáng đèn đỏ 30s (đếm ngược từ 30 về 0), cột 2 đèn xanh 25s(đếm ngược từ 25 về 0)..đèn vàng là 5s..sau khi cột đèn đỏ chạy đến 0s thì nó sẽ phải chuyển sang giây thứ 25 của đèn xanh..NHƯNG bài e làm nó lại nhảy sang giây 20 rồi 24 và đếm ngc về k..tất cả về sau cũng thế...nó k hiện giây 25 nữa mà nó lại hiện giây 20 rồi 24-23-22...0..có ai biết k giúp e với e đang cần gấp! thanks..đây là code và mô phỏng của e:
#include <sfr51.inc>
time equ 30h ;thời gian sáng đèn đỏ
gtime equ 31h ;thời gian sáng đèn xanh
st1 equ 32h ; st1, st2 ghi trạng thái của 2 cột đèn
st2 equ 33h ;0 = xanh, 1 = vàng, 2 = đỏ
chuki equ 34h ;xác định nửa chu kì 0 hoặc 1
org 0h
ljmp main
org 0bh
ljmp timer0isr
org 40h
main:
mov sp,#5fh
mov tmod,#01h
setb ET0
setb EA
mov th0,#high(15535)
mov tl0,#low(15535)
setb tr0
mov r5,#0 ;biến đếm số lần tràn timer
mov time,#30 ;thời gian đèn đỏ là 30 giây
mov st1,#0 ;st1 = 0 đèn 1 xanh
mov st2,#2 ;st2 = 2 đèn 2 đỏ
mov chuki,#0 ;nửa chu kì đầu là 0
mov dptr,#table
mov p1,#12h ;bật đèn 1 xanh, đèn 2 đỏ
mov r0,#5
mov r1,#2
mov r3,#3
;========================
sangled: ;quét led 7 thanh hiện thời gian
;cột đèn 1
cjne r0,#-1,led1ondv ;nếu r0≠-1 cho sáng led đơn vị đèn 1
sjmp led1offdv ;nếu r0=-1 tắt led đơn vị đèn 1
led1ondv: mov a,r0 ;quét led 7 thanh đơn vị đèn 1
movc a,@a+dptr
mov p0,a
setb p3.5
lcall delay
led1offdv: clr p3.5
cjne r1,#0,led1onch ;nếu r1≠0 cho sáng led chục đèn 1
sjmp led1offch ;nếu r1=0 tắt led chục đèn 1
led1onch: mov a,r1 ;quét led 7 thanh chục đèn 1
movc a,@a+dptr
mov p0,a
setb p3.4
lcall delay
led1offch: clr p3.4
;cột đèn 2 (tương tự như cách quét led ở cột đèn 1)
cjne r2,#-1,led2ondv
sjmp led2offdv
led2ondv: mov a,r2
movc a,@a+dptr
mov p0,a
setb p3.7
lcall delay
led2offdv: clr p3.7
cjne r3,#0,led2onch
sjmp led2offch
led2onch: mov a,r3
movc a,@a+dptr
mov p0,a
setb p3.6
lcall delay
led2offch: clr p3.6
sjmp sangled ;lặp lại quá trình quét led 7 thanh
;============================
dectime: ;thực hiện các công việc khi 1 giây tiếp theo trôi qua
dec time ;giảm giá trị biến time đi 1 đơn vị
clr c ;thời gian sáng đèn đỏ bằng tổng thời
mov a,time ;gian sáng đèn xanh và đèn vàng
subb a,#5 ;đặt thời gian sáng đèn vàng là 5 giây
mov gtime,a ;=> time – 5 = gtime
mov r7,time
cjne r7,#4,cmp0 ;nếu time≠4: nhảy tới nhãn cmp0
mov r6,chuki
cjne r6,#1,time40 ;nếu time=4,chuki=0: nhảy tới time40
sjmp time41 ;nếu time=4,chuki=1: nhảy tới time41
cmp0: cjne r7,#-1,tieptuc ;nếu time≠-1: nhảy tới nhãn tieptuc
lcall chgst1 ;nếu time=-1: gọi 2 CTC chgst1 và
lcall chgst2 ;chgst2 để thay đổi giá trị st1, st2
lcall doichuki ;gọi CTC doichuki thay đổi nửa chu kì
tieptuc: mov r6,st1 ;kiểm tra sự thay đổi giá trị của các
mov r7,st2 ;biến trạng thái st1, st2 để kiểm soát
cjne r6,#1,nhan1 ;việc hiển thị trên các led 7 thanh
lcall tatled1 ;Cột đèn nào sáng đèn xanh thì led 7
;thanh hiện gtrị biến time, sáng đèn đỏ
cmpst2: cjne r7,#1,nhan2 ;thì led 7 thanh hiện gtrị biến gtime,
lcall tatled2 ;sáng đèn vàng thì tắt led 7 thanh ở
retdectime:ret ;cột đèn đó.
;==============================
nhan1: cjne r6,#2,do2xanh1
sjmp cmpst2
;=============================
nhan2: cjne r7,#2,do1xanh2
sjmp retdectime
;=============================
tatled1: ;CTC tắt led 7 thanh của cột đèn 1
mov r1,#0 ;cho r1=0, r0=-1 để khi quét led thì
mov r0,#-1 ;led 7 thanh của cột đèn 1 không sáng
lcall tdo
mov r2,b ;cho led 7 thanh của cột đèn 2 tiếp tục
mov r3,a ;đếm giây
ret
;=============================
tatled2: ;CTC tắt led 7 thanh của cột đèn 2
mov r3,#0 ;cho r3=0, r2=-1 để khi quét led thì
mov r2,#-1 ;led 7 thanh của cột đèn 2 không sáng
lcall tdo
mov r0,b ;cho led 7 thanh của cột đèn 1 tiếp tục
mov r1,a ;đếm giây
ret
;=============================
do2xanh1:
lcall tdo ;cho led 7 thanh của cột đèn 2 hiện
mov r2,b ;gtrị của biến time tức là thời gian
mov r3,a ;sáng đèn đỏ
lcall txanh ;cho led 7 thanh của cột đèn 1 hiện
mov r0,b ;gtrị của biến gtime tức là thời gian
mov r1,a ;sáng đèn xanh
sjmp retdectime
;=============================
do1xanh2:
lcall tdo ;cho led 7 thanh của cột đèn 1 hiện
mov r0,b ;gtrị của biến time tức là thời gian
mov r1,a ;sáng đèn đỏ
lcall txanh ;cho led 7 thanh của cột đèn 2 hiện
mov r0,b ;gtrị của biến gtime tức là thời gian
mov r1,a ;sáng đèn xanh
sjmp retdectime
;=============================
tdo: mov b,#10 ;time/10 thương cho vào a,
mov a,time ;dư cho vào b => a là số chục, b là số
div ab ;đơn vị của time
ret
;=============================
txanh:
mov b,#10 ;gtime/10 thương cho vào a,
mov a,gtime ;dư cho vào b => a là số chục, b là số
div ab ;đơn vị của gtime
ret
;==============================
Time40: ;tại thời điểm time=4 của nửa chu kì đánh số 0 thì
lcall chgst1 ;gọi CTC đổi trạng thái cột đèn 1
sjmp cmp0 ;rồi nhảy về nhãn cmp0
;==============================
Time41: ;tại thời điểm time=4 của nửa chu kì đánh số 1 thì
lcall chgst2 ;gọi CTC đổi trạng thái cột đèn 2
sjmp cmp0 ;rồi nhảy về nhãn cmp0
;==============================
doichuki:
inc chuki ;tăng chuki lên 1 đơn vị
mov a,chuki ;sau đó thực hiện chia chuki cho 2, lấy
mov b,#2 ;phần dư gán trả lại cho biến chuki
div ab ;như vậy giá trị biến chuki sẽ thay đổi
mov chuki,b ;qua lại giữa 0 và 1
mov time,#30 ;khởi tạo lại gtrị cho biến time về 30s
clr c ; gtime = time - 5
mov a,time
subb a,#5 ; thời gian đèn vàng là 5s
mov gtime,a
ret
;==============================
chgst1: ;CTC thay đổi gtrị biến trạng thái st1 của cột đèn 1
inc st1 ;tăng st1 lên 1đv, st1/3 lấy phần dư
mov a,st1 ;gán trả lại cho st1 (chia 3 vì st1
mov b,#3 ;nhận 1 trong 3 gtrị 0,1,2)
div ab ;Sau khi thay đổi gtrị biến st1 thì
mov st1,b ;kiểm tra ngay giá trị đó để bật tắt
mov r7,st1 ;đèn tín hiệu trên cột đèn 1:
cjne r7,#0,sosanh1 ;st1≠0 => nhảy đến nhãn sosanh1
lcall xanh1 ;nếu st1=0 => gọi CTC xanh1
retst1: ret
sosanh1:
cjne r7,#1,do1 ;nếu st1≠1=> st1=2 => gọi CTC do1
sjmp vang1 ;tr.hợp còn lại => gọi CTC vang1
;==============================
chgst2: ;CTC thay đổi gtrị biến trạng thái st2 của cột đèn 2
inc st2 ;CTC này hoạt động tương tự CTC chgst1
mov a,st2
mov b,#3
div ab
mov st2,b
mov r7,st2
cjne r7,#0,sosanh2
lcall xanh2
retst2: ret
sosanh2:
cjne r7,#1,do2
sjmp vang2
;==============================
xanh1: ;bật đèn xanh ở cột đèn 1
setb p1.1
clr p1.3
clr p1.5
ret
vang1: ;bật đèn vàng ở cột đèn 1
setb p1.3
clr p1.1
clr p1.5
ret
do1: ;bật đèn đỏ ở cột đèn 1
setb p1.5
clr p1.3
clr p1.1
ret
;=============================
xanh2: ;bật đèn xanh ở cột đèn 2
setb p1.0
clr p1.2
clr p1.4
ret
vang2: ;bật đèn vàng ở cột đèn 2
setb p1.2
clr p1.0
clr p1.4
ret43
do2: ;bật đèn đỏ ở cột đèn 1
setb p1.4
clr p1.0
clr p1.2
ret
;==============================
timer0isr: ;CTC phục vụ ngắt, được gọi mỗi khi timer0 tràn
mov th0,#high(15535)
mov tl0,#low(15535)
inc r5 ;tăng r5 lên 1đv
cjne r5,#20,thoat ;nếu số lần tràn timer < 20 thì thoát
mov r5,#0 ;nếu số lần tràn timer = 20 thì reset
lcall dectime ;gtrị thanh ghi r5 về 0 để đếm lại từ
thoat: reti ;đầu, sau đó gọi CTC dectime
;==============================
delay: mov r4,#100 ;CTC tạo khoảng trễ 1ms
dl: nop
nop
nop
nop
nop
nop
nop
nop
djnz r4,dl
ret
;==============================
table: ;Bảng mã quét led 7 thanh Anode chung, a là LSB
db 0c0h,0f9h,0a4h,0b0h, 99h, 92h, 82h,0f8h, 80h, 90h
; 0 1 2 3 4 5 6 7 8 9
end
CÒN ĐÂY LÀ MÔ PHỎNG:mo phongn proteus.rar
#include <sfr51.inc>
time equ 30h ;thời gian sáng đèn đỏ
gtime equ 31h ;thời gian sáng đèn xanh
st1 equ 32h ; st1, st2 ghi trạng thái của 2 cột đèn
st2 equ 33h ;0 = xanh, 1 = vàng, 2 = đỏ
chuki equ 34h ;xác định nửa chu kì 0 hoặc 1
org 0h
ljmp main
org 0bh
ljmp timer0isr
org 40h
main:
mov sp,#5fh
mov tmod,#01h
setb ET0
setb EA
mov th0,#high(15535)
mov tl0,#low(15535)
setb tr0
mov r5,#0 ;biến đếm số lần tràn timer
mov time,#30 ;thời gian đèn đỏ là 30 giây
mov st1,#0 ;st1 = 0 đèn 1 xanh
mov st2,#2 ;st2 = 2 đèn 2 đỏ
mov chuki,#0 ;nửa chu kì đầu là 0
mov dptr,#table
mov p1,#12h ;bật đèn 1 xanh, đèn 2 đỏ
mov r0,#5
mov r1,#2
mov r3,#3
;========================
sangled: ;quét led 7 thanh hiện thời gian
;cột đèn 1
cjne r0,#-1,led1ondv ;nếu r0≠-1 cho sáng led đơn vị đèn 1
sjmp led1offdv ;nếu r0=-1 tắt led đơn vị đèn 1
led1ondv: mov a,r0 ;quét led 7 thanh đơn vị đèn 1
movc a,@a+dptr
mov p0,a
setb p3.5
lcall delay
led1offdv: clr p3.5
cjne r1,#0,led1onch ;nếu r1≠0 cho sáng led chục đèn 1
sjmp led1offch ;nếu r1=0 tắt led chục đèn 1
led1onch: mov a,r1 ;quét led 7 thanh chục đèn 1
movc a,@a+dptr
mov p0,a
setb p3.4
lcall delay
led1offch: clr p3.4
;cột đèn 2 (tương tự như cách quét led ở cột đèn 1)
cjne r2,#-1,led2ondv
sjmp led2offdv
led2ondv: mov a,r2
movc a,@a+dptr
mov p0,a
setb p3.7
lcall delay
led2offdv: clr p3.7
cjne r3,#0,led2onch
sjmp led2offch
led2onch: mov a,r3
movc a,@a+dptr
mov p0,a
setb p3.6
lcall delay
led2offch: clr p3.6
sjmp sangled ;lặp lại quá trình quét led 7 thanh
;============================
dectime: ;thực hiện các công việc khi 1 giây tiếp theo trôi qua
dec time ;giảm giá trị biến time đi 1 đơn vị
clr c ;thời gian sáng đèn đỏ bằng tổng thời
mov a,time ;gian sáng đèn xanh và đèn vàng
subb a,#5 ;đặt thời gian sáng đèn vàng là 5 giây
mov gtime,a ;=> time – 5 = gtime
mov r7,time
cjne r7,#4,cmp0 ;nếu time≠4: nhảy tới nhãn cmp0
mov r6,chuki
cjne r6,#1,time40 ;nếu time=4,chuki=0: nhảy tới time40
sjmp time41 ;nếu time=4,chuki=1: nhảy tới time41
cmp0: cjne r7,#-1,tieptuc ;nếu time≠-1: nhảy tới nhãn tieptuc
lcall chgst1 ;nếu time=-1: gọi 2 CTC chgst1 và
lcall chgst2 ;chgst2 để thay đổi giá trị st1, st2
lcall doichuki ;gọi CTC doichuki thay đổi nửa chu kì
tieptuc: mov r6,st1 ;kiểm tra sự thay đổi giá trị của các
mov r7,st2 ;biến trạng thái st1, st2 để kiểm soát
cjne r6,#1,nhan1 ;việc hiển thị trên các led 7 thanh
lcall tatled1 ;Cột đèn nào sáng đèn xanh thì led 7
;thanh hiện gtrị biến time, sáng đèn đỏ
cmpst2: cjne r7,#1,nhan2 ;thì led 7 thanh hiện gtrị biến gtime,
lcall tatled2 ;sáng đèn vàng thì tắt led 7 thanh ở
retdectime:ret ;cột đèn đó.
;==============================
nhan1: cjne r6,#2,do2xanh1
sjmp cmpst2
;=============================
nhan2: cjne r7,#2,do1xanh2
sjmp retdectime
;=============================
tatled1: ;CTC tắt led 7 thanh của cột đèn 1
mov r1,#0 ;cho r1=0, r0=-1 để khi quét led thì
mov r0,#-1 ;led 7 thanh của cột đèn 1 không sáng
lcall tdo
mov r2,b ;cho led 7 thanh của cột đèn 2 tiếp tục
mov r3,a ;đếm giây
ret
;=============================
tatled2: ;CTC tắt led 7 thanh của cột đèn 2
mov r3,#0 ;cho r3=0, r2=-1 để khi quét led thì
mov r2,#-1 ;led 7 thanh của cột đèn 2 không sáng
lcall tdo
mov r0,b ;cho led 7 thanh của cột đèn 1 tiếp tục
mov r1,a ;đếm giây
ret
;=============================
do2xanh1:
lcall tdo ;cho led 7 thanh của cột đèn 2 hiện
mov r2,b ;gtrị của biến time tức là thời gian
mov r3,a ;sáng đèn đỏ
lcall txanh ;cho led 7 thanh của cột đèn 1 hiện
mov r0,b ;gtrị của biến gtime tức là thời gian
mov r1,a ;sáng đèn xanh
sjmp retdectime
;=============================
do1xanh2:
lcall tdo ;cho led 7 thanh của cột đèn 1 hiện
mov r0,b ;gtrị của biến time tức là thời gian
mov r1,a ;sáng đèn đỏ
lcall txanh ;cho led 7 thanh của cột đèn 2 hiện
mov r0,b ;gtrị của biến gtime tức là thời gian
mov r1,a ;sáng đèn xanh
sjmp retdectime
;=============================
tdo: mov b,#10 ;time/10 thương cho vào a,
mov a,time ;dư cho vào b => a là số chục, b là số
div ab ;đơn vị của time
ret
;=============================
txanh:
mov b,#10 ;gtime/10 thương cho vào a,
mov a,gtime ;dư cho vào b => a là số chục, b là số
div ab ;đơn vị của gtime
ret
;==============================
Time40: ;tại thời điểm time=4 của nửa chu kì đánh số 0 thì
lcall chgst1 ;gọi CTC đổi trạng thái cột đèn 1
sjmp cmp0 ;rồi nhảy về nhãn cmp0
;==============================
Time41: ;tại thời điểm time=4 của nửa chu kì đánh số 1 thì
lcall chgst2 ;gọi CTC đổi trạng thái cột đèn 2
sjmp cmp0 ;rồi nhảy về nhãn cmp0
;==============================
doichuki:
inc chuki ;tăng chuki lên 1 đơn vị
mov a,chuki ;sau đó thực hiện chia chuki cho 2, lấy
mov b,#2 ;phần dư gán trả lại cho biến chuki
div ab ;như vậy giá trị biến chuki sẽ thay đổi
mov chuki,b ;qua lại giữa 0 và 1
mov time,#30 ;khởi tạo lại gtrị cho biến time về 30s
clr c ; gtime = time - 5
mov a,time
subb a,#5 ; thời gian đèn vàng là 5s
mov gtime,a
ret
;==============================
chgst1: ;CTC thay đổi gtrị biến trạng thái st1 của cột đèn 1
inc st1 ;tăng st1 lên 1đv, st1/3 lấy phần dư
mov a,st1 ;gán trả lại cho st1 (chia 3 vì st1
mov b,#3 ;nhận 1 trong 3 gtrị 0,1,2)
div ab ;Sau khi thay đổi gtrị biến st1 thì
mov st1,b ;kiểm tra ngay giá trị đó để bật tắt
mov r7,st1 ;đèn tín hiệu trên cột đèn 1:
cjne r7,#0,sosanh1 ;st1≠0 => nhảy đến nhãn sosanh1
lcall xanh1 ;nếu st1=0 => gọi CTC xanh1
retst1: ret
sosanh1:
cjne r7,#1,do1 ;nếu st1≠1=> st1=2 => gọi CTC do1
sjmp vang1 ;tr.hợp còn lại => gọi CTC vang1
;==============================
chgst2: ;CTC thay đổi gtrị biến trạng thái st2 của cột đèn 2
inc st2 ;CTC này hoạt động tương tự CTC chgst1
mov a,st2
mov b,#3
div ab
mov st2,b
mov r7,st2
cjne r7,#0,sosanh2
lcall xanh2
retst2: ret
sosanh2:
cjne r7,#1,do2
sjmp vang2
;==============================
xanh1: ;bật đèn xanh ở cột đèn 1
setb p1.1
clr p1.3
clr p1.5
ret
vang1: ;bật đèn vàng ở cột đèn 1
setb p1.3
clr p1.1
clr p1.5
ret
do1: ;bật đèn đỏ ở cột đèn 1
setb p1.5
clr p1.3
clr p1.1
ret
;=============================
xanh2: ;bật đèn xanh ở cột đèn 2
setb p1.0
clr p1.2
clr p1.4
ret
vang2: ;bật đèn vàng ở cột đèn 2
setb p1.2
clr p1.0
clr p1.4
ret43
do2: ;bật đèn đỏ ở cột đèn 1
setb p1.4
clr p1.0
clr p1.2
ret
;==============================
timer0isr: ;CTC phục vụ ngắt, được gọi mỗi khi timer0 tràn
mov th0,#high(15535)
mov tl0,#low(15535)
inc r5 ;tăng r5 lên 1đv
cjne r5,#20,thoat ;nếu số lần tràn timer < 20 thì thoát
mov r5,#0 ;nếu số lần tràn timer = 20 thì reset
lcall dectime ;gtrị thanh ghi r5 về 0 để đếm lại từ
thoat: reti ;đầu, sau đó gọi CTC dectime
;==============================
delay: mov r4,#100 ;CTC tạo khoảng trễ 1ms
dl: nop
nop
nop
nop
nop
nop
nop
nop
djnz r4,dl
ret
;==============================
table: ;Bảng mã quét led 7 thanh Anode chung, a là LSB
db 0c0h,0f9h,0a4h,0b0h, 99h, 92h, 82h,0f8h, 80h, 90h
; 0 1 2 3 4 5 6 7 8 9
end
CÒN ĐÂY LÀ MÔ PHỎNG:mo phongn proteus.rar
Comment