原创 转载DS1302校时

2013-12-30 09:38 1656 24 24 分类: MCU/ 嵌入式

将DS1302时钟走时更准确的方法

 

用DS1302制作电子时钟,由于32678K的晶振误差原因造成时钟走时不准确,大家使用的晶振精度都不高,每天误差都差6到10秒,如果购买高精度的晶振价格又非常高,不如用单片机的计时器编程走时更准确,可以进行误差调整,本人作了几个用DS1302时钟,由于32678K晶振的原因,每天都快6-9秒之间,原来用的方法是每天自动校一次,由于每天的误差不是整数,比如每天快7.6秒,这样每天就得自动校8秒,又造成每天慢0.4秒,每月误差又是12秒,走时还是不准确,本人改成了每差1秒校正一次的方法,原理是:比如每天快7.6秒,24*60/7.6=189,也就是189分钟快1秒,每189分钟就自动校一次时钟,这样校时理论上每年的误差最大不到6秒,本人的时钟4个月误差不到1秒,属于相当准确喽,现在提供给大家分享。

设计原理是:

由于程序的大小和原理不同,每分钟读取DS1302的次数也不同,这样先设置二个变量,一个是分钟比较变量,用于判断分钟不等相等时计数器变量加1,另一个是校时计数变量,用于校时时间计数,当计数器变量等于189时,DS1302自动修正一次,程序如下: 

代码:
变量设置
BJBL DATA 20H ;分钟比较变量,用于判断分钟不等相等时计数器加1
JSBL DATA 21H ;校时计数变量,用于校时时间计数
MOV BJBL,#00H
MOV JSBL,#00H
自动校时子程序
AUTOXS:
MOV A,MIN
CJNE A,BJBL,AS1
JMP AS2
AS1: MOV BJBL,A
MOV A,JSBL
INC A
MOV JSBL,A
AS2: MOV A,JSBL
CJNE A,#0D3H,AS5
MOV A,SEC
CJNE A,#01H,AS5 ;秒等于1时校回到0秒

MOV R1,#8EH ;写保护寄存器
MOV R0,#00H ;允许写入
LCALL WRITE ;调用写DS1302程序

MOV R1,#80H ;写秒寄存器
MOV R0,#00H ;启动振荡器工作
LCALL WRITE ;调用写DS1302程序

MOV R1,#8EH ;写保护寄存器
MOV R0,#80H ;禁止写入
LCALL WRITE ;调用写DS1302程序

MOV JSBL,#00H
AS5: RET

将此子程序在每次读取DS1302时调用

 

参考网上自动校时的程序,按照他的思路重新写了一个,目前能用了,现在正在测试中。
思路是这样的:首先参照标准时间,让时钟运行24小时,看看24小时内秒运行误差,我的是快2秒左右。按照24*60/2=720进行计算,得到结果是每720分钟快1秒,也就是只要每720分钟后,时钟再走1秒后,重新向1302秒寄存器写入00即可,就能达到每720分钟减1秒效果

 

#define CHECHPERIOD 720
#define MINUTE_ADDRESS 0x80;
#define SECOND_ADDRESS 0x82;
 
unsigned int bjminute = 0; //比较变量,用于判断分钟不相等时计数器加1
unsigned int jscount = 0; //校时计数变量,用于校时时间计数
void AutoCheckTime(void)
{
unsigned char minute = 0;
unsigned char second = 0;
 
minute = readDS1302(MINUTE_ADDRESS);
 
if(minute != bjminute)
{
bjminute = minute;
  jscount = jscount +1;
}
else 
{
if( jsbl == CHECHPERIOD)
{
second = readDS1302(SECOND_ADDRESS);
if(second == 0x01)//秒等于1时,写秒值0
{
WriteDS1302(0x00,SECOND_ADDRESS);
jscount = 0;
}
}
}

 

使用EPSON 的RS8025  就可以解决这个问题了,内部集成晶振;


几块钱就解决问题;

再不行就用GPS校时

也就100块钱多一点的价位吧。到淘宝上搜“5680A”,大把的是,这个东西是最便宜最容易买到的铷原子钟模块了,10MHz标准频率输出,呵呵,如果用来做时钟的话,你用到它报废,误差也不会到一秒钟的

文章评论0条评论)

登录后参与讨论
我要评论
0
24
关闭 站长推荐上一条 /2 下一条