基于单片机的电子闹钟设计.docx
- 文档编号:12409118
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:25
- 大小:187.70KB
基于单片机的电子闹钟设计.docx
《基于单片机的电子闹钟设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子闹钟设计.docx(25页珍藏版)》请在冰豆网上搜索。
基于单片机的电子闹钟设计
基于单片机的电子闹钟设计
摘要
本设计以AT89C51芯片为核心,辅以必要的外围电路,设计了一个结构简单,功能齐全的电子时钟,它由5V直流电源供电。
关键词:
单片机;led;闹钟;定时器
Abstract
Thisdesign,adoptingAT89C51chipasthecorepartwithsomenecessaryperipheralcircuits,isasimpleelectronicclockwhichuses5VDCasthepowersupply.
Keywords:
singlechipmachine,infixedtimemachine,alarmclock,LED
1引言
1.1设计目的
此次课程设计是在学习先修课程《单片机原理与系统设计》之后,为加强对学生系统设计和应用能力的培养而开设的综合设计训练环节。
本课程设计应结合《单片机原理与系统设计》课程的基础理论,重点强调实际应用技能训练,包括单片机系统设计的软件和硬件两部分。
其课程设计任务是使学生通过应用单片机系统设计的基本理论,基本知识与基本技能,掌握单片机应用系统各主要环节的设计、调试方法,初步掌握并具备应用单片机进行设备技术改造和产品开发的能力,培养学生的创新意识,提高学生的动手能力和分析问题、解决问题的能力。
1.2设计要求
结合单片机知识,以AT89C51单片机为核心,利用七段LED数码管实现计时、校时及闹钟功能。
1.3设计方法
以AT89C51单片机为核心,外加晶振电路,使用8个七段数码管显示,LED采用动态扫描,用74ls245芯片作为驱动电路。
通过四个独立按键对时间进行定时、校时,从而实现闹钟提醒功能。
2设计方案及原理
2.1设计方案
选AT89C51单片机作为系统核心,辅助外部产生时钟信号的晶振电路,再加上四个独立按键作为输入信号,使用8个七段数码管显示时间,芯片74ls245为数码管段选线的驱动,最后用蜂鸣器实现闹铃功能。
使用单片机的定时器T0计时时间为50ms,计时20次作为1s的时间基准。
第一部分,12MHz的晶振连接至单片机的时钟信号输入端;第二部分,四个独立按键加上四个上拉电阻连接至单片机的P1口的低四位;第三部分,单片机的P0口通过由芯片74ls245构成的驱动电路连接至数码管的段选线,单片机的P3口连接至数码管的位选线;第四部分,单片机的P2.1通过一个NPN型三极管连接至蜂鸣器。
8个七段数码管使用动态扫描显示时间,独立按键用软件编程实现对时间和闹钟时、分、秒的设置,再通过比较所设置的闹钟与时间是否相等,达到闹铃发出声响的效果。
2.2设计原理
系统原理图如图2.1所示。
图2.1系统原理图
3硬件设计
硬件电路分四个模块:
晶振电路、键盘电路、数码管显示电路、蜂鸣器驱动电路。
晶振电路使用12MHz晶体振荡器,经分频后供单片机工作。
键盘采用4个独立按键配以4个上拉电阻实现对时钟和闹钟的设定及修改。
由于通过数码管公共及的电流较大且避免过多地使用分立元件,采用了一片74ls245来驱动段码,用P3口作位码驱动。
发音部分是通过三极管放大驱动蜂鸣器工作,再通过软件这时产生等时时间方波驱动蜂鸣器发出间断嘀声,这样就可以省去硬件振荡电路,降低成本。
系统硬件电路图如图3.1所示。
图3.1系统硬件图
4软件设计
源程序清单见附录。
主程序流程图如图4.1所示。
图4.1主程序流程图
5系统仿真及调试
硬件部分设置了的三个按键K1、K2、K3、K4。
当按键K1第一次按下时,停止计时进入闹钟1的秒设置,当按键K1第二、第三次按下时,分别进入闹钟1的分设置和时设置,当按K1第四、第五、第六次按下时分别进入闹钟2的秒、分、时设置,当按K1第七、第八、第九次按下时分别进入闹钟3的秒、分、时设置,当按K1第十、第二一、第十二次按下时分别进入时间的秒、分、时设置,在K1按下的各阶段,可用按键K2、K3进行时间和闹铃时间的时、分、秒进行加减设置;当按键K1第十三次按下时恢复到时间显示功能。
当显示的时间和定时设置的时间一致时,蜂鸣器发出等时间断蜂鸣声,闹铃时间设置为60秒。
在各个闹钟设置阶段,如果有K4按下,则相应闹钟功能关闭或开启;如在闹铃时有K4按下则提前停止闹铃。
系统仿真图如图5.1所示。
图5.1系统仿真图
6总结
通过两周的努力,完成了电子闹钟的设计目的,实现了时间的显示、校时、设置闹钟、闹铃等功能。
这期间,我复习了单片机的相关知识,并结合查阅相关资料,设计了整体电路以及各模块的电路,对照硬件电路编写对应模块的子程序,最后将各个子程序整合到一个主程序中,完成了设计所需功能。
在设计中,我发现选择合适的元器件很重要,比如数码管有共阳极和共阴极两种,不同的选择会导致程序的不同,经过多次调试最终选择了共阳极数码管。
另外,我觉得软件的设计比硬件设计更重要,而且难度更大。
比如写一个程序看其功能很少认为编写程序简单,但到编程的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。
我在这次设计中收获颇多。
我对所学的理论知识在实践中加深了认识,同时更加熟练掌握了Proteus、Keil等软件的使用。
做任何事都需要耐心和细心,一点小的疏忽和懈怠可能导致整个设计失败。
还有一点,自己的设计思路不可能凭空产生,只有借鉴别人已有的设计并充分消化吸收成为自己的东西,才能做出更好的设计作品。
参考文献
[1]王思明.单片机原理及应用系统设计[M].北京:
科学出版社,2012.
[2]陈明荧.89C51单片机课程设计实训教材[M].北京:
清华大学出版社,2003.
[3]刘瑞新.单片机原理及应用教程[M].北京:
机械工业出版社,2005.
[4]杨文龙.单片机原理及应用[M].西安:
西安电子科技大学出版社,2002.
附录
源程序清单:
//****************************头文件********************************
#include
#include
//****************************宏定义********************************
#defineucharunsignedchar
#defineuintunsignedint
//****************************位声明********************************
sbitkey1=P1^0;
sbitkey2=P1^1;
sbitkey3=P1^2;
sbitkey4=P1^3;
sbitfmq=P2^1;
//************************数码管显示的数值**************************
ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
//012345
0x82,0xf8,0x80,0x90,0xbf,0x0ff};
//6789-灭
voidjia();//定义时间加函数
voidjian();//定义时间减函数
//********************数组定义,数组内含有8个数值******************
uchartable1[8],table2[8],table3[8],table4[8];
//**************************时间显示初始值**************************
ucharshi=12,fen=0,miao=0;
//**************************定义全局变量****************************
ucharshi1,fen1,miao1,shi2,fen2,miao2,shi3,fen3,miao3;
ucharshi4,fen4,miao4;
ucharflag,flag1,wss,cnt,cnt1,alm1,alm2,alm3;
//1秒等时位闪次数校时闹1闹2闹3
uintflag2;
//蜂鸣
//*********************延时函数,用于动态扫描数码管*****************
voiddelay(uchari)
{ucharx,y;
for(x=i;x>0;x--)
for(y=120;y>0;y--);
}
//*******************************初始化函数*************************
voidinit()
{TMOD=0x01;//工作方式1
TH0=0x3c;//定时时间为:
50ms(65536-50000)/256
TL0=0x0b0;//(65536-50000)%256
ET0=1;//打开定时器
EA=1;//开总中断
TR0=1;//启动定时器
}
//********************显示子函数,用于显示时间数值*****************
voiddisplay()
{uchari,j;
if(cnt!
=10||wss==0)
{table1[0]=miao%10;//分离秒的个位与十位
table1[1]=miao/10;
}
else
{table1[0]=table1[1]=11;}
if(cnt!
=11||wss==0)
{table1[3]=fen%10;//分离分的个位与十位
table1[4]=fen/10;
}
else
{table1[3]=table1[4]=11;}
if(cnt!
=12||wss==0)
{table1[6]=shi%10;//分离时的个位与十位
table1[7]=shi/10;
}
else
{table1[6]=table1[7]=11;}
table1[2]=table1[5]=10;
j=0x7f;
for(i=0;i<=7;i++)//从秒到时的扫描
{P3=j;//选通点亮八个数码管
P0=table[table1[i]];//显示数值
delay(10);//调用延时程序
j=_cror_(j,1);//循环右移
}
}
//*******************显示子函数,用于显示定时1时间*****************
voiddisplay1()
{uchari,j;
if(alm1==0)
{if(cnt!
=1||wss==0)
{table2[0]=miao1%10;//分离秒的个位与十位
table2[1]=miao1/10;
}
else
{table2[0]=table2[1]=11;}
if(cnt!
=2||wss==0)
{table2[3]=fen1%10;//分离分的个位与十位
table2[4]=fen1/10;
}
else
{table2[3]=table2[4]=11;}
if(cnt!
=3||wss==0)
{table2[6]=shi1%10;//分离时的个位与十位
table2[7]=shi1/10;
}
else
{table2[6]=table2[7]=11;}
}
else
table2[0]=table2[1]=table2[3]=table2[4]=table2[6]=table2[7]=10;
table2[2]=table2[5]=10;
j=0x7f;
for(i=0;i<=7;i++)//从秒到时的扫描
{P3=j;//选通点亮八个数码管
P0=table[table2[i]];//显示数值
delay(10);//调用延时程序
j=_cror_(j,1);//循环右移
}
}
//********************显示子函数,用于显示定时2时间******************
voiddisplay2()
{uchari,j;
if(alm2==0)
{if(cnt!
=4||wss==0)
{table3[0]=miao2%10;//分离秒的个位与十位
table3[1]=miao2/10;
}
else
{table3[0]=table3[1]=11;}
if(cnt!
=5||wss==0)
{table3[3]=fen2%10;//分离分的个位与十位
table3[4]=fen2/10;
}
else
{table3[3]=table3[4]=11;}
if(cnt!
=6||wss==0)
{table3[6]=shi2%10;//分离时的个位与十位
table3[7]=shi2/10;
}
else
{table3[6]=table3[7]=11;}
}
else
table3[0]=table3[1]=table3[3]=table3[4]=table3[6]=table3[7]=10;
table3[2]=table3[5]=10;
j=0x7f;
for(i=0;i<=7;i++)//从秒到时的扫描
{P3=j;//选通点亮八个数码管
P0=table[table3[i]];/显示数值
delay(10);//调用延时程序
j=_cror_(j,1);//循环右移
}
}
//***************显示子函数,用于显示定时3时间数值****************//
voiddisplay3()
{uchari,j;
if(alm3==0)
{if(cnt!
=7||wss==0)
{table4[0]=miao3%10;//分离秒的个位与十位
table4[1]=miao3/10;
}
else
{table4[0]=table4[1]=11;}
if(cnt!
=8||wss==0)
{table4[3]=fen3%10;//分离分的个位与十位
table4[4]=fen3/10;
}
else
{table4[3]=table4[4]=11;}
if(cnt!
=9||wss==0)
{table4[6]=shi3%10;//分离时的个位与十位
table4[7]=shi3/10;
}
else
{table4[6]=table4[7]=11;}
}
else
table4[0]=table4[1]=table4[3]=table4[4]=table4[6]=table4[7]=10;
table4[2]=table4[5]=10;
j=0x7f;
for(i=0;i<=7;i++)//从秒到时的扫描
{P3=j;//选通点亮八个数码管
P0=table[table4[i]];//显示数值
delay(10);//调用延时程序
j=_cror_(j,1);//循环右移
}
}
//***********************时间子函数*****************************//
voidshijian()
{if(flag>=20)//判断是否到一秒
{wss=~wss;
flag=0;//到了,则标志位清零
if(cnt1!
=0)
{miao4++;//秒加1
if(miao4>59)//判断秒是否到60s
{miao4=0;//到了,则清零
fen4++;//分加1
if(fen4>59)//判断分是否到1min
{fen4=0;//到了,则清零
shi4++;//时加1
if(shi4>23)//判断时是否到24h
shi4=0;//到了,则清零
}
}
}
else
{miao++;//秒加1
if(miao>59)//判断秒是否到60s
{miao=0;//到了,则清零
fen++;//分加1
if(fen>59)//判断分是否到1min
{fen=0;//到了,则清零
shi++;//时加1
if(shi>23)//判断时是否到24h
shi=0;//到了,则清零
}
}
}
}
}
//**************************键盘扫描子函数************************//
voidkey_scan()
{if(key1==0)
{while(!
key1)//防止掉显
{if(cnt==1||cnt==2||cnt==3)
{display1();}//key1按了1、2、3次,调用闹钟1子程序
if(cnt==4||cnt==5||cnt==6)
{display2();}//key1按了4、5、6次,调用闹钟2子程序
if(cnt==7||cnt==8||cnt==9)
{display3();}//key1按了7、8、9次,调用闹钟3子程序
if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13)
{display();}//key1按了10、11、12、13次,调用计时子程序
}
cnt++;//记下按键key1按下的次数
if(cnt==10&&cnt1==0)
{miao4=miao;
fen4=fen;
shi4=shi;
cnt1++;
}
if(cnt==13)
{cnt=0;
if(cnt1==1)
{miao=miao4;
fen=fen4;
shi=shi4;
}
cnt1=0;
}
}
if(key2==0)//判断key2是否按下
{while(!
key2)//防止掉显
{if(cnt==1||cnt==2||cnt==3)
{display1();}
if(cnt==4||cnt==5||cnt==6)
{display2();}
if(cnt==7||cnt==8||cnt==9)
{display3();}
if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13)
{display();}
}
jia();//调用加1子函数
}
if(key3==0)//判断key3是否按下
{while(!
key3)//防止掉显
{if(cnt==1||cnt==2||cnt==3)
{display1();}
if(cnt==4||cnt==5||cnt==6)
{display2();}
if(cnt==7||cnt==8||cnt==9)
{display3();}
if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13)
{display();}
}
jian();//调用减1子函数
}
if(key4==0)//判断key4是否按下
{while(!
key4)//防止掉显
{if(cnt==1||cnt==2||cnt==3)
{alm1=~alm1;
display1();
}
if(cnt==4||cnt==5||cnt==6)
{alm2=~alm2;
display2();
}
if(cnt==7||cnt==8||cnt==9)
{alm3=~alm3;
display3();
}
if(cnt==0||cnt==10||cnt==11||cnt==12||cnt==13)
display();
}
}
}
//****************************加1子函数***************************
voidjia()
{if(cnt==1)//判断key1按下的次数是否为1
{miao1++;//是,则秒加1
if(miao1>59)//判断秒是否大于60,是,则秒清零
miao1=0;
}
if(cnt==2)//判断key1按下的次数是否为2
{fen1++;//是,则分加1
if(fen1>59)//判断分是否大于60
fen1=0;//是,则分清零
}
if(cnt==3)//判断key1按下的次数是否为3
{shi1++;//是,则时加1
if(shi1>23)//判断时是否大于23
shi1=0;//是,则时清零
}
if(cnt==4)//判断key1按下的次数是否为4
{miao2++;//是,则秒加1
if(miao2>59)//判断秒是否大于60,是,则秒清零
miao2=0;
}
if(cnt==5)//判断key1按下的次数是否为5
{fen2++;//是,则分加1
if(fen2>59)//判断分是否大于60
fen2=0;//是,则分清零
}
if(cnt==6)//判断key1按下的次数是否为6
{shi2++;//是,则时加1
if(shi2>23)//判断时是否大于23
shi2=0;//是,则时清零
}
if(cnt==7)//判断key1按下的次数是否为7
{miao3++;//是,则秒加1
if(miao3>59)//判断秒是否大于60,是,则秒清零
miao3=0;
}
if(cnt==8)//判断key1按下的次数是否为8
{fen3++;//是,则分加1
if(fen3>59)//判断分是否大于60
fen3=0;//是,则分清零
}
if(cnt==9)//判断key1按下的次数是否为9
{shi3++;//是,则时加1
if(shi3>23)//判断时是否大于23
shi3=0;//是,则时清零
}
if(cnt==10)//判断key1按下的次数是
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 电子 闹钟 设计