您好,欢迎来到99网。
搜索
您的当前位置:首页ATC51数字电子钟

ATC51数字电子钟

来源:99网
ATC51数字电子钟(已测试通过)

[日期:2010-09-16 ] [来源:本站原创 作者:佚名] [字体:大 中 小] (投递新闻)

该数字钟可实现精度误差≤ 1S/天的变精度时钟,并能方便地调节时钟、时间、定时时间等.

led1 bit p1.0 ;LED定义 led2 bit p1.1 led3 bit p1.2 led4 bit p1.3 led5 bit p1.4 led6 bit p1.5 led7 bit p1.6 led8 bit p1.7

s1 bit p0.0 s2 bit p0.1 s3 bit p0.2 s4 bit p0.3 s5 bit p0.4 s6 bit p0.5 s7 bit p0.6 s8 bit p0.7

led_data equ p2

key1 bit p3.5 key2 bit p3.6 key3 bit p3.7 key equ 56h

time_h equ 57h time_l equ 58h

t_h equ 60h t_s equ 61h t_m equ 62h

time equ 63h timer_h equ h timer_m equ 65h

timset bit 00h

disstart equ 70h

;数码管位数定义 ;数码管定义 ;按键定义 ;定时初值高位 ;低位 ;时分秒对应的地址 ;时钟计数单元 ;定时时单元 ;定时分单元 ;设置时间标志 ;显示单元首地址 int_data equ 45h ;中断数据地址 count_data equ 44h ;计数单元地址 timer_data equ 43h ;定时地址 ; ************** 以上为预定义部分

; ************** 以下程序开始

org 00h ;程序开始地址

jmp main ;跳转到代码开始处

org 1bh ;定时器 T1 中断服务程序入口 jmp tim1

org 030h ;主程序开始的地址 30H

main:MOV sp,#30h ;首先定义堆栈 lcall rest ;初始化

lcall pro_set ;设置定时器开始工作 lpp:lcall time_set ;接受用户设置时间 lcall timer ;时钟处理

lcall time_pro ;时间格式处理,码型变化等 lcall time_display ;显示 jmp lpp

; ************* 初始化程序 *************************** rest:MOV a,#00h ;累加器清零 MOV b,#00h

MOV p0,#0 ;数码管禁止显示 MOV t_h,#0 ;时单元 MOV t_m,#0 ;分单元 MOV t_s,#0 ;秒单元

MOV time,#00h ;计数溢出次数,溢出20次为一秒 clr timset ;定时设置标志位,0->增加 1 ->减少 MOV timer_h,#12 ;定时器时单元,设置定时为 12:00 MOV timer_m,#00h ;定时器分单元 MOV p2,#255 ;禁止显示数码管 clr beep ;禁止蜂鸣器 ret ;返回 ; *************** 定时器 T1 中断服务程序 ****

tim1:clr tr1 ;首先停止定时操作 MOV th1,time_h ; MOV tl1,time_l

inc time ;自增

MOV a,time ;取得溢出次数

cjne a,#20,retend ;如果满20此表示到 1 秒 cpl p1.0 ;取反p1.0,p1.1指示秒钟

cpl p1.1

MOV time,#00h ;重新开始等待1秒 inc t_s ;秒单元加1 retend:setb tr1 ;定时开始 reti ;中断返回

; ***************** 设置定时器初始化,定时时间为 50ms **** pro_set:MOV dptr,#0000h ;数据指针清零

MOV tmod,#10h ;设置定时器1工作在方式1 MOV time_h,#3ch ;计算定时50ms需要的初值 MOV th1,time_h ;保存高位 MOV time_l,#0c1h ;低位 MOV tl1,time_l ;保存低位

setb ea ;总的中断允许 setb et1 ;定时器1允许 setb tr1 ;定时器1开始运行 ret ;返回

; ****************** timer 程序主要完成数据的处理 ********** timer:MOV a,t_s ;取得秒单元数据 cjne a,#60,tend ;秒不到60返回 MOV t_s,#00h ;清除秒单元 inc t_m ;为分单元加1

MOV a,t_m ;取得分单元数据 cjne a,#60,tend ;分不等于60返回 MOV t_m,#00h ;分单元清零 setb beep ;整点短鸣提示 lcall delay ;鸣叫延时 clr beep ;停止蜂鸣器

inc t_h ;同时为时单元加1 MOV a,t_h ;取得时单元数据

cjne a,#24,timetest ;如果不等于24,查看定时 MOV t_h,#00h ;时单元清零 jmp tend ;返回

timetest:cjne a,timer_h,tend ;不等于定时的时单元,返回 MOV a,t_m ;取得定时的分单元

cjne a,timer_m,tend ;当前分不等于定时的分单元,返回 setb beep ;定时到,蜂鸣提示 lcall delay clr beep lcall delay setb beep lcall delay

clr beep ;连续发出短音提示 tend:ret ;返回

; ************ time_display 程序主要为显示时间值用 ************* time_display: MOV r0,#disstart ;取得显示单元首地址 MOV r1,#01h ;从第一个数码管开始 MOV r2,#06h ;共6个数码管 dislp:MOV led_data,@r0 ;获得当前单元数据 inc r0 ;指向下一个单元 MOV p0,r1 ;数码显示

MOV a,r1 ;为下一个数准备 rl a ;下一个单元 MOV r1,a ;保存

lcall delay5ms ;为了保证数码管亮度, ;但要防止闪烁,延时5ms

djnz r2,dislp ;重复显示,直到全部数据刷新过 ret ;返回

; ******* time_pro 时间处理,主要为 bcd码转换,查表 *********** time_pro:lcall bcd ;BCD码转换

MOV r0,#disstart ;获得显示单元首地址 MOV r2,#06h ;需要转换的个数

prlp:MOV a,@r0 ;取得当前需要转换的数据 MOV dptr,#tab_nu ;获得表头

MOVc a,@a+dptr ;获得转换后的数据 MOV @r0,a ;存回去 inc r0 ;指向下一个

djnz r2,prlp ;重复转换,直到6个全部完成 ret ;返回

; **************** 码型变换 **************************************** bcd:MOV r0,#disstart ;获得首地址

MOV a,t_s ;获得待转化的低位

MOV b,#10 ;转化进制,如果要进行十进制转换 改为 10

div ab ;计算 A/B

MOV @r0,b ;第一位转换完毕,保存低位转化后的数据 inc r0 ;自增

MOV @r0,a ;保存高位

inc r0 ;取第二个数据地址

MOV a,t_m ;获得第二个需要转换的数据 MOV b,#10 ;十六进制 div ab ;计算

MOV @r0,b ;存低位 inc r0

MOV @r0,a ;存高位

inc r0 ;第三位 MOV a,t_h ;获得数据 MOV b,#10 ;十六进制 div ab ;计算

MOV @r0,b ;存低位 inc r0

MOV @r0,a ;存高位 ret ;完毕,返回

;*************************************************************************************** ;******** time_set 设置时间 ******************************************************* ; * *

; * 检测用户按键,1-> 设置时单元 2-> 设置分单元,3->设置增减方式 *

; * 如果需要增加 时,先将方式设置为 增加(默认为减),即,按下 KEY3一下, *

; * 然后按 KEY1 ,如果要减少时单元,需要再次按下KEY3,然后按KEY1; * ; * 分的设置也是如此。 *

;***************************************************************************************

time_set:MOV p0,#00h ;禁止数码管显示 MOV p2,#255 ;防止按键时闪烁 lcall pro_key ;查找用户按键情况 MOV a,key ;查找键值

jz tsend ;如果等于0,表示没用按键,直接返回 cjne a,#1,tset1 ;是否等于1?没有到下一个处理程序

MOV key,#00h ;等于1,表示设置时 请零,否则会引起重复设置

jb timset,tset10 ;时间设置标志位,1 ->减少,0->增加 MOV a,t_h ;标志位 0 ,增加,取得时单元 cjne a,#23,ts1 ;如果时单元不等于23,转移到增加操作 jmp tsend ;等于23 直接返回 ts1:inc t_h ;时单元增加1 jmp tsend ;返回

tset10: MOV a,t_h ;这里处理为减少的情况 jz tsend ;如果时单元为0,直接返回 dec t_h ;否则,数据减1

jmp tsend ;返回,以下关于分的设置一样 tset1:cjne a,#2,tset2 ;如果按键不是 2 则 转移到下一个处理 MOV key,#00h ;是2,表示设置 分

jb timset,tset20 ;其余同上 MOV a,t_m cjne a,#59, ts2 jmp tsend ts2:inc t_m jmp tsend tset20:MOV a,t_m jz tsend dec t_m jmp tsend

tset2:cjne a,#3,tsend ;等于 3 表示设置标志 MOV key,#00h ;清零 cpl timset ;标志取反 tsend:ret ;返回

;********* 按键处理 读取键盘 ************************* ;参见有关键盘查询的说明,和前面的有关程序

pro_key: ;键盘查询子程序

setb key1 ;首先输出高电平,检测低电平的到来 setb key2 ;不同电路,可能检测方式不一样 setb key3

jb key1,ke1 ;如果用户没有按第一个键,到第下个处理部分, MOV key,#1 ;表示用户按了第一个键 lcall delay20ms ;软件延时,防止干扰

jmp pro_key ;重新查询,直到用户释放按键

ke1:jb key2,ke2 ;处理第二个按键,如果没有到下一个处理部分 MOV key,#2 ;以下和第一个处理单元相似。 lcall delay20ms jmp pro_key ke2:jb key3,ke3 MOV key,#3 lcall delay20ms jmp pro_key ke3:ret

;************************************** ;******** 定时器 T0 设置 **************

;定时器工作在方式1,为提高精度,总定时时间为50ms, ;定时器溢出20次为1秒,

pro_timer:MOV tmod,#01h ;设置定时器为定时方式1 MOV th0,#0ffh ;初始化定时初值 MOV tl0,#0a1h ;

setb ea ;总中断允许 setb et0 ;定时器0 允许 setb tr0 ;开始定时

ret ;返回 ; ***************************************** ; *************** 软件延时 *************

delay:push psw ;保存原来的寄存器内容 clr psw.3 ;

clr psw.4 ;设置新的寄存器组 MOV r0,#2 ;延时参数1 MOV r1,#250 ;延时参数2 MOV r2,#2 ;延时参数3 dl1:djnz r0,dl1 ;延时循环1 MOV r0,#250 ;

dl2:djnz r1,dl1 ;延时循环2 MOV r0,#240 ; MOV r1,#248 ;

dl3:djnz r2,dl1 ;延时循环3

nop ;定时精度调整 pop psw ;恢复原来的寄存器 ret ;返回 ;***************************************** ;*************** 键盘延时 *************** delay20ms:push psw clr psw.3 clr psw.4

MOV r0,#250 MOV r1,#40 d20:djnz r0,d20 MOV r0,#250 djnz r1,d20 pop psw ret

;************************************** ;*********** 延时 5ms **************** delay5ms:push psw clr psw.3 setb psw.4 MOV r0,#250 MOV r1,#10 d5:djnz r0,d5 MOV r0,#250 djnz r1,d5 pop psw ret

;************************************************************************************

;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16 ; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推

tab_nu:db 0c0h, 0f9h, 0a4h, 0b0h, 99h , 92h , 82h, 0f8h ;数字0-7 不带小数点代码 db 80h , 90h, 88h , 83h , 0c6h, 0a1h, 86h, 8eh ;数字8-f 不带小数点代码 db 40h , 79h, 24h , 30h , 19h , 12h , 02h, 78h ;数字0-7 带小数点代码 db 00h , 10h, 08h , 03h , 46h , 21h , 06h, 0eh ;数字8-f 带小数点代码 end ;

参考链接:http://www.picavr.com/news/2010-09/2325.htm

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务