文号
t39896
阅读
5028
回复
11
收藏
8
在单片机实验板上搞了个电子钟
2012/01/23
IP:福建
雕虫小技,新手,求指教……
求更准确的时间算法……
我用的是内部定时器……
单片机型号stc89c52
电路图 QQ截图20120123172746.jpg QQ截图20120123172808.jpg QQ截图20120123172816.jpg

20120123310.jpg
一张效果图
程序

#include <REG52.H>
#define uc unsigned char
void ff();
void ff2();
void ff3();
void ff4();
sbit key30=P3^0;
sbit key31=P3^1;
sbit key32=P3^2;
sbit key33=P3^3;
uc num;
uc code table[]={
0xc0,0xf9,0xa4,
0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90};
uc se,mi,mm,mmm,ho,hho;
void main()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
num=0;
P0=0x0;
se=0;
mi=0;
mm=0;
mmm=0;
ho=0;
hho=0;
while(1)
{
ff();
}
}

void ff()
{
if(key30==0)
{
EA=0;
ff3();
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
num=0;
}
if(num>=20)
{
num=0;
se=se+1;
if(se==10)
{
se=0;
mi=mi+1;
}
}
if(mi==6)
{
mm=mm+1;
mi=0;
se=0;
}
if(mm==10)
{
mm=0;
mmm++;
}
if(mmm==6)
{
mmm=0;
ho=ho+1;
}
if(ho==10)
{
ho=0;
hho=hho+1;
}
if(hho==2)
{
if(ho==4)
{
ho=0;
hho=0;
}
}
P1=0x1;
P0=table[se];
ff2();
P1=0x2;
P0=table[mi];
ff2();
P1=0x8;
P0=table[mm];
ff2();
P1=0x10;
P0=table[mmm];
ff2();
P1=0x40;
P0=table[ho];
ff2();
P1=0x80;
P0=table[hho];  /*6176*/
ff2();
ff();
}
void ff2()
{
uc i,j;
for(i=6;i>0;i--)
for(j=100;j>0;j--);
}


void ff3()
{
if(key31==0)
{
se=se+1;
ff4();
if(se==10)
{
se=0;
mi++;
if(mi==6)
{
se=0;
mi=0;
}
}
}
if(key32==0)
{
mm=mm+1;
ff4();
if(mm==10)
{
mm=0;
mmm=mmm+1;
if(mmm==6)
{
mi=0;
se=0;
}
}
}
if(key33==0)
{
ff4();
ho=ho+1;
if(ho==10)
{
ho=0;
hho=hho+1;
}
}
if(hho>2)
{
hho=0;
if(ho>=4)
{
ho=0;
}
}
P1=0x1;
P0=table[se];
ff2();
P1=0x2;
P0=table[mi];
ff2();
P1=0x8;
P0=table[mm];
ff2();
P1=0x10;
P0=table[mmm];
ff2();
P1=0x40;
P0=table[ho];
ff2();
P1=0x80;
P0=table[hho];  /*6176*/
ff2();
}

void ff4()
{
uc l,k,n;
for(l=100;l>0;l--)
   for(k=100;k>0;k--)
       for(n=10;n>0;n--);
   }
void T1_time() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
}
#include <REG52.H>
#define uc unsigned char
void ff();
void ff2();
void ff3();
void ff4();
sbit key30=P3^0;
sbit key31=P3^1;
sbit key32=P3^2;
sbit key33=P3^3;
uc num;
uc code table[]={
0xc0,0xf9,0xa4,
0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90};
uc se,mi,mm,mmm,ho,hho;
void main()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
num=0;
P0=0x0;
se=0;
mi=0;
mm=0;
mmm=0;
ho=0;
hho=0;
while(1)
{
ff();
}
}

void ff()
{
if(key30==0)
{
EA=0;
ff3();
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
num=0;
}
if(num>=20)
{
num=0;
se=se+1;
if(se==10)
{
se=0;
mi=mi+1;
}
}
if(mi==6)
{
mm=mm+1;
mi=0;
se=0;
}
if(mm==10)
{
mm=0;
mmm++;
}
if(mmm==6)
{
mmm=0;
ho=ho+1;
}
if(ho==10)
{
ho=0;
hho=hho+1;
}
if(hho==2)
{
if(ho==4)
{
ho=0;
hho=0;
}
}
P1=0x1;
P0=table[se];
ff2();
P1=0x2;
P0=table[mi];
ff2();
P1=0x8;
P0=table[mm];
ff2();
P1=0x10;
P0=table[mmm];
ff2();
P1=0x40;
P0=table[ho];
ff2();
P1=0x80;
P0=table[hho];  /*6176*/
ff2();
ff();
}
void ff2()
{
uc i,j;
for(i=6;i>0;i--)
for(j=100;j>0;j--);
}


void ff3()
{
if(key31==0)
{
se=se+1;
ff4();
if(se==10)
{
se=0;
mi++;
if(mi==6)
{
se=0;
mi=0;
}
}
}
if(key32==0)
{
mm=mm+1;
ff4();
if(mm==10)
{
mm=0;
mmm=mmm+1;
if(mmm==6)
{
mi=0;
se=0;
}
}
}
if(key33==0)
{
ff4();
ho=ho+1;
if(ho==10)
{
ho=0;
hho=hho+1;
}
}
if(hho>2)
{
hho=0;
if(ho>=4)
{
ho=0;
}
}
P1=0x1;
P0=table[se];
ff2();
P1=0x2;
P0=table[mi];
ff2();
P1=0x8;
P0=table[mm];
ff2();
P1=0x10;
P0=table[mmm];
ff2();
P1=0x40;
P0=table[ho];
ff2();
P1=0x80;
P0=table[hho];  /*6176*/
ff2();
}

void ff4()
{
uc l,k,n;
for(l=100;l>0;l--)
   for(k=100;k>0;k--)
       for(n=10;n>0;n--);
   }
void T1_time() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
}





附件是视频……
还有hex
20120123063.mp4  点击下载

attachment icon zd.rar 0.58KB RAR 28次下载
11
14年11个月前IP:未同步
357363
1楼
1、定时器必需使用自动重载方式工作,你在中断中去设定记数值是没办法精确的。
2、程序可以做到没有误差,硬件的误差更重要,好的晶振和低温度系数的电容是关键。
3、内部把运行周期做成100ms或10ms,然后做一个软件修正,如100000秒后加/减一个计数单位。
4、找一个高精度的时间基准进行校准,推荐用GPS的同步脉冲输出,一般的GPS模块都有,1次/秒。
5、如果还要更精确就把温度误差修正也加上。

希望你能做一个高精度的时钟。
引用
评论
cqb98作者
14年11个月前IP:未同步
357370
2楼
谢谢ls的指导,目前我的实力就这样……寒假开始,断断续续学了些[s:225]    也只会这个……
引用
评论
14年11个月前IP:未同步
357375
3楼
找一个DS1302芯片,这个IC精度很高,配上备用电池的话可以调电不丢时间
我的一个小玩意的源码:
attachment icon LCD.zip 113.04KB ZIP 30次下载
这个使用了1602显示屏+DS1302时钟芯片+DS18B20温度传感器,里面有DS1302的H文件
引用
评论
14年11个月前IP:未同步
357383
4楼
谢谢ls的指导,目前我的实力就这样,很好继续学习。
引用
评论
14年11个月前IP:未同步
357412
5楼
这个实验板实物,电路图似曾相识啊,哪买的?看过个教学视频,貌似就用这个实验板
引用
评论
cqb98作者
14年11个月前IP:未同步
357444
6楼
引用第5楼jxs于2012-01-23 21:19发表的 :
这个实验板实物,电路图似曾相识啊,哪买的?看过个教学视频,貌似就用这个实验板  

这是YZ200的
话说这个电路可以不用晶振么?
话说ds1302怎么用啊,实验板上有……不会用
我发现每40到50分钟就快1 秒。我便每50分钟就把秒位减 1.这样可靠么?
引用
评论
14年11个月前IP:未同步
359009
7楼
你可以使用 DS12C887  芯片来做  这个芯片可以精确到毫秒级别,内部自带锂电池,即使外部断电 内部电池理论上可以坚持9年  但是 一般坚持7--8年左右 一个也就20 左右  可能还要贵反正不会超过40
引用
评论
14年11个月前IP:未同步
359010
8楼
回 6楼(cqb98) 的帖子
你可以去看一看 郭天祥的视频 很好的里面有 一共十多集,国内公认的初级入门视频
引用
评论
14年10个月前IP:未同步
375565
9楼
我用过DS1302、DS12C887、和DS3231,个人感觉DS1302误差太大,DS12C887体积太大,引脚还那么多,DS3231还不错,精度很高,自带温度补偿的晶振,串行的接口,封装也不大。
引用
评论
14年7个月前IP:未同步
398395
10楼
看看,围观下。。。。
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的