|
| AT89C2051制电子钟时钟源程序 |
|
|
at89c2051制电子钟时钟源程序 at89c2051制电子钟时钟源程序
本文来自五一电子网站,欢迎大家来本站免费注册:[url]http://www.51dz.com/dp.asp?dl=&xl=12&so=&fw=&gjz=&pg=2&sn=12728#&i=wangfei
本程序来自于互联网,站长尚没试验,但是,该程序给出了详细的说明,相信对大家很有帮助!因此,站长向原作者表示真诚谢意!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; at89c2051时钟程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ; 定时器t0、t1溢出周期为50ms,t0为秒计数用, t1为调整时闪烁用, ; p3.7为调整按钮,p1口 为字符输出口,采用共阳显示管。 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 中断入口程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; org 0000h ;程序执行开始地址 ljmp start ;跳到标号start执行 org 0003h ;外中断0中断程序入口 reti ;外中断0中断返回 org 000bh ;定时器t0中断程序入口 ljmp intt0 ;跳至intto执行 org 0013h ;外中断1中断程序入口 reti ;外中断1中断返回 org 001bh ;定时器t1中断程序入口 ljmp intt1 ;跳至intt1执行 org 0023h ;串行中断程序入口地址 reti ;串行中断程序返回 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 主 程 序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; start: mov r0,#70h ;清70h-7ah共11个内存单元 mov r7,#0bh ; cleardisp: mov @r0,#00h ; inc r0 ; djnz r7,cleardisp ; mov 20h,#00h ;清20h(标志用) mov 7ah,#0ah ;放入"熄灭符"数据 mov tmod,#11h ;设t0、t1为16位定时器 mov tl0,#0b0h ;50ms定时初值(t0计时用) mov th0,#3ch ;50ms定时初值 mov tl1,#0b0h ;50ms定时初值(t1闪烁定时用) mov th1,#3ch ;50ms定时初值 setb ea ;总中断开放 setb et0 ;允许t0中断 setb tr0 ;开启t0定时器 mov r4,#14h ;1秒定时用初值(50ms×20) start1: lcall display ;调用显示子程序 jnb p3.7,setmm1 ;p3.7口为0时转时间调整程序 sjmp start1 ;p3.7口为1时跳回start1 setmm1: ljmp setmm ;转到时间调整程序setmm ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 1秒计时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;t0中断服务程序 intt0: push acc ;累加器入栈保护 push psw ;状态字入栈保护 clr et0 ;关t0中断允许 clr tr0 ;关闭定时器t0 mov a,#0b7h ;中断响应时间同步修正 add a,tl0 ;低8位初值修正 mov tl0,a ;重装初值(低8位修正值) mov a,#3ch ;高8位初值修正 addc a,th0 ; mov th0,a ;重装初值(高8位修正值) setb tr0 ;开启定时器t0 djnz r4, outt0 ;20次中断未到中断退出 addss: mov r4,#14h ;20次中断到(1秒)重赋初值 mov r0,#71h ;指向秒计时单元(71h-72h) acall add1 ;调用加1程序(加1秒*作) mov a,r3 ;秒数据放入a(r3为2位十进制数组合) clr c ;清进位标志 cjne a,#60h,addmm ; addmm: jc outt0 ;小于60秒时中断退出 acall clr0 ;大于或等于60秒时对秒计时单元清0 mov r0,#77h ;指向分计时单元(76h-77h) acall add1 ;分计时单元加1分钟 mov a,r3 ;分数据放入a clr c ;清进位标志 cjne a,#60h,addhh ; addhh: jc outt0 ;小于60分时中断退出 acall clr0 ;大于或等于60分时分计时单元清0 mov r0,#79h ;指向小时计时单元(78h-79h) acall add1 ;小时计时单元加1小时 mov a,r3 ;时数据放入a clr c ;清进位标志 cjne a,#24h,hour ; hour: jc outt0 ;小于24小时中断退出 acall clr0 ;大于或等于24小时小时计时单元清0 outt0: mov 72h,76h ;中断退出时将分、时计时单元数据移 mov 73h,77h ;入对应显示单元 mov 74h,78h ; mov 75h,79h ; pop psw ;恢复状态字(出栈) pop acc ;恢复累加器 setb et0 ;开放t0中断 reti ;中断返回 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 闪动调时 程 序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;t1中断服务程序,用作时间调整时调整单元闪烁指示 intt1: push acc ;中断现场保护 push psw ; mov tl1, #0b0h ;装定时器t1定时初值 mov th1, #3ch ; djnz r2,intt1out ;0.3秒未到退出中断(50ms中断6次) mov r2,#06h ;重装0.3秒定时用初值 cpl 02h ;0.3秒定时到对闪烁标志取反 jb 02h,flash1 ;02h位为1时显示单元"熄灭" mov 72h,76h ;02h位为0时正常显示 mov 73h,77h ; mov 74h,78h ; mov 75h,79h ; intt1out: pop psw ;恢复现场 pop acc ; reti ;中断退出 flash1: jb 01h,flash2 ;01h位为1时,转小时熄灭控制 mov 72h,7ah ;01h位为0时,"熄灭符"数据放入分 mov 73h,7ah ;显示单元(72h-73h),将不显示分数据 mov 74h,78h ; mov 75h,79h ; ajmp intt1out ;转中断退出 flash2: mov 72h,76h ;01h位为1时,"熄灭符"数据放入小时 mov 73h,77h ;显示单元(74h-75h),小时数据将不显示 mov 74h,7ah ; mov 75h,7ah ; ajmp intt1out ;转中断退出 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 加1子 程 序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; add1: mov a,@r0 ;取当前计时单元数据到a dec r0 ;指向前一地址 swap a ;a中数据高四位与低四位交换 orl a,@r0 ;前一地址中数据放入a中低四位 add a,#01h ;a加1*作 da a ;十进制调整 mov r3,a ;移入r3寄存器 anl a,#0fh ;高四位变0 mov @r0,a ;放回前一地址单元 mov a,r3 ;取回r3中暂存数据 inc r0 ;指向当前地址单元 swap a ;a中数据高四位与低四位交换 anl a,#0fh ;高四位变0 mov @r0,a ;数据放入当削地址单元中 ret ;子程序返回 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 清零程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;对计时单元复零用 clr0: clr a ;清累加器 mov @r0,a ;清当前地址单元 dec r0 ;指向前一地址 mov @r0,a ;前一地址单元清0 ret ;子程序返回 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 时钟调整程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;当调时按键按下时进入此程序 setmm: clr et0 ;关定时器t0中断 clr tr0 ;关闭定时器t0 lcall dl1s ;调用1秒延时程序 jb p3.7,closedis ;键按下时间小于1秒,关闭显示(省电) mov r2,#06h ;进入调时状态,赋闪烁定时初值 setb et1 ;允许t1中断 setb tr1 ;开启定时器t1 set2: jnb p3.7,set1 ;p3.7口为0(键未释放),等待 setb 00h ;键释放,分调整闪烁标志置1 set4: jb p3.7,set3 ;等待键按下 lcall dl05s ;有键按下,延时0.5秒 jnb p3.7,sethh ;按下时间大于0.5秒转调小时状态 mov r0,#77h ;按下时间小于0.5秒加1分钟*作 lcall add1 ;调用加1子程序 mov a,r3 ;取调整单元数据 clr c ;清进位标志 cjne a,#60h,hhh ;调整单元数据与60比较 hhh: jc set4 ;调整单元数据小于60转set4循环 lcall clr0 ;调整单元数据大于或等于60时清0 clr c ;清进位标志 ajmp set4 ;跳转到set4循环 closedis: setb et0 ;省电(led不显示)状态。开t0中断 setb tr0 ;开启t0定时器(开时钟) close: jb p3.7,close ;无按键按下,等待。 lcall display ;有键按下,调显示子程序延时削抖 jb p3.7,close ;是干扰返回close等待 waith: jnb p3.7,waith ;等待键释放 ljmp start1 ;返回主程序(led数据显示亮) sethh: clr 00h ;分闪烁标志清除(进入调小时状态) sethh1: jnb p3.7,set5 ;等待键释放 setb 01h ;小时调整标志置1 set6: jb p3.7,set7 ;等待按键按下 lcall dl05s ;有键按下延时0.5秒 jnb p3.7,setout ;按下时间大于0.5秒退出时间调整 mov r0,#79h ;按下时间小于0.5秒加1小时*作 lcall add1 ;调加1子程序 mov a,r3 ; clr c ; cjne a,#24h,houu ;计时单元数据与24比较 houu: jc set6 ;小于24转set6循环 lcall clr0 ;大于或等于24时清0*作 ajmp set6 ;跳转到set6循环 setout: jnb p3.7,setout1 ;调时退出程序。等待键释放 lcall display ;延时削抖 jnb p3.7,setout ;是抖动,返回setout再等待 clr 01h ;清调小时标志 clr 00h ;清调分标志 clr 02h ;清闪烁标志 clr tr1 ;关闭定时器t1 clr et1 ;关定时器t1中断 setb tr0 ;开启定时器t0 setb et0 ;开定时器t0中断(计时开始) ljmp start1 ;跳回主程序 set1: lcall display ;键释放等待时调用显示程序(调分) ajmp set2 ;防止键按下时无时钟显示 set3: lcall display ;等待调分按键时时钟显示用 ajmp set4 set5: lcall display ;键释放等待时调用显示程序(调小时) ajmp sethh1 ;防止键按下时无时钟显示 set7: lcall display ;等待调小时按键时时钟显示用 ajmp set6 setout1: lcall display ;退出时钟调整时键释放等待 ajmp setout ;防止键按下时无时钟显示 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 显示程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 显示数据在70h-75h单元内,用六位led共阳数码管显示,p1口输出段码数据,p3口作 ; 扫描控制,每个led数码管亮1ms时间再逐位循环。 display: mov r1,#70h ;指向显示数据首址 mov r5,#0feh ;扫描控制字初值 play: mov a,r5 ;扫描字放入a mov p3,a ;从p3口输出 mov a,@r1 ;取显示数据到a mov dptr,#tab ;取段码表地址 movc a,@a+dptr ;查显示数据对应段码 mov p1,a ;段码放入p1口 lcall dl1ms ;显示1ms inc r1 ;指向下一地址 mov a,r5 ;扫描控制字放入a jnb acc.5,endout ;acc.5=0时一次显示结束 rl a ;a中数据循环左移 mov r5,a ;放回r5内 ajmp play ;跳回play循环 endout: setb p3.5 ;一次显示结束,p3口复位 mov p1,#0ffh ;p1口复位 ret ;子程序返回 tab: db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,0ffh ;共阳段码表 "0""1""2" "3""4""5""6""7" "8""9""不亮" ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 延时程序 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;1ms延时程序,led显示程序用 dl1ms: mov r6,#14h dl1: mov r7,#19h dl2: djnz r7,dl2 djnz r6,dl1 ret ;20ms延时程序,采用调用显示子程序以改善led的显示闪烁现象 ds20ms: acall display acall display acall display ret ;延时程序,用作按键时间的长短判断 dl1s: lcall dl05s lcall dl05s ret dl05s: mov r3,#20h ;8毫秒*32=0.196秒 dl05s1: lcall display djnz r3,dl05s1 ret ; end ;程序结束
--------------------------------------------------------------------------------
|
|