用单片机内部的定时计数器来实现电子时钟的方法.docx
《用单片机内部的定时计数器来实现电子时钟的方法.docx》由会员分享,可在线阅读,更多相关《用单片机内部的定时计数器来实现电子时钟的方法.docx(9页珍藏版)》请在冰豆网上搜索。
![用单片机内部的定时计数器来实现电子时钟的方法.docx](https://file1.bdocx.com/fileroot1/2023-6/7/807f30d3-03b5-431e-a9bf-70f363af5a83/807f30d3-03b5-431e-a9bf-70f363af5a831.gif)
用单片机内部的定时计数器来实现电子时钟的方法
用单片机内部的定时/计数器来实现电子时钟的方法
时钟,自从它发明的那天起就成为人类的朋友,但随着时间的推移,科学技术的不段发展,人们对时间计量的精度要求越来越高,怎样让时钟更好的为人们服务,怎样让我们的老朋友焕发青春呢?
这就要求人们不断的设计出新型时钟。
现今,高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟,石英表都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调校;数字式电子钟用集成电路计时时,译码代替机械转动,用LED显示器代替指针进而显示时间,减小了计时误差,这种表具有时,分,秒显示时间的功能,还可以进行时和分,秒的校对,片选的灵活性好。
时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。
在一个单片机应用系统中,时钟有两方面的含义:
一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间,它通常有两种实现方法:
一是用软件实现,即用单片机内部的可编程定时/计数器来实现,但误差很大,主要用在对时间精度要求不高的场合;二是用专门的时钟芯片实现,在对时间精度要求很高的情况下,通常采用这种方法,典型的时钟芯片有:
DS1302,DS12887,X1203等都可以满足高精度的要求。
本文主要介绍用单片机内部的定时/计数器来实现电子时钟的方法
一.基本功能
1.时间显示功能:
显示时,分,秒,且计时初值为12:
00:
00
2.时间设置功能:
可以通过键盘任意设定,修改显示时间
二.硬件框图
在系统电路中显示器为6个共阳极的LED数码管,用一个BCD七段译码器74LS47驱动数码管(74LS47的输入为BCD码,其输出为集电极开路,可直接驱动七段译码器,具有首尾消零
等特点)用3-8译码器的74LS138的输出作为动态扫描数码管的选通信号。
因为采用了上述的两个芯片,所以在对数码管进行扫描显示时。
只需要单片机的7条I/O线就能完成显示功能了。
2.1单片机
单片机采用AT89C51型,它是一种带4K字节的闪烁可编程可擦处的只读存储的低电压,高性能的SMOS8位位处理器,该器件采用ATMEL高密度非易失性存储器制造技术和工业标准的MCS-51指令集和输出管脚相兼容,由于该8位多功能CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微处理器,为很多嵌入控制系统提供了一种灵活高而且价格低廉的方案。
2.2时钟显示电路
为了实现LED显示器的数字显示,可以采用静态显示法和动态显示法。
由于静态显示法需要数据锁存器等硬件,接口复杂一点,考虑到时钟显示只有6位,且系统没有其他复杂的处理任务,所以决定采用动态扫描法实现LED显示。
2.3时钟电路
如果设置过多的按键,将会占用很多的I/O口,而且给布线带来不便,按键过少,在修改时间和闹钟时间的时候就不能直接输入,只能通过加或者减来完成,稍为有点麻烦,但是程序简单,成本低,考虑到上述原因这里采用独立按键来实现。
2.4闹钟电路
当时间与设置闹钟时间相当时,通过I/O控制继电器接通闹钟实现。
2.5复位电路
复位电路采用按钮电平复位电路
三.软件设计
由于电路设计巧妙,许多功能都可以有硬件电路来完成,因此软件设计就比较简单,软件采用模块化的设计,流程图如下
主程序
置计时初值
12:
00:
00
置T0为4MS定时
开T0中断
有键按下
计数值调整
调用控制子程序
3.1初始化参数设置
设置电子钟的计时初值为12:
00:
00,启动T0进行4MS定时,且允许T0中断3.2定时器T0中断服务子程序
中断服务子程序的作用是进行时,分,秒,的计时与显示。
定时器T0用于
定时周期设为4MS,中断累计250次,即1S,对秒计数单元进行加一操作。
时间计数单元分别在2CH(S)2BH(MIN)2AH(H)内存单元中,在计数单元中采用组合BCD码计数,满60进位。
定时器T0中断服务程序流程图如下:
T0中断
重新启动T0
保护现场
1S定时到
计数值调整
调DISP子程序
调SCAN子程序
恢复现场
中断返回
3.3显示程序DISP:
DISP子程序的作用是分别将时间记数单元2CH(S)2BH(MIN)2AH(H)中的十进制时间值(组合BCD码)转化为个位和十位(分离BCD码)存放在显示缓冲区中。
显示缓冲区的地质为20H~25H,其中,20H~21H存放秒数据,22H~23H存放分数据,24H~25H存放时数据,由于每一个地址单元均为分离BCD码,用BCD七为译码器74LS47直接进行编译。
因此,不需要软件方式对BCD码进行编译。
3.4扫描子程序SCAN
SCAN的作用是把显示缓冲区的数据依次送经显示器进行,把扫描值作为24位,显示数据值作为低4位,输出到P112,以完成显示。
因为采用了3-8译码器74LS138作为扫描输出,所以用28H单元存放扫描指针,即28H中存放的是数码管的序层。
显示时,只需要去处20H~25H某一地址中的数据,并从P1口的低4位输出,同时P1口的高4位作为扫描值的输出,就能保证数码管的正常工作。
3.5控制子程序
作用是判断时间是否与设置闹钟时间相等。
如相等则开启闹钟。
3.6源程序清单
*******主程序*******
ORG000H;主程序起始地址
JMPSTART;跳至主程序
ORG0BH;T0中断子程序起始地址
JMPTIMO;跳至TO中断子程序TIM0
START:
MOVSP,#70H;设置堆栈在70H
MOV28H,#00;(28H)为扫描指针,初值为0
MOV2AH,#12H;时初值为10H
MOV2BH,#00H;分初值为00H
MOV20H,#00H;秒初值为00H
MOVTMOD,#01H;设T0为MOOD1
MOVTH0,#0F0H;计时中断为4MS
MOVTL0,#60H
MOVIE,#10000010B;T0中断使能
MOVR4,#250;中断250次
STEBTR0;启动T0
LOOP:
JBP0.0N2;秒按下?
若不是,则跳至N2J检查S2
CALLDELAY;消除抖动
MOVA,2CH;将秒值存如A
ADDA,#01H;A的内容加1
DAA;做十进制位调整
MOV20H,A;将A的值存入秒单元
CJNEA,#60H,N3;是否等于60MIN?
若不是,则跳至N3MOV2BH,#00H;若是,则清除分的值为00
N3:
JNBP0.1,$;(分)放开了?
CALLDELAY;消除抖动
N4:
JBP0.2,LOOP;时按了么?
若不是,则跳至LOOP
CALLDELAY;消除抖动
MOVA,2AH;将十的值存入A
ADDD,#01;A的内容加1
DAA;将十进位调整
MOV2AH,A;将A的值存入时单元
CJNEA,#24H,N5;是否等于20时?
若不是,则跳至N5
MOV2AH,#00;若是,则消除时的值为00
N5:
JNBP0.2,$;分放开了?
CALLDELAY;消除抖动
JMPLOOP
*******中断服务子程序********
TIM0:
MOVTH0,#0F0H;重新启动T0
MOVTL0,#60
PUSHACE;将A的值暂时存入堆栈
PUSHPSW;将PSW的值暂时存入堆栈
DJNZR4,X2;计时一秒
MOVR4,#250
CALLCLOCK;调用计时子程序CLOCK
CALLDISP;调用显示子程序
X2:
CALLSCAN;调用扫描子程序
POPPSW;从堆栈取出PSW的值
POPACE;从堆栈取出A的值
RETL
******显示器扫描子程序*******SCAN:
MOVR0,#28H;28H为扫描指针
CJNE@R0,#6,X3;扫描完6个数码管?
若不是,则调至X3
MOV@R0,#00
X3:
MOVA,@R0;扫描指针存入A
ADDA,#20H;A加20H即为现实缓冲区地址
MOVR1,A;将各地址存入R1
MOVA,@R0;扫描指针存入A
SWAPA;将A的高四位交换(P1高电平位扫描值)
ORLA,@R1;P1高四位为扫描值,低四位为显示数据值MOVP1,A;输出至P1
INC@R0;扫描指针加1
RET
*******时分秒计数值调整程序*******CLOCK:
MOVA,20H;20H为秒计数单元
ADDA,#1;秒加1
DAA;做十进制调整
MOV2CH,A;存入秒计数单元
CJNEA,#60H,X4;是否等于60秒?
若不是,则跳至X4MOV2CH,#00;若是,则清除为00
MOVA,2BH;2BH为计数单元
ADDA,#1;分加1
DAA;做十进制调整
MOV2BH,A;存入分计数单元
CJNEA,#60H,X4;是否等于60MIN若不是,则调至X4MOV2BH,#00;若是,则清除为00
MOVA,2AH;2AH为时计数单元
ADDA,#1;时加1
DAA;做十进制调整
MOV2AH,A;存入时计数单元
CJNEA,#24H,X4;是否等于24时,若不是则调至X4MOV2AH,#00;若是,则清除为00
**********向显示器缓冲区写数据*********
DISP:
MOVR1,#20H;20H为显示缓冲区的首址
MOVA,2CH;将秒计数单元的值存入A
MOVB,#10H;设B累加器的值为10H
DIVAB;A除以B,商存入A,余存入B
MOV@R1,B;将B的值存入20H
INCR1;R1增加为21H
MOV@R1,A;将A的值增加为21H
INCR1;R1增加为22H;
MOVA,2BH;将分数单元的值存入A
MOVB,#10H,将B累加器的值为10H
DIVAB;A除以B,商存入A,余存入B
MOV@R1,B;将B的值存入22H
INCR1;R1累加为23H
MOV@R1,A;将A的值存入23H
INCR1;R1的值增加为24H
MOVA2AH;将时计数单元的值存入AMOVB,#10H;将B累加器的值为10HDIVAB;A除以B,商存入A,余存入BMOV@R1,B;将B的值存入24H
INCR1;R1的值增加为25H
MOV@R1,A;加A的值存入25H
RET
DELAY:
MOVR6,#60
D1:
MOVR7,#248
DJNZR7,$
DJNZR6,D1
RET