单片机课程设计电子时钟Word文件下载.docx
《单片机课程设计电子时钟Word文件下载.docx》由会员分享,可在线阅读,更多相关《单片机课程设计电子时钟Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
2.3系统流程图
键盘扫描流程图
显示函数流程图
闰年,闰月的判断(从日到月及年的加程序,从年到月再到日减得程序与此类似,因此不再编写流程图)
调时函数流程图(移位键按一次,调秒。
按两次调分,按三次,调时。
此外功能切换键按一次是时分秒切换到年月日,按两次是切换到闹钟,按三次是切换倒计时。
流程图和上图类似)
闹钟函数流程图
主函数流程图
中断函数流程图
第三部分主要器材及基本简介
3.1主要器材
1.STC89C51RC单片机一个,LCD7406数码管。
3.2主要器材简介
STC89C51RC单片机是采用8051核的ISP在系统可编程芯片,片内涵4Kbytes的可反复擦写的Flash制度程序储存器,器件80C51引脚结构,芯片内集成了6位中央处理器。
具有在系统中可编程特性,配合PC端的控制程序即可将用户的程序下载到单片机内部,省去了购买通用编成器,而且速度更快。
80C51引脚图
第四部分系统硬件设计
4.1数码管显示电路
数码管的显示屏S0-S5和单片机的P2.0-P2.5相接。
段选地址和单片机的P1.0-P1.7相连。
4.2键盘输入电路
采用点阵式键盘,6个独立式按键由P0.0-P0.1和P2.0-P2.2共同控制,先判断行为0其他制1,在检测那个列线为0,则该列与制0的行线交叉处的按键就是被按下的按键。
4.3蜂鸣器
蜂鸣器的作用是整点报时,定时时间到时报时以及倒计时时间归零是报警。
与单片机P0.3相连,低电平有效。
第五部分课程设计总结
历时两周多的努力钻研,这个单片机实训终于画上了一个完美的的句号;
然而这短短的两周,却令我收益匪浅。
我记得开始看见题目要求是自己还是一片茫然,感觉要独自把这些要求做完对我来说是过于勉强,加上考试将近,我的心思没法完全集中在实训上,前几天的开始设计程序是我就遇到不少难题没法解决,当时自己的心里就想着万一不行就弄出个基础要求就行。
当听见同寝室的学霸*在考试前就基本完成了,这时让我如梦初醒,也许这个实训没我想象中这么难;
于是我决定在考完试后全身心投入到这实训中去。
考试考完,我总结了一些难点,并逐个突破最终完成实训:
难点1;
实验中我们所用的自己早就焊好的单片机的矩阵键盘的编程方法让人头疼,因为它的键盘的设定端口一端在P0,一端在P2,不会设定这种类型的矩阵键盘,那么就只能用两个键,这将给编程实现的功能带来极大的麻烦。
自己看书,也查了一些资料,但总是差那么一步,我就请教了*,终于找到了解决办法,自己的键盘扫描函数内部需要补上(while!
R0)以保证键盘扫描循环进行;
之后的编程我不断思考一个问题:
怎样能够极大地在简化编程同时满足逻辑的严谨;
答案就是熟悉各种编程逻辑语言和加深对单片机各种功能的理解,不断地问自己自己思考的是否全面,是否漏了什么或者多了什么,不断地尝试,从失败中查找自己的错误,首先是自己错在哪,之后是为什么错了,最后是怎么改。
这样步步为营,为我的编程省了很大的精力和时间。
难点2;
实验中要求在调时的时候,调时位要做到闪烁;
闪烁就是一暗一灭;
联想到有LED闪烁,那么原理是一样的,半个周期亮,半个周期灭,那么借鉴这点运用到数码管的话,只要在定时器的计时上和显示函数上进行一个关联就行,这样就可以在定时器在0.5s时给他的闪烁标志位置数(同时联想到移位就调时,就可以令移位键与闪烁标志位的所置的数相联系),在达到1s时把标志位的置数清零,这样在显示函数内用闪烁标志位进行判断是否执行闪烁,这样巧妙利用定时器和标志位就做到了闪烁。
这次实训让我学到了很多东西,让我对一些自己忽略的基本有了新的认识,让我对细节的重要性有了更深的体会,往往是一些自己不注意的细节让自己陷入困境,同时我也认识到无论有多少困难,那并不重要,重要的是自己努力了多少,因为你不努力那么你永远也不会知道自己的极限和潜力能达到一个什么样的位置。
附录
1.系统源程序及功能说明
#include<
reg52.h>
//调用头文件
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
staticunsignedchars=55,m=59,h=23,s1=5,m1=0,h1=0,s2=0,m2=0,h2=0,s3=0,m3=0,h3=0;
//实时、闹钟、定时器、倒数计时器的时分秒定义和赋初值;
sbitR0=P0^0;
sbitR1=P0^1;
sbitC0=P2^0;
sbitC1=P2^1;
sbitC2=P2^2;
//键盘端口定义
sbitbell=P0^3;
//蜂鸣器端口定义
unsignedinttcount,t1count,key,number,k,a,t,i,flag,nian,b,r=28,y=2,n=1900;
//参数定义以及年月日赋初值
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管显示的段选
voiddelay(uchari)//延时函数;
进行延时;
入口参数i;
无出口参数;
没有调用子程序;
{
ucharj,k;
for(j=i;
j>
0;
j--)
for(k=125;
k>
k--);
}
voidkeyscan()//键盘扫描函数;
判断哪个键被按下;
入口参数C0、C1、R0、R1、R2;
出口参数a、k、number、t、key;
调用的子函数为delay(uchari),进行消抖;
C0=1;
列0(最右边)列扫描
if(R0==0){delay(15);
if(R0==0)a=(a+1)%3;
while(!
R0);
}//关闹钟以及定时清零键S6被按下;
if(R1==0){delay(15);
if(R1==0)k=(k+1)%4;
R1);
}//移位调时键S7被按下;
C1=1;
列1(最左边)列扫描
if(R0==0)number=2;
}//减一键S5被按下;
if(R1==0)number=1;
}//加一键S4被按下;
C2=1;
列2(中间列)列扫描
if(R0==0)t=(t+1)%2;
}//定时器以及倒计时器的开关和暂停键S2被按下;
if(R1==0)key=(key+1)%5;
}//功能键S3被按下;
}
voiddisplay(uchars,ucharm,ucharh)//显示函数:
显示实时、调时、计时的时间;
入口参数s,m,h;
出口参数s/10,s%10,m/10,m%10,h/10,h%10;
嵌套子程序有delay(uchari)、keyscan();
{if(flag!
=1)//移位标志flag不与数码管位选的标志位对应,则正常显示;
{P2=0x20;
//数码管显示的位选地址0x20,0x10;
P1=table[s%10];
//P1口向数码管输入数据并显示;
delay(3);
//延时
P2=0x10;
//
P1=table[s/10];
if(flag==1)//移位标志flag与数码管位选的标志位对应,则闪烁;
P2=0x00;
//关显示;
if(flag!
=2)
{P2=0x08;
P1=table[m%10];
P2=0x04;
P1=table[m/10];
if(flag==2)
=3)
{P2=0x02;
P1=table[h%10];
P2=0x01;
P1=table[h/10];
if(flag==3)
keyscan();
//键盘扫描
voidmonth1()//闰月和大小月判断函数:
判断月份包含多少天,适用于累加;
入口参数:
r、y、n,出口参数y;
没有嵌套子程序;
{if((y==1)||(y==3)||(y==5)||(y==7)||(y==8)||(y==10)||(y==12)){if(r==32){r=1;
y++;
}}//大月31天
if((y==4)||(y==6)||(y==9)||(y==11)){if(r==31){r=1;
}}//小月30天
if(y==2){if(n%400==0||(n%4==0&
&
n%100!
=0)){if(r==30){r=1;
}}//闰年二月29天
if(n%4!
=0||(n%100==0&
n%400!
=0)){if(r==29){r=1;
}}}//平年二月28天
voidmonth2()//闰月和大小月判断函数:
判断月份包含多少天,适用于递减;
{if((y==1)||(y==3)||(y==5)||(y==7)||(y==8)||(y==10)||(y==12)){if(r==0){r=31;
y--;
}}
if((y==4)||(y==6)||(y==9)||(y==11)){if(r==0){r=30;
=0)){if(r==0){r=29;
=0)){if(r==0){r=28;
}}}
voidchangetime()//调时函数:
执行显示,切换实时时间、闹钟定时器、倒数计时器及其调时和设定计时初值;
入口参数:
number、key、k;
出口参数:
s、m、h、s1、m1、h1、s2、m2、h2、r、y、n;
嵌套子程序为display(uchars,ucharm,ucharh);
{if(key==0)//功能键标志位为0(没按下功能键);
{display(s,m,h);
//显示实时时间;
if(k==1)//移位标志为1(按下一次移位键)
{{if(number==1)//按下加一键
{s++;
number=0;
//秒加一
if(s==60)s=0;
}//秒置为0;
}
{if(number==2)//按下减一键
{s--;
//秒减一
if(s==-1)s=59;
}//秒置为59
}}
if(k==2)//移位标志为2(按下两次移位键)
{{if(number==1)
{m++;
if(m==60)m=0;
{if(number==2)
{m--;
if(m==-1)m=59;
if(k==3)//移位标志为3(按下三次移位键)
{h++;
if(h==24)h=0;
{h--;
if(h==-1)h=23;
}
if(key==1)//功能键标志为1(按下一次功能键)
{display(r,y,nian);
//显示年月日;
if(k==1)
{r++;
month1();
{r--;
month2();
if(k==2)
{y++;
if(y==13)y=1;
{y--;
if(y==0)y=12;
if(k==3)
{n++;
if(n==10000)n=0;
{n--;
if(n==0)n=9999;
if(key==2)//功能键标志为2(按下两次功能键)
{display(s1,m1,h1);
//显示闹钟定时时间
{s1++;
if(s1==60)s1=0;
{s1--;
if(s1==-1)s1=59;
{m1++;
if(m1==60)m1=0;
{m1--;
if(m1==-1)m1=59;
{h1++;
if(h1==24)h1=0;
{h1--;
if(h1==-1)h1=23;
if(key==3)//功能键标志为3(按下三次功能键)
{display(s2,m2,h2);
//显示定时器和倒数计时器的定时时间,倒数计时显示时间
{s2++;
if(s2==60)s2=0;
{s2--;
if(s2==-1)s2=59;
{m2++;
if(m2==60)m2=0;
{m2--;
if(m2==-1)m2=59;
{h2++;
if(h2==24)h2=0;
{h2--;
if(h2==-1)h2=23;
if(key==4)//功能键标志为4(按下四次功能键)
{display(s3,m3,h3);
}//显示定时器时间
voidalarm()//闹钟函数:
在定的闹钟时间到、定时器时间到、倒数计时器时间到、则闹钟响;
入口参数s、m、h,s1、m1、h1,t,s2、m2、h2,s3、h3、m3;
出口参数:
a;
{if(s2==s3&
m2==m3&
h2==h3&
(s3!
=0||m3!
=0||h3!
=0))a=a+1;
//定时器时间到,闹钟标志位进一
if(t==1&
s2==0&
m2==0&
h2==0)a=a+1;
//倒数计时器时间到,闹钟标志位进一
if(s==s1&
m==m1&
h==h1)a=a+1;
//闹钟时间到,闹钟标志位进一
if(a==1)bell=~bell;
//闹钟标志位为1,闹钟响;
main(void)//主函数:
执行开启定时器1、定时器2,并进行调时、闹铃的功能;
入口出口参数没有;
调用的寄存器存储单元:
中断允许寄存器为0A8H、TMOD为89H;
嵌套子程序为changetime()和alarm()
{
TMOD=0x11;
//(方式3)
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//定时器0赋初值
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
//定时器1赋初值
EA=1;
//开系统中断
ET0=1;
//开定时器中断0
ET1=1;
//开定时器中断1
TR0=1;
//开定时器0
TR1=1;
//开定时器1
nian=n%100;
while
(1)//重复执行
{
changetime();
//调时
alarm();
//闹钟
voidt0(void)interrupt1using0//定时器0工作方式1:
进行实时时间的定时计数;
入口参数k,tcount,出口参数flag,s,m,h,r,y,n;
嵌套子函数month1();
{TH0=(65536-50000)/256;
tcount++;
if(tcount==10){if(k>
0)flag=k;
}//在为0.5s的时候判断k如果满足k>
0,给闪烁的标志flag赋值;
if(tcount==20)//时间达到1s
{tcount=0;
//计数器清零
flag=0;
//闪烁标志flag清零
s++;
if(s==60)//秒计数
{s=0;
m++;
if(m==60)//分计数
{m=0;
h++;
if(h==24)//时计数
{h=0;
r++;
month1();
//调用月份判断;
执行月计数
if(y==13)//年计数
{y=1;
n++;
}
voidt1(void)interrupt3using2//定时器1工作于方式3:
进行倒计时和定时;
入口参数k,t1count,t,key;
出口参数flag、s2、m2、h2、s3、m3、h3;
没有嵌套子函数;
{TH1=(65536-50000)/256;
t1count++;
if(t1count==20)t1count=0;
//定时器清零
if(t==1)//倒数计时器开启和暂停开启
{if(key==3)显示倒数计时
{if(t1count==10){if(k>
if(s2!
=0||m2!
=0||h2!
=0)//倒数计时器初值不为0
{if(t1count==0){s2--;
flag=0;
}//秒倒计时
if(m2>
0&
s2==-1){m2--;
s2=59;
}//分倒计时
if(h2>
s2==-1){h2--;
m2=59;
}//时倒计时
}
if(t==1)定时器开启和暂停键开启
{if(key==4)显示定时走时
{if(s2!
{if(t1count==0&
s2!
=s3||m2!
=m3||h2!
=h3)//1s时间到,且定时时间和定时器走时不等
{s3++;
if(s3==60){m3++;
s3=0;
}//秒计时
if(m3==60){h3++;
m3=0;
}//分计时
if(h3==24){h3=0;
}//时计时
if(s2==s3&
h2==h3)//定时时间和定时器走时相等
{s3=s2;
m3=m2;
h3=h2;
}//停止走时
if(a==2){s3=0;
h3=0;
}//清零
电子钟使用的是STC89C52RC型号的单片机,通过编程实现六段数码管的显示,即:
分俩页显示时分秒和年月日。
通过6个按键控制,其中S2:
倒计时开启按键,S3:
功能选择按键,S4:
减一按键,S5:
加一按键。
S6:
闹钟停止按键,S7:
移位按键。
由P2.0-P2.2和P0.0-P0.1共同控制,而六段数码管分别和P2.0-P2.5相连。
2.功能说明
(1)各个按键的功能:
通过按下按键可对数码管所显示的进行调解调节。
如加1,减1,复位,移位,功能选择及确定等功能。
时间:
时钟上电后,可