本文将通过介绍一种实用的单片机电子钟的设计与制作过程,帮助初学者学习单片机的应用。
一、系统的功能要求与单片机选型
单片机电子钟要求的基本功能是计时和校时,另外还可增加闹钟、秒表、自动打铃等功能。本系统选用与MCS-51系列单片机完全兼容的AT89C51低功耗单片机。
二、系统的软、硬件功能划分
电子钟的功能要求比较简单,因此主要考虑最大限度地节约系统的硬件成本,所有能用软件实现的功能都用软件完成,如按键的去抖动采用软件延时的方法,显示部分采用动态显示等。这样,硬件部分的设计可以采用单片机最小系统,所谓最小系统是仅具有程序存储器和时钟及复位电路的单片机系统。
三、硬件设计
基本电子钟的硬件原理图见图1。

1.单片机及程序存储器
AT89C51内部有4KB的FLASH存储器,本电子钟的程序不会超过4KB,因此无需扩展外部的程序存储器。
晶振采用6MHz,两个20pF的电容是微调电容。
上电复位电路中,电阻和电容的选择是要保证电容充电时RST引脚上的高电平的维持时间大于2个机器周期,对应6MHz晶振,机器周期为2μs,也即充电时RST引脚上高电平维持时间要求为4μs以上。该复位电路复位引脚上的复位信号维持时间由RC的值确定,取电阻R3=1k,电容为20μF/16V,这样完全可满足复位信号的要求。
2.键盘
用于校正时间,选用普通的按键,有功能键、增1键、减1键、确认键,共4个键。
按键通过P3口的低四位接入,当有键按下时输入端为低电平,无键按下时为高电平,单片机的输入电流要求较小,取电阻R4=10k。
3.显示器
主要用于显示时间,选用LED显示器,共6位,分别显示时、分、秒,采用动态显示方式,通过软件进行动态扫描刷新。
本系统LED的段控接P0口,位控接P2口的低五位。P0口作段控口输出时,由于其内部是漏极开路的,因此要外接1k左右的上拉电阻,取R1=1k。而P2口由于其内部已有上拉电阻,无需外接。为了提高段控口和位控口的驱动能力, P0口和P2口分别通过ULN2003反相器(ULN2003是七反相器,电源引脚是⑨,接地引脚是⑧)再与LED相连。
LED是共阴的,要点亮某段,必须在位控端加低电平,段控端加高电平,一般有5~30mA的电流即可点亮。因此可计算段控端的限流电阻为:R2=(5-1.5-0.3)V/(5~30)mA,取R2=200Ω。式中的0.3V和1.5V,是分别考虑位控端输出的低电平和发光二极管的每段压降。
4.电源部分
利用典型的三端稳压器7805电路,产生+5V单电源,给单片机电子钟系统供电。
变压器选220V/9V,3VA。整流二极管VD1~VD4及7805的保护管VD5选1N4001,电容的容量见图1,耐压为16V。
根据硬件连接图,布置元器件,然后进行焊接。
四、软件设计
硬件部分制作完成之后,关键是程序的编写。程序主要包括以下几部分:主程序、显示子程序、中断服务程序、按键判断与处理子程序。
1.主程序(MAIN)
主程序首先是初始化部分,主要是计时单元清零、中断初始化、堆栈指针初始化、启动定时器工作,然后是调用显示子程序,接着是判断有无按键。无按键则回到调用显示子程序处;有按键,则执行按键处理子程序,执行完后回到调用显示子程序处,重复循环。主程序流程见图2。

编写主程序应特别注意两点:(1)调用子程序的逻辑顺序。(2)主程序的起始存储地址是0000H单元,但由于本系统用了定时器T0的中断,中断服务程序入口地址为000BH,因此从0000H单元起存放一条短跳转指令AJMP MAIN,使真正的主程序从0300H单元开始存放。
2.中断服务程序(TIME)
本电子钟的计时是用单片机内部的定时/计数器T0定时100ms,即0.1s,10次中断即为1秒,60秒为1分,60分为1小时,24小时为1天,如此循环,从而实现计时功能。根据晶振频率可知T0的计时初值为3CB0H,考虑到中断响应时间,可在3CB0H~3CB7H之间调整计时初值。
编写中断服务程序关键要注意:(1)现场保护,在本系统中是累加器A和程序状态字PSW值的保护。(2)计时处理时采用的是十进制,因此时、分、秒单元加1后要进行十进制调整,即要执行DA A指令,还要注意的是时计到24就回零,分和秒是计到60就回零。(3)定时器T0计时初值的重置,考虑到中断响应的时间,重置时送3CB4H,以减小计时误差。(4)中断返回前的现场恢复。
3.显示子程序(DISP)
本显示采用的是动态显示,LED是共阴的,但注意段控和位控都经过反相器,因此显示的字形代码是共阴代码取反即为共阳的显示代码,位控信号输出时是高电平有效。在校时时,采用的是点亮小数点作位调节标志,哪位小数点亮表示调整的是该位的值。
显示子程序的第一部分是拆字,显示缓冲区是2FH~2AH;第二部分是查字形代码,输出段控和位控信号,由于采用的是动态显示,所以每输出一位的段控和位控信号要延时一定的时间,使LED显示器显示的字符是稳定的。
4.按键判断(KEY)与按键处理程序(ANKEY)
按键判断子程序(KEY)在编写时应注意按键的去抖动,该系统采用的是延时去抖动的方法,延时是通过调用显示子程序来实现的,每个键按下后要等待释放后再返回。
按键处理子程序(ANKEY)中的按键是校时的,所以进入按键处理子程序后就关闭定时中断,对于功能键注意设置显示标志(将显示缓冲区某单元的D4位设为1,这样查显示代码时就查小数点亮的代码表)。在使用相对跳转指令时,只能在
±127B范围内转移,超出范围就要先转到某个地方再用AJMP指令进行跳转。
编程时还需要考虑出现程序跑飞的现象,这时可在程序存储器空的单元中存放若干条NOP指令及在适当的地方存放LJMP 0000H,或者如本系统采用LJMP NEXT指令。这样程序不管跑飞到什么地方都能回到主程序中继续执行,不至于出现死机现象,这就是常说的看门狗。
五、软硬件的统调
通常在统调前应该先分别进行硬件和软件的调试。
1.硬件调试
在未写入程序前,硬件的调试主要是检查电路板有没有虚焊、短路,连线是否正常,尤其要注意单片机和反相器的电源引脚和接地引脚是否正确,电源电路是否正常输出,有关点的电压是否正常。
在确保正确的前提下,可以通过一个几百欧的电阻强制对段控口P0的某位接地,观察相应的LED段是否点亮,如有故障可逐步查找。
2.软件调试
程序调试是先调试各个子程序,然后再和主程序一起联调。利用仿真器,通过设置断点、单步执行等方法进行软件的分段调试。不具备条件的可直接进行软硬件的统调。
3.软硬件的统调
正常情况下系统可以完成如下操作:
(1)系统上电后,会自动进入计时状态,显示为000000。
(2)校时操作:先按“功能键”选择调节的对象(哪一位小数点亮表示调整的是该位的值),再用“增1”和“减1”键进行具体的调整,最后按“确认键”结束校时操作。
如果有问题可以借助于仿真器进行软硬件的统调,通常这种统调比较简单。如没有仿真器可直接将程序写入存储器,进行实际调试,这时可能要反复擦写多次。
本文所提供的程序是调试通过的,并且进行过长期运行。读者可适当改变一些接线,如改变段控和位控口、按键的输入口等,这时程序需作相应的修改。还可将独立键盘改成矩阵式键盘,以节约更多的输入口。
六、系统功能的扩充
前面所介绍的是最基本的时钟,如要增加秒表和打铃等功能,可考虑增加两个键,一个是用于秒表的计时开始与停止,另一个键用于秒表的回零,可接在P3口的P3.4和P3.5两位。这时按键处理程序就要根据情况决定是否关中断,因为秒表需要用0.1s的定时信号,并且这时时钟需要继续走时,秒表工作时,显示器用于显示秒表所计时间。
打铃功能的增加,可以加一个输出信号,并由P1口的某一位输出,还需要将打铃的时间表存入程序存储器。这时在中断服务程序中,每当分单元加1时就要与时间表进行比较,判断是不是要进行打铃输出,从而设置打铃输出的标志位,在主程序中增加一段对打铃输出标志的判断程序,有打铃输出标志,则P1.0输出低电平使铃响,否则输出高电平铃不响,并且还要控制打铃输出的时间,打铃输出可用发光二极管模拟指示,其接线见图3,其中R取200Ω。

对本文有兴趣读者可在本期配刊光盘的“本期程序”文件夹中找到单片机电子钟的全部源程序。
(丁辉 姚庆文)