;有位网友写了一个倒计时秒表的程序,程序中的变量,采用了逐次加一的方法。
;变量加一,怎么能够倒计时呢?
;原来,程序中段码的排列次序,反过来了。
;于是:
;当变量是0的时候,查找出来9的段码,送去显示;
;当变量是1的时候,查找出来8的段码,送去显示;
;……
;当变量是9的时候,查找出来1的段码,送去显示。
;更改一下七段码表的次序,竟然可以使程序由正计时,变成倒计时!
;构思极为巧妙。
;PROTEUS 仿真截图如下:
;图片链接:http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/album/item/d8186c3cec4a335fbba167b3.html#
;程序使用汇编语言编写,原程序的结构有些凌乱,没有达到预期的效果。
;做而论道稍加整理,可以正常工作了,全部程序如下。
;硬件中,设置了一个按键,用以控制计时器的启动、暂停和复位。
SECOND EQU 30H
TCOUNT EQU 31H
KCOUNT EQU 32H
KEY BIT P3.7
ORG 00H
SJMP START
ORG 0BH
LJMP T0_INT
;----------------------------------------
START:
MOV P0, #6FH ;开始, 数码管显示"99"
MOV P2, #6FH
MOV TMOD, #01H ;T0定时方式1
MOV TH0, #(65536 - 50000) / 256
MOV TL0, #(65536 - 50000) MOD 256
MOV IE, #82H
MOV SECOND, #0
MOV TCOUNT, #0
MOV KCOUNT, #0
;----------------------------------------
K0:
JB KEY, $ ;等待按键按下
CALL DELAY ;延时
JB KEY, K0 ;没有按下,就是抖动
JNB KEY, $ ;等待按键松开
INC KCOUNT ;按键次数值加1
;----------------------
MOV A, KCOUNT ;判断按键次数
K1:
CJNE A, #1, K2
SETB TR0 ;第1次按键, 启动定时器
JMP K0
;----------------------
K2:
CJNE A, #2, START
CLR TR0 ;第2次按键, 关闭定时器
JMP K0
;----------------------------------------
T0_INT:
MOV TL0, #(65536 - 50000) MOD 256
MOV TH0, #(65536 - 50000) / 256
INC TCOUNT
MOV A, TCOUNT
; CJNE A, #2, T0_END ;是否计0.1秒?
CJNE A, #10, T0_END ;2, 速度太快,不便观察,暂用10
MOV TCOUNT, #0
INC SECOND
MOV A, SECOND
CJNE A, #100, DISP ;是否够10秒?
MOV SECOND, #0
DISP:
MOV DPTR, #TABLE
MOV A, SECOND
MOV B, #10
DIV AB
MOVC A, @A+DPTR ;显示时间
MOV P0, A
MOV A, B
MOVC A, @A+DPTR
MOV P2, A
T0_END:
RETI
;----------------------------------------
TABLE:
;9~0的段码, 反序排序。使用反序,可显示倒计时
DB 6FH, 7FH, 07H, 7DH, 6DH
DB 66H, 4FH, 5BH, 06H, 3FH
;0~9的段码, 正序
; DB 3FH, 06H, 5BH, 4FH, 66H
; DB 6DH, 7DH, 07H, 7FH, 6FH
;----------------------------------------
DELAY:
MOV R6, #20
D1: MOV R7, #250
DJNZ R7, $
DJNZ R6, D1
RET
;----------------------------------------
END