|
发表于 2010-12-12 22:20:25
|
|阅读模式
哈哈,第一次在矿山收音机论坛发帖,欢迎大家来拍砖或者灌水啊!
在百度上看到不少求“单片机电子钟”的设计,又看了不少自认为高明的人写的程序……我承认自己是笨鸟,那些程序写的不知所云,完全不考虑优化和实时性,并且很难读懂,所以我在闲着没事的时候突发奇想的自己试着写了一下,用proteus仿真和在板子上运行试验……绘制proteus图用了5分钟,下载程序到板子上运行了2分钟——测试时间的精度。大部分的时间——50分钟——都用在程序的编写上,赌上我以前编程使用的技巧和经验,写出的程序虽然比网上所见的程序都要长,但是绝对是每个人都能轻易看懂的。
在发布我的程序之前,我先说说网上的程序存在的一些问题吧:
电子钟的核心就是如何准确的定时1s,很多人喜欢用51单片机和12MHz晶振,这没错,使用定时器的溢出中断,最大一次溢出需要的时间是50ms,所以中断程序是这样的:
void STA() interrupt 1
{
TL0=(65535-50000)%256;
TH0=(65535-50000)/256;
………………
}
这中断程序没错,在每次溢出中断时重载数值。但这样的方法是“笨”了,别忘了52单片机(现在都是52单片机)有定时器2,定时器2的特点是有重载功能,只要在主程序中将T2设置为自动重载方式,RCAP2L=(65535-50000)%256;RCAP2H=0=(65535-50000)/256,就可以一劳永逸的解决赋初值的问题,因为T2自动重载方式在发生中断时自动将RCAP2H:RCAP2L的数值复制给TH2:TL2。
在AVR单片机中的定时器比51的定时器更强悍,除了像51那样的溢出中断之外,还有比较匹配方式CTC和PWM输出方式。如果还有人在用AVR单片机做电子钟时用和51一样的方式——在中断程序中给定时器赋初值——那就要挨板子了。因为AVR定时有CTC方式,控制的定时的误差为0,只与晶振的误差有关!比如CTC比较的数值是125,当计数器数值从0开始累加,到125时就自动回到0重新开始累加并产生中断,这样就能控制任意方式精确定时了。
我用的是Atmega16单片机,11.0592MHz频率,T0使用CTC方式产生100Hz中断频率用于按键扫描,T1使用CTC方式产生1Hz的中断来作为电子钟的时钟源,所以这个电子钟在实际运行时的误差就是晶振的误差,如果晶振误差为0,那么计时的误差就是0……好不再多说了,上程序和图片。注意仿真用的是Proteus7.7,编译器使用Code Vision AVR C 1.25.5或更高版本。
补充编辑:好了,总算在楼主位上传文件了……
[ 本帖最后由 Paktu 于 2010-12-12 22:55 编辑 ] |
|