第89节:用单片机内部定时器做一个时钟
开场白:
很多网友建议,为了方便初学者学习编程思路,我应该用单片机定时器做一个时钟程序供大家参考学习。其实我前面第48节就已经用ds1302做了一个可以显示和更高时间的时钟,这一节只要在第48节的源代码基础上,大的框架不用动,只需要把ds1302产生的时间改成用定时中断产生的时间就可以了,改动的地方非常小。但是为了让时间的精度更高,最后必须跟标准时间进行校验,来修正系统中一秒钟需要多个定时中断的误差,这个误差决定了系统的时间精度,其实这个校验方法我在前面很多章节上跟大家介绍过了:
第一步:在程序代码上先写入1秒钟大概需要200个定时中断。
第二步:把程序烧录进单片机后,上电开始测试,手上同步打开手机里的秒表,当手机的标准时间跑了780秒(这个标准时间跑得越长校验精度越高),而此时单片机仅仅跑了1632秒。那么最终得出1秒钟需要的定时中断次数是:const_time_1s=(200*1632)/780=418。
第三步:如果发现时钟还是不太准,可以继续返回第一步根据最新1秒钟的时间是418次,多校验几次,来不断调整const_time_1s的数值,直到找到相对精度的时间为止。
本系统仅供学习,精度不可能做得很好,因为影响时间精度的因素还有定时中断的重装值,定时中断里面的代码尽量少,以及晶振等不好控制的因素。所以鸿哥一直不推荐在实际项目中用单片机的内部定时器做实时时钟,因为精度有限。真正想要准确的时钟时间,还是强烈建议大家用外部专用的时钟芯片或者用CPLD/FPGA来做。
具体内容,请看源代码讲解。
(1硬件平台.
基于朱兆祺51单片机学习板。
(2)实现功能:
本程序有2两个窗口。
第1个窗口显示日期。显示格式“年-月-日”。注意中间有“-”分开。
第2个窗口显示时间。显示格式“时 分 秒”。注意中间没“-”,只有空格分开。
系统上电后,默认显示第2个窗口,实时显示动态的“时 分 秒”时间。此时按下S13按键不松手就会切换到显示日期的第1个窗口。松手后自动切换回第2个显示动态时间的窗口。
需要更改时间的时候,长按S9按键不松手超过3秒后,系统将进入修改时间的状态,切换到第1个日期窗口,并且显示“年”的两位数码管会闪烁,此时可以按S1或者S5加减按键修改年的参数,修改完年后,继续短按S9按键,会切换到“月”的参数闪烁状态,只要依次不断按下S9按键,就会依次切换年,月,日,时,分,秒的参数闪烁状态,最后修改完秒的参数后,系统会自动把我们修改设置的日期时间一次性更改到定时中断函数内部的时间变量,达到修改日期时间的目的。
S13是电平变化按键,用来切换窗口的,专门用来查看当前日期。按下S13按键时显示日期窗口,松手后返回到显示实时时间的窗口。
[size=10.5000pt](3)源代码讲解如下:
- #include "REG52.H"
- #define const_dpy_time_half200//数码管闪烁时间的半值
- #define const_dpy_time_all 400//数码管闪烁时间的全值 一定要比const_dpy_time_half 大
- #define const_voice_short40 //蜂鸣器短叫的持续时间
- #define const_key_time120 //按键去抖动延时的时间
- #define const_key_time220 //按键去抖动延时的时间
- #define const_key_time320 //按键去抖动延时的时间
- #define const_key_time420 //按键去抖动延时的时间
- #define const_key_time171200//长按超过3秒的时间
- /* 注释一:
- * const_timer_1s这个是产生多少次定时中断才算1秒钟的标准。这个标准决定了时钟的精度。这个标准最后是需要校验的。
- * 那么是如何检验的呢?根据我们前面介绍的校验时间方法:
- * 步骤:
- * 第一步:在程序代码上先写入1秒钟大概需要200个定时中断。
- * 第二步:把程序烧录进单片机后,上电开始测试,手上同步打开手机里的秒表,当手机的标准时间跑了780秒(这个标准时间跑得越长校验精度越高),
- * 而此时单片机仅仅跑了1632秒。那么最终得出1秒钟需要的定时中断次数是:const_time_1s=(200*1632)/780=418。
- * 第三步:如果发现时钟还是不太准,可以继续返回第一步根据最新1秒钟的时间是418次,多校验几次。本系统仅供学习,精度不可能做得很好,因为
- * 影响时间精度的因素还有定时中断的重装值,定时中断里面的代码尽量少,以及晶振等不好控制的因素。所以鸿哥一直不推荐在实际项目中
- * 用单片机的内部定时器做实时时钟,因为精度有限。真正想要准确的时钟时间,还是强烈建议大家用外部专用的时钟芯片或者用CPLD/FPGA来做。
- */
- //#define const_timer_1s200 //第一次假设大概1秒
单片机内部定时器时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)