多功能电子时钟报告.docx
- 文档编号:2745018
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:51
- 大小:340.25KB
多功能电子时钟报告.docx
《多功能电子时钟报告.docx》由会员分享,可在线阅读,更多相关《多功能电子时钟报告.docx(51页珍藏版)》请在冰点文库上搜索。
多功能电子时钟报告
单片机设计实验报告
多功能电子时钟设计
班级:
学号:
姓名:
指导教师:
多功能电子时钟
(一)实验目的
1、巩固和加深对单片机实验设计的理解,提高综合运用本课程所学知识的能力;
2、掌握单片机的P0、P1、P2口的使用方法,及编程实现所需功能;
3、掌握掌握单片机键盘扫描方法;
4、通过电路方案的分析、论证和比较,设计计算和选取元器件、电路组装、调试和检测等环节,初步掌握简单实用电路的分析方法和工程设计方法;
5、学会keil软件及protuse软件仿真和硬件电路的实验调试和性能指标的测试方法,提高学生动手能力和进行单片机程序设计应用的基本技能;
(二)实验任务及要求
基本功能:
1、显示时间;
2、调节时间;
3、设置闹钟时间;
4、整点报时(可开可关可随时停止);
扩展功能:
5、简易计算器(可算加减法)计算范围是:
9999-(-999)内的整数加减运算;
6、秒表(可精确到百分之一秒和十分之一秒,可切换)可存储三个时间并读取显示;
7、倒计时(可设置倒计时时间,减到0后蜂鸣器响);
(三)实验总电路图(这个硬件电路图是不完善的哈!
)
(四)实验原理
1、显示电路
采用动态扫描的方式,不断给P0和P1口送数,其中,P0口决定数码管显示的内容,而P1口决定哪个数码管显示。
在程序中,首先定义数码管的编码:
unsignedcharcodeSelect[]={0x00,0x07,0x0b,0x0d,0x0e};//全亮,第一个,第二个,第三个,第四个
//code说明把这个表格里面的数据存在程序存储器中
unsignedcharcodeLED_CODES[]=
{0x02,0x9e,0x24,0x0c,0x98,//0-4
0x48,0x40,0x1e,0x00,0x08,//5-9
0x10,0xc0,0x62,0x84,0x60,0x70,//A,b,C,d,E,F
0xFe,0x30,0x90,0x7e,0xBe,0xfc//空格(16),P,H,-,|,
};
然后,在程序中,我定义了一下两个函数,通过对上面数组的操作,进行数码管显示:
voiddisplay(uintx,uinty)//显示函数
{
uinti,j;
i=x;j=y;
P1=Select[i];
P0=LED_CODES[j];
}
voiddisplay2(uinta,uintb,uintc,uintd)//显示函数2
{
uinti,j,m,n;
i=a;j=b;m=c;n=d;
display(1,i);
delay(5);
display(2,j);
delay(5);
display(3,m);
delay(5);
display(4,n);
delay(5);
}
通过延时,利用人眼视觉暂留的作用,用动态扫描,达到静态显示的效果。
2、键盘扫描电路
从总电路图可以看到,我把键盘阵通过P2口来检测。
通过不断的给P2口送值,然后检测P2口的状态,从而判断出,究竟哪个按键被按下,然后去执行之后的程序。
键盘检测时,给P2口送的值以及检测到某个按键所对应的值,如下表:
送值
检测
对应按键
送值
检测
对应按键
P2=0xf7
0x70
按键1
P2=0xfd
0x70
按键9
0xb0
按键2
0xb0
按键←
0xd0
按键3
0xd0
按键0
0xe0
按键4
0xe0
按键→
P2=0xfb
0x70
按键5
P2=0xfe
0x70
按键↑
0xb0
按键6
0xb0
按键↓
0xd0
按键7
0xd0
按键OK
0xe0
按键8
0xe0
按键Esc
通过不同的按键,实现不同的功能选择。
(五)实验操作
电子时钟的操作方法,如下图:
下面,具体介绍各功能使用方法:
1、计算器功能,如下图:
2、时钟功能,如下图:
3、秒表倒计时功能,如下图:
(六)时钟误差分析
在51定时器做电子钟的误差分析里,有3项:
1、机器周期误差,由晶体频率相对变化的误差产生;
2、中断响应延迟误差;
3、调整精度产生的误差,就是计数初值改变1对应的时间差。
定时器是独立于CPU的硬件计数器,对于89C51CPU只管理启动和装初值。
一旦定时器启动之后,就一直在计数,在定时器溢出后会从0重新开始计数,不存在等待问题。
所以,定时的误差除了晶体自身的误差(主要指晶体的频率漂移误差,而晶体频率偏离标称值的固定的绝对误差是可以修正的)以外,就是来自从定时器溢出中断到装初值这段时间的误差,由于从溢出到响应中断的时间不确定,所以存在不定的误差。
而在我的程序中,是每50ms产生一次中断,每次进入中断之后,重新赋初值,即会每50ms赋一次初值。
在实际测试时,发现每一分钟就会慢1s,所以一个小时下来基本上就有一分钟的误差了。
出现这个现象的原因也是因为一开始我并没有考虑到误差这个问题。
考虑到这个问题后,我也试着去想一些办法解决这个精度问题。
解决方法有一下几种:
1)配上收音头,1小时或1天收一次中央台的哨声用于校正,可保证累积误差最少;
2)可以用定时器方式2自动装入初值的方法,从而解决了由于定时器重载后,定时器才重新开始计数,而导致的延迟;
3)选择比较好的晶振,减少由于晶振产生的误差。
(七)实验感想
通过这次实验,我掌握了单片机的P0口、P1口以及P2口的基本功能的使用,学会了在Keil下用c语言编写单片机程序的能力。
在硬件设计及软件编程方面,都有了较大的提升。
会用程序的编写,来实现自己设计的功能。
在硬件电路方面,起先在实验是的实验箱上做实验,后来发现实验箱都很不稳定,容易出现“通讯出错”的问题。
于是,后来自己买了一块开发板。
之后通过对该开发板上的资源的学习,熟练掌握了开发板的硬件电路原理之后,便开始自己编写程序。
利用开发上的资源,实现自己设计的功能。
在软件编程方面,一向习惯用c语言编写程序的我,感觉在掌握了硬件电路之后,在软件编程上还是比较简单的。
通过几天的奋战,终于把所有功能都实现了,代码也是比较多。
由于自己开始时并没有注意各个变量的命名使用,所以,在做后来的代码优化时,发现还是比较乱一点的。
代码不易修改。
这也是我今后编写程序时需要注意的问题。
最后就是电路板的焊接,由于对硬件电路已经比较熟悉了,所以,在电路板的设计上,并没有花多长时间。
焊接完毕之后,发现自己的焊接工艺仍需要提高,但是,由于注意到不能乱“飞线”的问题,所以,这个电路板在这个方面还是做到了。
附件:
程序全部
#include
#include
#defineuintunsignedint
unsignedcharcodeSelect[]={0x00,0x07,0x0b,0x0d,0x0e};//全亮,第一个,第二个,第三个,第四个
//code说明把这个表格里面的数据存在程序存储器中
unsignedcharcodeLED_CODES[]=
{0x02,0x9e,0x24,0x0c,0x98,//0-4
0x48,0x40,0x1e,0x00,0x08,//5-9
0x10,0xc0,0x62,0x84,0x60,0x70,//A,b,C,d,E,F
0xFe,0x30,0x90,0x7e,0xBe,0xfc//空格(16),P,H,-,|,
};
uintzhuantai,flag=0,i=0,weixuan1=0,weixuan2=0,flag1=0,flag2=0,anci=1,qianwei1=0,baiwei1=0,shiwei1=0,gewei1=0,qianwei2=0,baiwei2=0,shiwei2=0,gewei2=0;
uintnum1=3;uintnum2=2;uintnum3=1;uintnum4=17,jieguo1=0;
intjieguo2=0;
uintqianwei3=0,baiwei3=0,shiwei3=0,gewei3=0,/*flag1=0,*/flagjisuanqi=0,flagshizhong=0,flagled=0,flagmiaobiao=0,flagmiaobiao2=0,flagzanting=0;
uintflagshi=0,flagfen=0,flagmiao=0,flagzuoyi=0,yiwei=0,flagyiwei=0,flagnaozhong=0;
uintj4=0,j3=9,j2=5,j1=1,j0=1,tt,ttm=0,jm4=0,jm3=0,jm2=0,jm1=0,jm0=0;
sbitledkg=P3^2;
sbitBUZ=P3^6;
voiddelay(uintz)//延时子程序1s
{
uinti,j;
for(j=z;j>0;j--)
for(i=110;i>0;i--);
}
voiddisplay(uintx,uinty)//显示函数
{
uinti,j;
i=x;j=y;
P1=Select[i];
P0=LED_CODES[j];
}
voiddisplay2(uinta,uintb,uintc,uintd)//显示函数2
{
uinti,j,m,n;
i=a;j=b;m=c;n=d;
display(1,i);
delay(5);
display(2,j);
delay(5);
display(3,m);
delay(5);
display(4,n);
delay(5);
}
voiddisplay3()//显示函数3
{
uinti;
for(i=10;i>0;i--)
{
delay(5);
display2(num4,num3,num2,num1);
}
}
voidqingling()//清零函数
{
num4=0;num3=0;num2=0;num1=0;anci=1;
qianwei1=0;baiwei1=0;shiwei1=0;gewei1=0;qianwei2=0;baiwei2=0;shiwei2=0;gewei2=0;qianwei3=0;baiwei3=0;shiwei3=0;gewei3=0;
jieguo1=0;jieguo2=0;flagzanting=1;jm0=0;jm1=0;jm2=0;jm3=0;
}
voidbeijiashu()//被加数存储函数
{if(num4==16){num4=0;}if(num3==16){num3=0;}if(num2==16){num2=0;}if(num1==16){num4=14;num3=10;num2=10;num1=0;}
qianwei1=num4;baiwei1=num3;shiwei1=num2;gewei1=num1;
jieguo1=qianwei1*1000+baiwei1*100+shiwei1*10+gewei1;flag1=1;
num4=16;num3=16;num2=16;num1=16;//anci=0;
}
voidbeijianshu()//被减数存储函数
{if(num4==16){num4=0;}if(num3==16){num3=0;}if(num2==16){num2=0;}if(num1==16){num4=0;num3=0;num2=0;num1=0;}
qianwei1=num4;baiwei1=num3;shiwei1=num2;gewei1=num1;
jieguo1=qianwei1*1000+baiwei1*100+shiwei1*10+gewei1;flag1=2;
num4=16;num3=16;num2=16;num1=16;//anci=0;
}
voidjiashu()//加数存储函数
{
if(num4==16){num4=0;}if(num3==16){num3=0;}if(num2==16){num2=0;}if(num1==16){num4=14;num3=10;num2=10;num1=0;}
qianwei2=num4;baiwei2=num3;shiwei2=num2;gewei2=num1;
jieguo2=jieguo1+qianwei2*1000+baiwei2*100+shiwei2*10+gewei2;
if(jieguo2>9999)
{
num4=14;num3=10;num2=10;num1=0;
}
else
{
if(jieguo2/1000==0){num4=16;}else{num4=jieguo2/1000;}
if((jieguo2%1000)/100==0&&jieguo2/1000==0){num3=16;}else{num3=(jieguo2%1000)/100;}
if(jieguo2%1000%100/10==0&&(jieguo2%1000)/100==0&&jieguo2/1000==0){num2=16;}else{num2=jieguo2%1000%100/10;}
num1=jieguo2%10;
}
}
voidjianshu()//减数存储函数
{if(num4==16){num4=0;}if(num3==16){num3=0;}if(num2==16){num2=0;}if(num1==16){num4=14;num3=10;num2=10;num1=0;}
qianwei2=num4;baiwei2=num3;shiwei2=num2;gewei2=num1;
jieguo2=jieguo1-(qianwei2*1000+baiwei2*100+shiwei2*10+gewei2);
if(jieguo2<0)
{
if(jieguo2>-9)
{
num4=16;num3=16;num2=21;num1=abs(jieguo2);
}
elseif(jieguo2>-99)
{
num4=16;num3=21;num2=abs(jieguo2)/10;num1=abs(jieguo2)%10;
}
elseif(jieguo2>=-999)
{
num4=21;num3=abs(jieguo2)/100;num2=abs(jieguo2)%100/10;num1=abs(jieguo2)%10;
}
else
{num4=14;num3=10;num2=10;num1=0;}
}
else
{if(jieguo2/1000==0){num4=16;}else{num4=jieguo2/1000;}
if((jieguo2%1000)/100==0&&jieguo2/1000==0){num3=16;}else{num3=(jieguo2%1000)/100;}
if(jieguo2%1000%100/10==0&&(jieguo2%1000)/100==0&&jieguo2/1000==0){num2=16;}else{num2=jieguo2%1000%100/10;}
num1=jieguo2%10;
}
}
voidanjian(uintcishu,uintchuzhi)
{
uintn;uintm;n=cishu;m=chuzhi;
if(n==1)num1=m;
elseif(n==2)
{num2=num1;num1=m;}
elseif(n==3)
{num3=num2;num2=num1;num1=m;}
elseif(n==4)
{num4=num3;num3=num2;num2=num1;num1=m;}
else{num4=num3;num3=num2;num2=num1;num1=m;}
}
voidjianpan()//=============================键盘计算器函数1=====================//
{
uintma;
display2(num4,num3,num2,num1);
P2=0xf7;
zhuantai=P2;
zhuantai=zhuantai&0xf0;
while(zhuantai!
=0xf0)
{
delay(5);
zhuantai=P2;
zhuantai=zhuantai&0xf0;
if(zhuantai!
=0xf0)
{
switch(zhuantai)
{
case0x70:
display3();ma=1;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键1
case0xb0:
display3();ma=2;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键2
case0xd0:
display3();ma=3;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键3
case0xe0:
display3();ma=4;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键4
}
}
}
//=============================================================================//
P2=0xfb;
zhuantai=P2;
zhuantai=zhuantai&0xf0;
while(zhuantai!
=0xf0)
{
delay(5);
zhuantai=P2;
zhuantai=zhuantai&0xf0;
if(zhuantai!
=0xf0)
{
switch(zhuantai)
{
case0x70:
display3();ma=5;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键5
case0xb0:
display3();ma=6;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键6
case0xd0:
display3();ma=7;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键7
case0xe0:
display3();ma=8;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键8
}
}
}
//================================================================================//
P2=0xfd;
zhuantai=P2;
zhuantai=zhuantai&0xf0;
while(zhuantai!
=0xf0)
{
delay(5);
zhuantai=P2;
zhuantai=zhuantai&0xf0;
if(zhuantai!
=0xf0)
{
switch(zhuantai)
{
case0x70:
display3();ma=9;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键9
case0xb0:
display3();ma=0;anjian(anci,ma);display2(num4,num3,num2,num1);anci++;break;//按键0
case0xd0:
if(flagshizhong==0){qingling();num4=16;num3=16;num2=16;num1=16;}elseif(flagshizhong==1){display2(num4,num3,num2,num1);}display2(num4,num3,num2,num1);break;//清零
case0xe0:
display2(num4,num3,num2,num1);break;//无效按键
}
}
}
//====================================================================================//
P2=0xfe;
zhuantai=P2;
zhuantai=zhuantai&0xf0;
while(zhuantai!
=0xf0)
{
delay(5);
zhuantai=P2;
zhuantai=zhuantai&0xf0;
if(zhuantai!
=0xf0)
{
switch(zhuantai)
{
case0x70:
display3();if(flagshizhong==0){beijiashu();display2(num4,num3,num2,num1);}elseif(flagshizhong==1){display2(num4,num3,num2,num1);}break;//加法
case0xb0:
display3();if(flagshizhong==0){
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多功能 电子 时钟 报告