电子万年历设计报告Word格式文档下载.docx
- 文档编号:20070711
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:21
- 大小:143.13KB
电子万年历设计报告Word格式文档下载.docx
《电子万年历设计报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《电子万年历设计报告Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
硬件组成简单,主要是单片机的数码管显示电路,晶振电路和按键电路。
可以在程序中预先设置每一分钟的某一段时间用来显示时、分、秒和星期信息,另一段时间显示年、月、日和星期信息。
可以看到时、分、秒和年、月、日交替显示。
同时利用按键可以切换时间的显示。
2.基本原理与论证
2.1电路工作原理
为了实现电子万年历的功能,首先要使时间可以变化,每过一秒单片机的时间也要加一秒,因此我们采用了定时器来产生时间。
而12M晶振下AT89C51单片机的定时器采用工作方式1定时的最大定时时间为65.535ms,为了实现时间秒加一,我们设定定时器每10ms溢出一次,计算出定时器的初值是TH0=0D8H,TL0=0F0H。
用一个变量来统计定时器的溢出次数,每当定时器溢出100次,我们就让秒加1,这样我们就可以得到准确的时间秒。
秒加到60后,让秒清零,分加1;
判断分加到60以后,分清零,时加1;
判断时加到24后,时清零,日期和星期加1;
判断日期到了31后,日期置1,月加1;
判断月加到13后,月置1,年加1;
判断年加到100时,年清零;
判断星期加到8后,星期置1。
这样时间的正确变化就实现了。
得到时间后,就要考虑怎么来显示了。
我们采用数码管的动态扫描来显示时间。
在两个4位共阳数码管上,一次只能显示时、分、秒、和星期信息。
时和分,分和秒之间用小数点来区分。
秒和星期之间用一横来区分。
同理,显示年、月、日、星期时年和月,月和日之间用小数点来区分,日和星期之间用一横来区分。
那什么时候让数码管显示时分秒星期,什么时候显示年月日星期呢?
我们可以在程序中设定。
比如我们可以设定每分钟的40~44秒的时候显示年月日,其余时间显示时分秒。
让数码管的动态扫描每次都扫描32H~39H单元里面的内容,而在40~44秒时我们往32H~39H里面送时分秒星期的值,在其余时间我们往32H~39H送年月日星期的值。
这样就实现了万年历的显示问题。
实现了时间的产生和显示问题后,还有一个按键功能的实现问题。
时间日期的显示调整设定了4个按键。
按键1用来暂停时间,这个很简单,只要关闭中断总开关,时间就不能加了,实现了暂停时间的功能。
按键2则用来选择需要显示的时间是日期(年、月、日)信息。
由于前面显示时间中就考虑到了时间的切换,我们只要让按键按下后进入往32H~39H送年月日星期的程序就可以了。
按键3实现恢复时间秒加1,只要再次打开终端就可以了。
按键4功能为单片机的自身的复位。
2.2复位电路
当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮内部的程序自动从头开始执行。
复位电路由电容串联电阻构成,由"
电容电压不能突变"
的性质可以知道,当系统一上电,RST脚将会出现高电平,并且,这个高电平持续的时间由电路的RC值来决定。
当RST脚的高电平持续两个机器周期以上就将复位,所以,适当组合RC的取值就可以保证可靠的复位。
这里我们取R4=2K和C3=10uf,R5=10K
2.3晶振电路
单片机最小系统起振电容C2、C3一般采用15~33pF,并且电容离晶振越近越好,晶振离单片机越近越好。
2.4上拉电阻
P0口为开漏输出,作为输出口时需加上拉电阻,接数码管时,阻值一般为1K。
2.5流程图
按键子程序:
显示子程序如下:
主程序:
2.6C语言程序
//本程序是通过定时器0产生1S准确时间的电子万年历
//通过8位数码管交替显示:
年\月\日\星期和时\分\秒\星期
//并在修改时间时,相应位数可以闪烁
//有三个按键;
按键1:
停止按键;
//按键2:
确定修改哪位数据,并在按下5次后恢复时钟
//按键3:
修改对应位的数据
#include<
reg51.h>
unsignedcharTable[11]=
{0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
//段码
vart_init();
//函数申明
Updata_LED1();
Updata_LED2();
Delay();
Delay1();
Xiugai();
Xiugaishu();
sbitled0=P2^0;
//定义P2各口
sbitled1=P2^1;
sbitled2=P2^2;
sbitled3=P2^3;
sbitled4=P2^4;
sbitled5=P2^5;
sbitled6=P2^6;
sbitled7=P2^7;
sbitstop=P1^0;
//定义P10--P12口
sbitwei=P1^1;
sbitjia=P1^2;
unsignedintmiao=32;
//秒
unsignedintfen=18;
//分
unsignedintshi=8;
//时
unsignedintriqi=21;
//日
unsignedintyue=2;
//月
unsignedintnian=12;
//年
unsignedintxingqi=2;
//星期
bitqufen=0;
//区分显示年\月\日\星期或时\分\秒\星期
bitzhanting=0;
//保持按键1按下后允许执行的程序段
intweishu=0;
//判断此时修改哪位数据
intncounter=0;
//定时器循环次数
intcounter=0;
intZJ=3;
//定时器T1内部自加变量
bitzhongj1=0;
//判断修改时间时的闪烁位数
bitzhongj2=0;
bitzhongj3=0;
bitzhongj4=0;
bitzhongj5=0;
bitzhongj6=0;
bitzhongj7=0;
bitzhongj8=0;
main()//主程序开始
{
vart_init();
//定时器初始化
while
(1)
{
Updata_LED1();
//判断子程序
Updata_LED2();
//显示子程序
if(miao==40)//秒等于40秒时显示日期(年\月\日\星期)
{
qufen=1;
}
if(miao==45)//秒等于45秒时显示时间(时\分\秒\星期)
qufen=0;
}
if(stop==0)//判断按键1是否按下并执行后面程序
zhanting=1;
if(zhanting==1)//判断按键1按下,并调用按键子程序
{
Xiugai();
}
}
}//主程序结束
Xiugai()//按键子程序:
暂停,判断是否执行数据修改
TR0=0;
//关闭定时器T0
if(wei==0)//判断按键2是否按下并执行相应程序
weishu++;
Delay1();
if(weishu==6)//当按键2按下6次后打开中断
{//并关闭数据修改子程序,恢复时钟继续运行
TR0=1;
//打开定时器T0
zhanting=0;
weishu=0;
}
}
Xiugaishu();
}
Xiugaishu()//数据修改子程序
if(qufen==0)//判断此时显示为时\分\秒\星期
switch(weishu)
{
case
(1):
if(jia==0)//检查按键3是否按下并执行下面程序
{
shi++;
//时++
Delay1();
//消抖
};
break;
case
(2):
fen++;
//分++
case(3):
miao++;
//秒++
case(4):
xingqi++;
//星期++
}
else
if(qufen==1)
nian++;
//年++
yue++;
//月++
riqi++;
//日++
}
Updata_LED1()//判断秒、分、时、日、月、年、星期是否到上限
{
if(ZJ==99)//定时器T1内部自加变量
ZJ=4;
}//并初始化,向上一级进位
if(miao==60)//判断秒是否到60秒
fen++;
miao=0;
if(fen==60)//判断分
shi++;
fen=0;
if(shi==24)//判断小时
riqi++;
xingqi++;
shi=0;
if(riqi==30)//判断日期
yue++;
riqi=0;
if(yue==12)//判断月
nian++;
yue=0;
if(nian==100)//判断年
nian=0;
if(xingqi==8)//判断星期
xingqi=1;
}
Updata_LED2()//显示子程序
if(qufen==0)//判断此时显示为时\分\秒\星期
intnTemp,xiaoshu=0x00;
if(weishu==5)//修改星期数据时闪烁程序
zhongj4=0;
if(weishu==4&
&
ZJ%2==0)
zhongj4=!
zhongj4;
zhongj3=0;
if(zhongj4==0)
P2=0XFF;
//显示星期
P0=Table[xingqi];
led7=0;
Delay();
if(weishu==3&
ZJ%2==0)//修改秒数据时闪烁程序
zhongj3=!
zhongj3;
zhongj2=0;
if(zhongj3==0)
nTemp=miao/10;
//显示秒十位
P0=Table[nTemp];
led4=0;
nTemp=miao%10;
//显示秒个位
led5=0;
}
if(weishu==2&
ZJ%2==0)//修改分数据时闪烁程序
zhongj2=!
zhongj2;
zhongj1=0;
if(zhongj2==0)
nTemp=fen/10;
//显示分十位
led2=0;
nTemp=fen%10;
//显示分个位
xiaoshu=0x80|Table[nTemp];
//点亮小数点
P0=xiaoshu;
led3=0;
if(weishu==1&
ZJ%2==0)//修改数据时闪烁程序
zhongj1=!
zhongj1;
if(zhongj1==0)
nTemp=shi/10;
//显示时十位
led0=0;
nTemp=shi%10;
//显示时个位
led1=0;
//显示横杆
P0=Table[10];
led6=0;
if(qufen==1)//判断此时显示年\月\日\星期
{
zhongj5=0;
zhongj5=!
zhongj5;
zhongj6=0;
if(zhongj5==0)
ZJ%2==0)//修改日数据时闪烁程序
zhongj6=!
zhongj6;
zhongj7=0;
if(zhongj6==0)
nTemp=riqi/10;
//显示日十位
nTemp=riqi%10;
//显示日个位
ZJ%2==0)//月修改数据时闪烁程序
zhongj7=!
zhongj7;
zhongj8=0;
if(zhongj7==0)
nTemp=yue/10;
//显示月十位
nTemp=yue%10;
//显示月个位
ZJ%2==0)//修改年数据时闪烁程序
zhongj8=!
zhongj8;
if(zhongj8==0)
nTemp=nian/10;
//显示年十位
nTemp=nian%10;
//显示年个位
}
Delay()//延时子程序(显示)
inti;
for(i=0;
i<
10;
i++);
Delay1()//延时子程序1(消抖)
inti,j;
i<
250;
i++)
for(j=0;
j<
j++);
voidTimer0_Overflow()interrupt1//定时器T0子程序
TH0=0x3c;
//50MS溢出
TL0=0xbd;
if(ncounter==20)//循环20次达到准确的1S
ncounter=0;
miao++;
//秒加1
ncounter++;
voidTimer1_Overflow()interrupt3//定时器T1子程序
TH1=0xCD;
//13MS溢出
TL1=0x38;
if(counter==10)//循环10次
counter=0;
ZJ++;
//变量加1
counter++;
vart_init()//定时器初始化子程序
{PT0=1;
//设置优先级
TMOD=0X11;
//定时器T0\T1工作在方式01下
TH0=0XC0;
//装载初值
TL0=0XFB;
ET0=1;
//打开中断
TR0=1;
EA=1;
TH1=0XCD;
TL1=0X38;
ET1=1;
TR1=1;
TF0=0;
TF1=0;
3.硬软件设计
1、电路仿真:
通过仿真软件绘制电子万年历的电路图,并测试其正确可行性。
2、硬件准备:
按照电路图所需的元件申请元件库。
3、焊接电路:
依据电路图进行焊接,焊接中确保焊接成功,不出现虚焊、缺焊等问题。
4、电板调试:
焊接成功后,对电板进行测试,确保电板的可使用性。
如果出现问题对其进行检查,并对错误进行修正。
4.实现与测试
电路板焊接完成确定无误后,将汇编程序写入单片机。
然后连接5V电源,测试功能。
发现可以交替显示时、分、秒、星期和年、月、日、星期信息。
测试按键后没有问题。
但是数码管的显示亮度太低。
经老师提醒,是所接上拉电阻为10K,导致电流太小的原因。
之后重新焊接了上拉电阻,显示亮度达到正常。
单片机写入C语言程序后,发现数码管的显示消隐没有做好,星期显示本应显示2,却始终显示0。
将C语言程序消隐部分完善后,显示没有问题。
按键检测功能正常。
5.分析与总结
此次的课外学分设计和以前的电路不一样,硬件相对较少,重要的部分是大量的程序。
在硬件方面,基于自己熟练的焊接电路的技术,电路一次就焊接成功了
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子 万年历 设计 报告