单片机应用电子时钟课程设计.docx
《单片机应用电子时钟课程设计.docx》由会员分享,可在线阅读,更多相关《单片机应用电子时钟课程设计.docx(15页珍藏版)》请在冰豆网上搜索。
单片机应用电子时钟课程设计
单片机应用课程设计
电子时钟
专业:
电气工程及其自动化
班级:
姓名:
指导教师:
电子时钟设计报告
一、课题设计目的
数字电子钟具有走时准确,一钟多用等特点,在生活中已经得到广泛的应用。
另外数字钟还具备秒表和闹钟的功能,且闹钟铃声可自选,使一款电子钟具备了多媒体的色彩。
单片机STC89C51在Proteus软件中实现数字时钟的定时、时间调整、闹正设置等功能。
具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。
在一个单片机应用系统中,时钟有两方面的含义:
一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间。
二、实验目的及意义:
1.理解学习LED数码管显示、以及硬件各引脚的含义
2.学习C51语言的应用。
3.学习Proteus、KEIL软件的应用。
4.培养解决实际问题的能力。
三、设计任务及要求(系统的主要功能)
1.具有时、分、秒计数显示功能,以24小时循环
2.LED数码管显示时、分、秒的个位和十位
3.可以在任意时刻校准时间
4.能够完成时间的显示、定时闹钟、复位等功能
四、工作原理及设计流程图
主程序是先开始,然后启动定时器,定时器启动后在进行按键检测,检测完后,就可以显示时间。
按键处理是先检测秒按键是否按下,秒按键如果按下,秒就加1;如果没有按下,就检测分按键是否按下,分按键如果按下,分就加1;如果没有按下,就检测时按键是否按下,时按键如果按下,时就加1;如果没有按下,就把时间显示出来。
定时器中断时是先检测1秒是否到,1秒如果到,秒单元就加1;如果没到,就检测1分钟是否到,1分钟如果到,分单元就加1;如果没到,就检测1小时是否到,1小时如果到,时单元就加1,如果没到,就显示时间。
五、硬件原理图
六、程序源代码
/***************************************
硬件连接:
数码管:
段码为:
P1
位码分别为:
P2.5~P2.0
蜂鸣器:
P2.7
功能键k1:
P3.4
加建k2:
P3.5
减键k3:
P3.6
***************************************/
#include//51头文件
sbitsmg1=P2^5;//位码1声明
sbitsmg2=P2^4;//位码2声明
sbitsmg3=P2^3;//位码3声明
sbitsmg4=P2^2;//位码4声明
sbitsmg5=P2^1;//位码5声明
sbitsmg6=P2^0;//位码6声明
sbitk1=P3^4;//按键k1的声明
sbitk2=P3^5;//按键k2的声明
sbitk3=P3^6;//按键k3的声明
sbitbeep=P2^7;//蜂鸣器声明
/*定义一些变量*/
chard=0,e=0,a=0,b=0,n=0,shi=12,fen=0,miao=0,b_shi=6,b_fen=30,b_miao=0;
charcodetable[]={//共阳级数码管码表0-9
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
voidinit();//初始化函数声明
voiddelay(intz);//带参数延时函数声明
voiddisplay(chars,f,m);//带参数显示函数声明
voidkey();//按键控制函数声明
voidmain()//主函数
{
init();//调用初始化函数
while
(1)//主函数内大循环
{
if(d==0)key();//如果d=0则扫描按键函数
if(shi==b_shi&&fen==b_fen)//如果闹铃时间到就蜂鸣器响
{
if(d==1&&!
(k1&k2&k3))//任意按键按下关闭铃声
{
e=1;//关闭闹铃标志位e
d=0;//屏蔽按键函数标志位d
}
if(e==0)//关闭铃声
{
d=1;//屏蔽按键函数
beep=0;//蜂鸣器鸣叫
delay(10);//延时一会
beep=1;//关闭蜂鸣器
}
}
if(n==0||n==1||n==2)//如果处在功能键的0、1、2三个中的某个状态
display(shi,fen,miao);//调用显示时钟
if(n==3||n==4)//如果处在功能键的3、4中的某个状态
display(b_shi,b_fen,b_miao);//调用显示闹铃时间
}
}
voidinit()//初始化函数
{
IE=0X8a;//10001010
TMOD=0X01;//00010001选择定时器0的工作方式1选择定时器1的工作方式1
TH0=(65536-50000)/256;//初值15536
TL0=(65536-50000)%256;
TR0=1;//开启定时器0
TH1=(65536-50000)/256;//初值15536
TL1=(65536-50000)%256;
TR1=1;//开启定时器1
}
voidtimer0()interrupt1//定时器0中断服务程序
{
TH0=(65536-50000)/256;//进入中断重新赋初值15536
TL0=(65536-50000)%256;//计数5万次(50毫秒)
a++;//每进一次中断a加一
if(a==20)//如果进入20次中断,正好一秒
{
a=0;//a到20就清零
miao++;//a每计20次,秒加一
if(miao==60)
{//秒到达60秒后清零,分加一
miao=0;
fen++;
e=0;//闹铃标志位清零
if(fen==60)
{//分到达60后清零,时加一
fen=0;
shi++;
if(shi==24)
{//时到达24后清零
shi=0;
}
}
}
}
}
voidtimer1()interrupt3//定时器1中断服务程序,用来设置光标闪烁频率
{
TH1=(65536-50000)/256;//进入中断重新赋初值15536
TL1=(65536-50000)%256;//计数5万次(50毫秒)
b++;//标志位b,用来确定光标闪烁频率
if(b==20)
b=0;//b=20时被清零
}
voiddisplay(chars,f,m)//带参数的显示函数,参数为sfm
{
smg1=0;//打开数码管1位选
P1=table[s/10];//给数码管1赋值,值为小时的十位
delay
(1);//延时
smg1=1;//关闭数码管1位选
P1=0Xff;//关闭数码管1段选
if(b<10&&(n==1||n==3))
{//在1,3状态下,b<10时,关闭数码管2
smg2=1;
P1=0Xff;
}
else//其他状态下,数码管2正常显示
{
smg2=0;//打开数码管2位选
P1=table[s%10];//给数码管2赋值,值为小时的个位
delay
(1);//延时
smg2=1;//关闭数码管2位选
P1=0Xff;//关闭数码管2段选
}
smg3=0;//打开数码管3位选
P1=table[f/10];//给数码管3赋值,值为分钟的十位
delay
(1);//延时
smg3=1;//关闭数码管3位选
P1=0Xff;//关闭数码管3段选
if(b<10&&(n==2||n==4))
{//在2,4状态下,b<10时,关闭数码管4
smg4=1;
P1=0Xff;
}
else
{//其他状态下,数码管4正常显示
smg4=0;//打开数码管4位选
P1=table[f%10];//给数码管4赋值,值为分钟的个位
delay
(1);//延时
smg4=1;//关闭数码管4位选
P1=0Xff;//关闭数码管4段选
}
smg5=0;//打开数码管5位选
P1=table[m/10];//给数码管5赋值,值为秒钟的十位
delay
(1);//延时
smg5=1;//关闭数码管5位选
P1=0Xff;//关闭数码管5段选
smg6=0;//打开数码管6位选
P1=table[m%10];//给数码管6赋值,值为秒钟的个位
delay
(1);//延时
smg6=1;//关闭数码管6位选
P1=0Xff;//关闭数码管6段选
}
voiddelay(intz)//带参数延时函数,参数Z
{//每次大约延时1毫秒
intx,y;
for(x=z;x>0;x--)//循环110*z次空函数
for(y=110;y>0;y--)
;
}
voidkey()//按键控制函数
{
if(k1==0)
{//功能键k1被按下
delay(5);//消抖延时
if(k1==0)
{
n++;//n记录功能键状态
if(n>4)n=0;//n清零
while(k1==0);//等待松手
}
}
if(n==0)//状态0,
{
TR0=1;//定时器打开状态
}
if(n==1)//状态1
{
TR0=0;//关闭定时器0
if(k2==0)
{//k2被按下
delay(5);//消抖延时
if(k2==0)
{
shi++;//小时加一
if(shi==24)
shi=0;//达到24清零
while(k2==0);//等待松手
}
}
if(k3==0)
{//k3被按下
delay(5);//消抖延时
if(k3==0)
{
shi--;//小时减一
if(shi<0)
shi=23;//小于0,重新复制
while(k3==0);//等待松手
}
}
}
if(n==2)//状态2
{
TR0=0;//关闭定时器0
if(k2==0)
{//k2被按下
delay(5);//消抖延时
if(k2==0)
{
fen++;//分加一
if(fen==60)
fen=0;//分到达60分清零
while(k2==0);//等待松手
}
}
if(k3==0)
{//k3被按下
delay(5);//消抖延时
if(k3==0)
{
fen--;//分减一
if(fen<0)
fen=59;//分小于0,分重新赋值59
while(k3==0);//等待松手
}
}
}
if(n==3)//状态三
{
TR0=1;//开启定时器
if(k2==0)
{//k2被按下
delay(5);//消抖延时
if(k2==0)
{
b_shi++;//闹铃时间加一
if(b_shi==24)
b_shi=0;//闹铃时间清零
while(k2==0);//等待松手
}
}
if(k3==0)
{//k3被按下
delay(5);//消抖延时
if(k3==0)
{
b_shi--;//闹铃时间减一
if(b_shi<0)
b_shi=23;//闹铃时间
while(k3==0);//等待松手
}
}
}
if(n==4)//状态四
{
TR0=1;//关闭定时器0
if(k2==0)
{//k2被按下
delay(5);//消抖延时
if(k2==0)
{
b_fen++;//闹铃时间分加一
if(b_fen==60)
b_fen=0;//闹铃分到达60清零
while(k2==0);//等待松手
}
}
if(k3==0)
{//k3被按下
delay(5);//消抖延时
if(k3==0)
{
b_fen--;//闹铃时间分减一
if(b_fen<0)
b_fen=59;//闹铃时间分重新赋值
while(k3==0);//等待松手
}
}
}
}
七、电子钟系统PROTUES仿真
用PROTUES软件,根据数字电子钟的原理图,画出仿真图,得到的图如下所示。
八、设计体会与总结
我在这一次数字电子钟的设计过程中,很是受益匪浅。
通过对自己所学的知识的回顾,并充分发挥对所学知识的理解思考,最终完成了。
这为自己今后进一步深化学习,积累了一定宝贵的经验。
撰写总结的过程也是专业知识的学习过程,它使我运用已有的专业基础知识,对其进行设计,分析和解决一个理论问题或实际问题,把知识转化为能力的实际训练。
培养了我运用所学知识解决实际问题的能力。
通过这次课程设计我发现,只有理论水平提高了;才能够将课本知识与实践相整合,理论知识服务于教学实践,以增强自己的动手能力。
这个实验十分有意义我获得很深刻的经验。
通过这次课程设计,我们知道了理论和实际的距离,也知道了理论和实际想结合的重要性,,也从中得知了很多书本上无法得知的知识。
我们的学习不但要立足于书本,以解决理论和实际教学中的实际问题为目的,还要以实践相结合,理论问题即实践课题,解决问题即课程研究,学生自己就是一个专家,通过自己的手来解决问题比用脑子解决问题更加深刻。
学习就应该采取理论与实践结合的方式,理论的问题,也就是实践性的课题。
这种做法既有助于完成理论知识的巩固,又有助于带动实践,解决实际问题,加强我们的动手能力和解决问题的能力。
在课程设计的过程当中,我遇到了所谓的“瓶颈时期”。
在没有很好的解决外部输入显示的问题之时,我没有找到合适的参考资料,没有遇到同样问题的人来给我提示,我完完全全感到自己走投无路,一度曾想放弃这个题目。
但是凭借着不断尝试和努力,我找到了解决问题的方法,最终完成了本次课程设计,这在对于我心态的磨练上也是及其重要的一步。
希望自己今后能够像在做单片机课程设计时表现出来的决心那样一直坚持到底。
也衷心感谢付老师以及各位助教老师,正是你们的负责、耐心,才使得同学们真正学有所用。