用汇编语言程序实现电子时钟
基本思想:
当需要编写程序实现较复杂的功能时,整个程序就如同一个装配体(总成),而子程序就如同装配体中的零件,子程序与主程序的接口就如同机械中的连接件将不同零件装配起来。
使用子程序能使程序结构更清晰,且逻辑不易发生错误。
实现电子时钟需要的子程序:
1.显示子程序disp
2.显示延时子程序dey1
3.中断服务intt0
4.中断服务退出子程序out
5.加一子程序add1
6.清空子程序clr0
应注意的事项:
1.位选应与段码输送相配合,若使用P2位选,P2.0连接最前端的数码管,则P2=#00000001B,即P2.0=1时,应输送小时的最高位段码
2.若通过P2左移实现显示,可通过左移次数判断一次显示是否完成,也可将P2的值赋给A,通过判断ACC.7是否为1得到一次显示是否完成,后者在实现上更方便
3.进入中断服务时,可将中断允许ET0先断开,在中断服务退出子程序中再将ET0打开,可减少计时误差
4.判断秒钟、分钟是否达到60,时钟是否达到24,用DJNE语句比用减法后判断JC更简单
5.当秒钟、分钟达到60,时钟达到24时,需调用清空子程序clr0将其清0
6.加一子程序add1可通过16进制数加#01h后通过十进制调整指令DA将其转换为10进制数,通过分别屏蔽高、低4位并通过SWAP指令分别赋给对应的显缓区
7.共阳极8位二极管显示0~9的段码分别为:
0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h
显示横杠(——)的段码为0bfh
共阴极段码取反即可
程序代码如下:
org 0000h
ljmp main
org 000bh
ljmp intt0
org 0100h
main: mov tmod,#01h
mov tl0,#0b0h
mov th0,#3ch
setb ea
setb et0
setb tr0
mov r4,#20
mov 73h,#10
mov 76h,#10
mov dptr,#table
loop: lcall disp
ljmp loop
disp: mov r3,#01h
mov r0,#78h
play: mov a,r3
mov p2,a
mov a,@r0
movc a,@a+dptr
mov p0,a
lcall dey1
mov a,r3
dec r0
jb acc.7,next
rl a
mov r3,a
ljmp play
next:ljmp disp
dey1: mov r6,#10
dl1: mov r7,#19h
dl2: djnz r7,dl2
djnz r6,dl1
ret
intt0: push acc
push psw
clr et0
clr tr0
mov tl0,#0b0h
mov th0,#3ch
setb tr0
djnz r4,out
adds: mov r4,#20
mov r0,#71h
lcall add1
mov a,r2
clr c
cjne a,#60h,addmin
addmin: jc out
lcall clr0
mov r0,#74h
lcall add1
mov a,r2
clr c
cjne a,#60h,addh
addh: jc out
lcall clr0
mov r0,#77h
lcall add1
mov a,r2
clr c
cjne a,#24h,hourreset
jc out
hourreset: lcall clr0
out: pop psw
pop acc
setb et0
reti
add1: inc r0
mov a,@r0
swap a
dec r0
orl a,@r0
add a,#01h
da a
mov r2,a
anl a,#0fh
mov @r0,a
mov a,r2
anl a,#0f0h
swap a
inc r0
mov @r0,a
ret
clr0: mov a,#0
mov @r0,a
dec r0
mov @r0,a
ret
table: db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,0bfh
end
使用proteus7.5仿真的效果如下: