数字钟报告.docx
《数字钟报告.docx》由会员分享,可在线阅读,更多相关《数字钟报告.docx(14页珍藏版)》请在冰豆网上搜索。
![数字钟报告.docx](https://file1.bdocx.com/fileroot1/2023-1/4/8ee507f3-fb07-486f-b3dc-288782539ced/8ee507f3-fb07-486f-b3dc-288782539ced1.gif)
数字钟报告
数字钟报告
一电子钟方案
方案1:
单片机定时可通过51系列的单片机两个内部的16位定时器/计数器实现时钟计数。
这两个计数器都是由8位的特殊RAM单元组成的,最大计数量程是65536。
定时器是单片机的内部晶振经过12分频后获得的一个脉冲源,并以它作为计数器信号的实现。
方案2:
专用时钟芯片DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信实时时钟/日历电路.提供秒分时日日期.月年的信息,每月的天数和闰年的天数可自动调整时钟操作可通过AM/PM指示决定采用24或12小时格式.DS1302与单片机之间能简单地采用同步串行的方式进行通信.双电源管脚用于主电源和备份电源供应Vcc1,为可编程涓流充电电源附加七个字节存储器.
方案选择:
由于直接用单片机内部定时器作为时钟计数比较不准确,同
编制日历软件复杂,不能提供准确的时间计量,而DS1302能够提供准确的年、月、日等信息,但没有此芯片,因此只能用单片机内部的定时器。
2.单片机选型:
AT89C52ATMEL公司生产的低电压,高性能CMOS8位单片机.片内含8KbyTES的可反复擦写的只读程序存储器(PEROM)和256byTES的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和FLASH由存储单元,与Mcs-51产品指令和引脚完全兼容。
二系统硬件设计
(1)显示电路:
器材限制,因此采用数码管显示。
1.数码管显示
2.液晶屏显示
(2)显示闹钟:
时钟显闹时,所有发光二极管发亮。
(3)复位电路:
在上电或复位过程中,控制CPU的复位状态:
这段时间内让CPU
保持复位状态,而不是一上电或刚复位完毕就工作,防止CPU发出错误的指令、
执行错误操作,也可以提高电磁兼容性能。
无论用户使用哪种类型的单片机,总
要涉及到单片机复位电路的设计。
而单片机复位电路设计的好坏,直接影响到整
个系统工作的可靠性。
方式一,手动按钮复位
方式二,上电复位
特例:
积分型上电复位
(4)振荡电路:
(5)键盘:
方式1.独立键盘
方式2.矩形键盘:
(6)总电路图:
方案一:
程序:
#include//包含头文件
#defineuintunsignedint//宏定义
#defineucharunsignedchar//宏定义
sbitP20=P2^0;//定义位变量
sbitP21=P2^1;
sbitP22=P2^2;
sbitP23=P2^3;
sbitP24=P2^4;
sbitP25=P2^5;
ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//数码管显视代码
uchars,f,m,s1,s2,f1,f2,aa,bb,cc,ns,nf,n1,n2,n3,n4;//定义全局变量
voiddelay(uintz)//延时函数
{uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddisplay(uchara,ucharb,ucharc,uchard);//声明显示函数
uchartiaoshi(ucharbb);//声明调时子函数
uchartiaofen(ucharcc);//声明调分子函数
voidmain()
{s=0;
f=0;
m=57;
ns=10;
nf=10;
TMOD=0x01;//设置定时器0为工作方式1
TH0=(65536-50000)/256;//赋予高四位初值
TL0=(65536-50000)%256;//赋予低四位初值
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
while
(1)
{if(aa==12)
{aa=0;
m++;
if(m==60)
{m=0;
f++;
if(f==60)
{f=0;
s++;
if(s==24)
{s=0;}
}
}
}
if(P20==0)//进入调时程序
{delay(5);
if(P20==0)
{s=tiaoshi(s);
f=tiaofen(f);}
}
if(P25==0)//进入调闹钟程序
{delay(5);
if(P25==0)
{while(P25!
=1)
{ns=tiaoshi(ns);
nf=tiaofen(nf);
n1=ns/10;
n2=ns%10;
n3=nf/10;
n4=nf%10;
display(n1,n2,n3,n4);
}
}
}
if(s==ns&&f==nf)
{P1=0x00;}//到闹钟指定时间时所有发光二极管发亮
elseP1=0xff;
s1=s/10;
s2=s%10;
f1=f/10;
f2=f%10;
display(s1,s2,f1,f2);
}
}
voidtime()interrupt1//中断函数
{TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
voiddisplay(uchara,ucharb,ucharc,uchard)//显示函数
{P0=table[a];P3=0x01;delay(5);P0=0xff;
P0=table[b+10];P3=0x02;delay(5);P0=0xff;
P0=table[c];P3=0x04;delay(5);P0=0xff;
P0=table[d];P3=0x08;delay(5);P0=0xff;
}
uchartiaoshi(ucharbb)//调时函数
{if(P21==0)
{delay(5);
if(P21==0)
{if(P23==0)
{delay(70);
if(P23==0)
{bb++;
if(bb==24)
{bb=0;}
}
}
if(P24==0)
{delay(70);
if(P24==0)
{bb--;
if(bb==-1)
{bb=23;}
}
}
}
}returnbb;
}
uchartiaofen(ucharcc)//调分函数
{if(P22==0)
{delay(5);
if(P22==0)
{if(P23==0)
{delay(70);
if(P23==0)
{cc++;
if(cc==60)
{cc=0;}
}
}
if(P24==0)
{delay(70);
if(P24==0)
{cc--;
if(cc==-1)
{cc=59;}
}}}}
returncc;
}
方案二
#include //包含头文件
#include //包含头文件
#defineucharunsignedchar //数据类型定义
ucharn=31; //定义月份天数变量并初始化
ucharms=0; //定义毫秒变量并初始化
ucharh1=0,m1=0,s1=0; //定义计时时、分、秒变量并初始化
ucharh2=0,m2=1,s2=1; //定义定时时、分、秒变量并初始化
ucharyear=7,month=9,day=8; //定义年、月、日变量并初始化
ucharwday=6; //定义星期变量并初始化
uchar*h=&h1,*m=&m1,*s=&s1;//定义显视位变量并初始化
uchar*p; //定义调节指针
uchark1=0,k2=0,k3=0,k4=0,k5=0; //定义控制变量并初始化
ucharcounter=0; //定义铃声节拍变量并初始化
ucharcount=0; //定义铃声音符变量并初始化
sbitsound=P1^0; //定义铃声输出位
uchara[8]={1,2,3,4,5,6,7}; //定义显视输出位数组并初始化
ucharcodett[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x40,0x00}; //数码管显视代码
ucharcodearray[]={0x18,0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,
0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,
0x1C,0x20,0x20,0x20,0x1C,0x20,0x18,0x20,
0x20,0x80,0xFF,0x00,0x20,0x30,0x1C,0x10,
0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,
0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0xff,
}; //array[i]=0x00代表歌曲演唱完毕
//array[i]=0xff代表是休止符
ucharleap(ucharyear) //判断是否闰年并返回二月份的天数
{ year+=2000; //闰年返回29,平年返回28
if(year%4==0)
{if(year%100==0)
{if(year%400==0)
return29;
elsereturn28;}
elsereturn29;}
elsereturn28;
}
ucharmon(ucharmonth) //计算并返回每个月的天数
{switch(month)
{case1:
case3:
case5:
case7:
case8:
case10:
case12:
return31;break; //1,3,5,7,8,10,12月每月31天
case4:
case6:
case9:
case11:
return30;break; //4,6,9,11月每月30天
case2:
returnleap(year);break;//返回二月份的天数
default:
break;
}
}
voidmusic(void) //铃声音乐功 能:
音乐节拍控制
{ counter++; //节拍次数计数
if(counter>=array[count+1]) //节拍次数判断
{count+=2; //音符变换
counter=0; //清0节拍数
if(count>=192) //判断是否唱完一曲
count=0; //返回第一个音符
}
}
voidtimer1(void)interrupt1using1 //音调设置功 能:
音乐频率设置
{sound=~sound; //铃声输出
TH0=(0xffff-30*array[count])>>8; //音频设置
TL0=(0xffff-30*array[count])&0xff;
}
voidtimer3(void)interrupt3using3 //计时中断功 能:
中断计时
{TH1=0xd8; //计数器初值重载
TL1=0xef; //定义单位节拍的延时大小为10ms
if(k5)music(); //调用闹铃音乐lns
elseTR0=0; //达到所设闹铃时间长度关铃声
if(++ms==100) //计时一秒钟
{ms=0;
if(++s1==60) //计时一分钟
{s1=0;
if(++m1==60) //计时一小时
{m1=0;
if(++h1==24) //计时一天
n=mon(month); //取每月的天数
if(++day>n) //计时一个月
{day=1;
if(++month>12) //计时一年
{month=1;
year++;
}
}
if(++wday>6) //星期计数
wday=0;
}
}
k5--; //闹铃时间长度倒记时
if(h1==h2&&m1==m2) //判断是否到定时时刻
{TR0=1; //开铃声中断lns
k5=s2; //设置闹铃时间长度
}}
}
}
voidd3(void) //显示输出
{ucharsel=0x80,i; //定义sel为位选通变量并初使化
if(k2) //判断是否处于调时状态
{if(k2==4)a[0]=a[1]=a[4]=a[6]=a[7]=10;//星期显示设置
if(k1&&(k3--==0))k3=255; //设置位调节闪烁初值
}
for(i=0;i<=8;i++) //循环显示八个数码管
{ P2=0xff; //清屏
P0=tt[a[i]]; //输出显示数值
if(k1&&(k3>200)) //判断是否闪烁
if (k1==1&&(i==6||i==7))P2=0xff; //时位闪烁
elseif(k1==2&&(i==3||i==4))P2=0xff;//分位闪烁
elseif(k1==3&&(i==0||i==1))P2=0xff;//秒位闪烁
elseP2=~sel; //非闪烁状态
elseP2=~sel; //非闪烁状态
sel=sel>>1; //显示位移位
}
}
voidd2(void)//功 能:
循环调用
{while
(1){a[0]=*s%10; //给显示数组赋值
a[1]=*s/10;
a[2]=10;
a[3]=*m%10;
a[4]=*m/10;
a[5]=10;
a[6]=*h%10;
a[7]=*h/10;
d3(); } //调用显示输出函数
}
voidd1(void) //功 能:
中断设置
{TMOD=0x11;
TH1=0xff;TH0=0xff;
TL1=0xff;TL0=0xff;
IE=0x8f;
TR1=1; IT0=1; IT1=1;
IP=0x02;
}
voidmain()//功 能:
程序入口,调用功能子函数
{ d1(); //调用中断位设置函数
d2(); }
voidd5(void) //显示菜单调节函数
{switch(k2)
{case1:
{h=&h1;m=&m1; s=&s1;}break; //菜单1:
显示时钟时间
case2:
{h=&h2;m=&m2; s=&s2;}break; //菜单2:
显示定时时刻
case3:
{h=&year;m=&month;s=&day;}break;//菜单3:
显示日历年月日
case4:
{h=&wday;m=&wday;s=&wday;}break;//菜单4:
显示星期0--6
default:
{k2=0;h=&h1;m=&m1;s=&s1;}break; //复位显示
}
}
voidd7(void) //调节限制函数
{if(k2==1||k2==2) //计时与定时限制
if(k1==1&&*p>=24)*p=0; //小时限制
elseif(*p>=60)*p=0;