51单片机课程设计闹钟程序设计Word格式文档下载.docx
《51单片机课程设计闹钟程序设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《51单片机课程设计闹钟程序设计Word格式文档下载.docx(25页珍藏版)》请在冰点文库上搜索。
![51单片机课程设计闹钟程序设计Word格式文档下载.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/a931237e-6aea-4a3b-8372-11582e771551/a931237e-6aea-4a3b-8372-11582e7715511.gif)
起止日期
2015
年
6
月
29
日起至
7
12
日止
课设内容和要求:
一、课程设计内容
设计一个数字显示的闹钟程序,具体内容如下:
1、闹钟能设定2个任务;
2、在数码管上显示剩余时间;
3、用发光二极管显示闹钟输出。
二、课程设计要求
1、认真查阅相关资料;
2、独立设计、调试并通过指导教师现场验收;
3、撰写课程设计报告
参考资料:
[1]张毅刚.单片机原理及应用[M].哈尔滨:
哈尔滨工业大学出版社,2008
[2]戴仙金.51单片机及其C语言程序开发实例[M].北京:
清华大学出版社,2011
[3]黄惟公.单片机原理与应用技术[M].西安:
西安电子科技大学出版社,2010
教研室审核意见:
教研室主任签字:
指导教师(签名)
日
学生(签名)
课程设计总结:
单片机是一门应用性很强的学科,课程设计是培养我们综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对我们实际工作能力的具体训练和考察过程。
虽然在做课程设计以前已经系统的把单片机课本认真的学习了一下,但是在刚拿到设计任务书时还是有点一头雾水,不知道该从哪里下手。
不过经过两周的学习,虽然过程很艰辛,但是总算实现了定时闹钟的功能,所有的努力都很值得。
这两周的大部分时间都在研究程序怎么处理,但是在这个过程中加深了我对单片机这门学科的理解,而且也学到了更多的知识。
通过这次课程设计,使我对这门功课有了更深刻的认识和了解。
使我懂得了理论与实际相结合的重要性,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,才能提高自己的实际动手能力和独立思考的能力。
其次,软件在这次设计中也有不足之处,比如闹钟无法显示剩余时间,但又不知道从哪个地方入手解决这个问题,这要求在以后的学习中,拓宽自己的知识面,解决设计的不足之处。
总之,通过这次课程设计不仅使我巩固了本课程所学的基本知识,还使我具有了撰写科研报告的初步训练能力,我相信这些能力在我以后的工作或者是再学习中一定会起到不小的作用,一切的辛苦和艰难都是值得的。
1总体设计方案
1.1课程设计的内容和要求
本设计是定时闹钟的设计,由MCS51单片机芯片和LED数码管为核心,辅以必要的电路,构成的一个单片机电子定时闹钟。
定时闹钟设计采用单片机来完成,用数码管显示“时”,“分”,“秒”。
使用MCS51系列单片机,单片机结合七段显示器设计的简易定时闹铃时钟,可以设置现在的时间、闹钟定时的时间,可以设置两个闹钟,若时间到则用发光二极管显示。
1.2课程设计原理
MCS51系列单片机内部有两个定时器,可以实现一定时间的定时,可以设置1秒的时长作为闹钟的单位时间,以此实现时钟的走时,单片机有32条I/O口线,5个中断源、一个全双工串行口等,可以通过数码管显示当前时间以及闹钟时间。
1.3课程设计思路
本设计通过设置定时器,实现时长为1秒的定时,作为时钟的单位时间,实现时钟的走时,外部按键连接到P1口,实现对时钟及闹钟的设定。
可以显示并设置两个的闹钟时间,开关功能如下:
K1:
秒调整;
K2:
分调整;
K3:
时调整;
K4:
秒归零;
K5:
时钟归零;
K6:
设置闹钟1;
K7:
按下显示闹钟设定时间,抬起显示时钟时间;
K8:
设置闹钟2。
2详细设计方案
2.1实现方法
电子闹钟应包括秒信号发生器、时间显示电路、按键电路以及闹铃指示电路等几部分。
电子闹钟的系统框图如下所示:
2.2模块设计
2.2.1主程序流程图
2.2.2中断程序流程图
2.2.2.1基本显示模块设计
基本显示模块设计的重点是由显示代码取得相应的段码,显示段码数据的并行发送,高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟,石英表,石英钟都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调校,数字式电子钟用集成电路计时时,译码代替机械式传动,用LED显示器代替显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时,分,秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。
流程图如下:
2.2.2.2时间设定模块设计
时调整。
Y
2.2.2.3闹铃功能的实现
闹铃功能的实现涉及到两个方面:
闹铃时间设定和是否闹铃判别与相应处理。
闹铃时间设定模块的设计可参照时间设定模块,这里着重阐述闹铃判别与处理模块的设计问题。
闹铃判别与闹铃处理的关键在于判别何时要进行闹铃。
当时十位、时个位、分十位、分个位、秒十位、秒个位中任一位发生改变(进位)时,就必须进行闹铃判别。
译码显示电路将“时”、“分”、“秒”计数器的输出送到七段显示译码驱动器译码驱动,通过六个七段LED显示器显示出来。
闹铃电路根据计时系统的输出状态产生一脉冲信号,然后驱动发光二极管亮。
N
3调试及结果分析
3.1调试步骤及方法
软件运行过程中,可以通过如下按键进行操作:
3.2实验结果
程序运行时,显示时钟初始值000000,闹钟初始值000100,运行后,时钟正常走时,此时按下K7,显示闹钟时间,按下K6,显示闹钟1时间,可以通过K1、K2、K3对闹钟1进行设置,抬起K6,按下K8,对闹钟2进行设置,然后抬起K7显示时钟时间,当闹钟1或闹钟2时间到达后,发光二极管亮。
参考文献
[1]张毅刚.单片机原理及应用[M].哈尔滨:
附录(源程序)
#include<
reg51.h>
absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
/*七段共阴管显示定义*/
ucharcode
dispcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0xBF,0x86,0xCB,0xCF,0xEF,0xED,0xFD,0x87,0xFF,0xDF};
/*定义并初始化变量*/
ucharxdata*p=0x8004;
ucharxdata*q=0x8002;
ucharsecond=0;
ucharminite=0;
ucharhour=0;
ucharsecond1=10;
ucharminite1=0;
ucharhour1=0;
ucharsecond2=10;
ucharminite2=0;
ucharhour2=0;
ucharmstcnt=0;
uchartmp=1;
uchartmp1=1;
sbitP1_0=P1^0;
//second调整定义
sbitP1_1=P1^1;
//minite调整定义
sbitP1_2=P1^2;
//hour调整定义
sbitP1_3=P1^3;
sbitP1_4=P1^4;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
sbitP2_0=P2^0;
sbitP2_1=P2^1;
unsignedcharalarm_flag=0;
//闹钟定时到达标志变量
/*函数声明*/
voiddelay(uchark);
//延时子程序
voidtime_pro();
//时间处理子程序
voiddisplay();
//显示子程序
voidkeyscan();
//键盘扫描子程序
voidalarm_judge(void);
//闹钟定时到达判定
voidbeep1(void);
//闹钟响铃程序
voidbeep2(void);
voidshow1(void);
voidshow2(void);
//闹钟设定显示
voidbeep1(void)
{
P2_0=!
P2_0;
delay(1000);
}
voidbeep2(void)
P2_1=!
P2_1;
/*****************************/
/*延时子程序*/
/****************************/
voiddelay(uchark){
ucharj;
while((k--)!
=0){
for(j=0;
j<
125;
j++){
;
}
/**************************/
/*时间处理子程序*/
voidtime_pro(void){
if(tmp=1){
if(second==60)//秒钟设为60进制
{second=0;
minite++;
if(minite==60)//分钟设为60进制
{minite=0;
hour++;
if(hour==24)
//时钟设为24进制
{hour=0;
}
voidtime_pro1(void){
if(tmp1==1){
if(second1==60)//秒钟设为60进制
{second1=0;
minite1++;
if(minite1==60)//分钟设为60进制
{minite1=0;
hour1++;
if(hour1==24)
{hour1=0;
voidtime_pro2(void){
if(second2==60)//秒钟设为60进制
{second2=0;
minite2++;
if(minite2==60)//分钟设为60进制
{minite2=0;
hour2++;
if(hour2==24)
{hour2=0;
/*显示子程序*/
voiddisplay()
{
if(tmp=1){
ucharcodesuccess[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,//共阴的数码管段选.将值送给P2口
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80,0x00};
ucharcodewema[]={0x20,0x10,0x08,0x04,0x02,0x01};
//位选,0-5位数码管
//while
(1)//做一个死循环,让程序永远在while下面的大括号里面运行。
{
*q=wema[0];
//位码ucharxdata*q=0x8002;
*p=success[hour/10];
delay
(1);
*q=wema[1];
*p=success[hour%10];
*q=wema[2];
*p=success[minite/10];
*q=wema[3];
*p=success[minite%10];
*q=wema[4];
*p=success[second/10];
*q=wema[5];
*p=success[second%10];
}
voiddisplay1()
if(tmp1==1){
ucharcodesuccess1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,//共阴的数码管段选.将值送给P2口
ucharcodewema1[]={0x20,0x10,0x08,0x04,0x02,0x01};
*q=wema1[0];
*p=success1[hour1/10];
*q=wema1[1];
*p=success1[hour1%10];
*q=wema1[2];
*p=success1[minite1/10];
*q=wema1[3];
*p=success1[minite1%10];
*q=wema1[4];
*p=success1[second1/10];
*q=wema1[5];
*p=success1[second1%10];
}
voiddisplay2()
ucharcodesuccess2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,//共阴的数码管段选.将值送给P2口
ucharcodewema2[]={0x20,0x10,0x08,0x04,0x02,0x01};
*q=wema2[0];
*p=success2[hour2/10];
*q=wema2[1];
*p=success2[hour2%10];
*q=wema2[2];
*p=success2[minite2/10];
*q=wema2[3];
*p=success2[minite2%10];
*q=wema2[4];
*p=success2[second2/10];
*q=wema2[5];
*p=success2[second2%10];
//******************闹钟判断函数******************************
voidalarm_judge(void)
if(hour==hour1&
&
minite==minite1&
second==second1)//定时到达设定标志1
{
beep1();
elseif(hour==hour2&
minite==minite2&
second==second2)
beep2();
voidkeyscan1(void){
if(P1_0==0)//按键1秒的调整
{
delay(100);
if(P1_0==0){
second1++;
if(second1==60){
second1=0;
if(P1_1==0)//按键2分的调整
if(P1_1==0)
minite1++;
if(minite1==60)
{minite1=0;
}}}
if(P1_2==0)//按键3小时的调整
if(P1_2==0)
hour1++;
{hour1=0;
voidkeyscan2(void){
second2++;
if(second2==60){
second2=0;
minite2++;
if(minite2==60)
{minite2=0;
hour2++;
{hour2=0;
/*******************************/
/*键盘扫描子程序*/
voidkeyscan(void){
if(tmp=1){
if(P1_3==0){
second=0;
minite=0;
hour=0;
if(P1_4==0){
second=0;
if(P1_0==0)//按键1秒的调整
second++;
if(second==60){
minite++;
if(minite==60)
{minite=0;
hour++;
{hour=0;
voidtimer0(void)interrupt1using0//定时器0方式1,50ms中断一次
TH0=0x3c;
TL0=0xb0;
TMOD=0x11;
mstcnt++;
if(mstcnt==20)
mstcnt=0;
//注意点。
对计数单元的清零十分的重要,本次调试中就是
/*闹钟设定*/
voidshow1(void)
if(P1_5==0){
tmp=0;
keyscan1();
//按键扫描
time_pro1();
//时间处理
display1();
//显示时间
tmp=1;
voidshow2(void)
if(P1_7==0){
tmp1=0;
keyscan2();
time_pro2();
display2();
tmp1=1;
/*主函数*/
/**************************/
voidmain(void){
P1=0xff;
//初始化p1口,全设为1
P2=0x00;
//初始化p2口,全设为0
//time0为定时器,方式1
//预置计数初值
EA=1;
ET0=1;
TR0=1;
while
(1){
alarm_judge();
if(P1_6==1){
keyscan();
time_pro();