基于单片C51数字钟.docx
- 文档编号:7237033
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:25
- 大小:190.53KB
基于单片C51数字钟.docx
《基于单片C51数字钟.docx》由会员分享,可在线阅读,更多相关《基于单片C51数字钟.docx(25页珍藏版)》请在冰豆网上搜索。
基于单片C51数字钟
目录
1课程设计分析·····················································2
2系统原理···························································2
2.1模块分布图·······················································2
2.2模块分析························································2
2.2.1计时模块······················································3
2.2.2显示模块······················································3
2.2.3响铃模块······················································4
2.2.4调整定时模块··················································4
3程序设计···························································6
3.1主程序···························································6
3.2计时程序·························································7
3.3显示程序·························································8
3.4调整定时程序·····················································9
3.5响铃程序·························································10
4功能实现···························································11
5心得体会···························································11
6参考文献···························································13
7附录································································13
1课程设计分析
课程设计题目:
定时闹钟的设计
课程设计目的:
在了解定时闹钟原理的基础上,通过编写合适的软件程序,在单片机上实现定时、计数、闹钟等功能。
在程序编写的过程中进一步了解各模块功能实现的方法,熟悉各种中断的调用,对所学知识进行巩固,并通过实地操作对各功能实现的代码加深理解。
为以后代码的编写与实际应用打下基础。
课程设计任务:
基于C51单片机设计定时闹钟。
设计要求和指标:
1.正确显示时、分;
2.利用按钮调整时间和设定闹钟时间;
3.到达设定的闹钟时间,蜂鸣器发出“滴、滴、滴”报警声;
4.通过串口在PC机上设定时间和闹钟。
2系统原理
2.1模块分布图:
图2.1模块分布图
2.2模块分析
定时闹钟是一个“时”,“分”,“秒”显示的计时装置。
由于本试验箱只有四个数码管,所以要求显示时间的时和分。
它的计时周期为24小时,显示满刻度为23时59分59秒,同时有校时功能和闹钟功能。
2.2.1计时模块:
在本设计中采用单片机内部的定时/计数器0计数,通过预置计数初值,溢出产生10ms的中断。
T=(12/fosc)*(2^16-a)s
计算得出a=56320=0xdc00
所以计数初值TH=0xdc,TL=0x00
每10ms产生一个溢出中断,用一个标志变量t来记录中断次数。
没中断一次t+1。
由于没有秒的显示,所以,当计时到一分钟,即中断6000次时,分钟加一。
当分钟计时到60时,零,此时,小时加一。
当小时计时到24时,清零。
2.2.2显示模块:
图2.2.1显示电路
本次设计中的数码管显示电路采用动态扫描的方式。
图中C51与8位数码管的接口电路中可知,P24到P27口作为段选码口,经过7407驱动与LED相连。
P00到P07口作为位选码口,经过7407驱动与LED的位相连。
将各个位选线直接连接在单片机的其中一个输出口,进行位扫描,完成动态的显示。
注意本设计中使用的实验箱是共阴极的数码管,所以只有当P24口到P27口输低电平时,该管被选中。
下面给出数码管显示0到10的数字时,P0口对应输出信号。
LED[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
2.2.3响铃模块:
图2.2.2蜂鸣电路
本设计中,蜂鸣器用9012三极管驱动,其基极接到RD端,当RD端为低电平时,三极管导通,蜂鸣器响,否则关断。
RD是端口P37的第二功能,因此,当时间等于设定的闹钟时间时,将P37口置为低电平,蜂鸣器响铃。
设计要求响铃三声“滴、滴、滴”。
所以,需要一个演示程序,P3^7=0时,调用延时程序,本设计中延时0.5s,响0.5s后,P3^7=1,再调用延时程序,以此为周期,重复3次,可以用for循环实现。
2.2.4调整定时模块
外部中断实现:
图2.2.4外部中断电路
在本设计的实验箱中,当S_INT0按钮按下后产生一个低电平单稳信号送单片机的INT0,所以,在此设计中,将外部中断0的触发方式定义成电平触发。
当按键按下时,产生外部中断。
按下第一次,调整时间,按下第二次设定闹钟,第三次恢复计时。
所以,需要定义一个标志变量,用来记录外部中断的次数。
当第一次或第二次按下S_INT0键时,均需要停止计数,所以,将定时/计数器0的启动位置0,停止计数,当第三次按下时,恢复计时,将定时/计数器0的启动位置1。
在调整时间或者设定闹钟时,都需要对所显示的时和分进行修改。
所以,要用到P20
到P23口的按键。
图2.2.3按键电路
当按下某按键时,该口信号为0,此时对时或分进行加一或者减一,重复操作,直至所需要的时间。
然后进入正常计时。
串行口实现:
图2.2.4串行口通信电路
这部分电路可以完成PC机跟单片机的串行通讯,也可以完成两个单片机进行串行通讯。
D_RXD和D_TXD指示收和发线上是否有信号,当通信时可观察到二灯闪烁。
当选择USB转URAT电路时,PC机的USB口同时承担给实验板供电的任务。
当单片机接收到PC机串行口发送来的数据时,将其显示在数码管上。
但是显示时还是分,这个必须通过程序来设定。
我们规定,第一次接收的数据显示在时的两位,第二次显示在分的两位,第三次设定闹钟的时,第四次设定闹钟的分。
3程序设计
3.1主程序
图3.1主程序流程图
系统上电复位以后,单片机内部首先开始执行初始化程序,开中断,并且启动定时/计数器0,载入定时初值后,开始计数。
同时将系统设定的显示初值送入数码管进行显示。
在主程序中,不停地调用显示子程序和计时子程序。
主程序:
while
(1)//显示、计时
{
display_time();
timecount();
u1();u2();
ring();
}
}
voidmain(void)
{
IE=0x93;//开3个中断
TH0=0xdc;//载入计数初值
TL0=0x00;
TR0=1;//启动T0
IT0=1;
TMOD=0x01;//选择定时器工作方式1
SCON=0x50;
PCON=0x00;
3.2计时程序:
T0中断入口
预置计数初值
标识变量+1
标识变量=6000吗?
N
Y
标识变量=0
分计数+1
计数加1
分计数=60吗?
N
Y
时计数=24吗?
N
Y
中断返回
图3.2计时程序流程图
voidt()interrupt1
//定时器0用于计时
{
TH0=0xdc;
TL0=0x00;
t++;
if(t==6000)
{
min++;
t=0;
if(min==60)
if(min==60)//计时1小时
{
hour++;
min=0;
if(hour==24)
hour=0;
}
}
}
{
TH0=0xdc;
TL0=0x00;
t++;
if(t==6000)//计时1分钟
{
min++;
t=0;
3.3显示程序
开始
N
Y
图3.3显示程序流程图
voidf_time(void)//分离时分的十位、个位
{
a=hour/10;//当前时间小时十位
b=hour%10;//当前时间小时个位
c=min/10;//当前时间分钟十位
d=min%10;//当前时间分钟个位
voiddisplay_time(void)
//显示当前时间函数
{
unsignedchari;
f_time();
while
(1)
{
for(i=0;i<4;i++)
{
switch(i)
{
case0:
P2=0xEF;P0=LED[a];break;
case1:
P2=0xDF;P0=LED[b];break;
case2:
P2=0xBF;P0=LED[c];break;
case3:
P2=0x7F;P0=LED[d];break;
default:
break;
}
delay
(1);
}
}
}
3.4调整定时程序
外部中断实现:
图3.4.2调整定时流程图
图3.4.1外部中断流程图
voidchange_time()interrupt0
{
flag++;
if(flag==1||flag==2)TR0=0;
if(flag==3)
{
TR0=1;flag=0;
}
}
voidu1()//调节时间
{
if(flag==1&&P2^0==0)
{
hour++;
if(hour==24)hour=0;
}
if(flag==1&&P2^1==0)
{
min++;
if(min==60)
min=0;
}
}
voidu2()//调节闹钟
{
if(flag==2&&P2^0==0)
{
chour++;
if(chour==24)chour=0;
}
if(flag==2&&P2^1==0)
{
cmin++;
if(cmin==60)
cmin=0;
}
}
串行口中断实现:
voidser()interrupt4
//串口中断用于调节时间和闹铃
{
unsignedcharj;
if(RI==1)
{
RI=0;
s[j]=SBUF;
switch(j)
{
case0:
hour=s[0];break;//第一次接收的数据设定时
case1:
min=s[1];break;//第二次接收的数据设定分
case2:
chour=s[2];break;//第三次接收的数据设定闹钟时
case3:
cmin=s[3];break;//第四次接收的数据设定闹钟分
default:
break;
}
j++;
if(j==4)
j=0;//传送完毕
}
}
3.5响铃程序
voidring()//闹钟响函数
{
unsignedchary;
f_time();f_clock();
if((ca==a)&&(cb==b)&&(cc==c)&&(cd==d))
{
for(y=0;y<3;y++)
{
P3_7=0;delay(500);
P3_7=1;delay(500);
}
}
4功能实现
程序输入完成后,进行调试和编译。
软件调试要很耐心、很细心的,同时要掌握一定的技巧。
遇到的问题可能是程序书写问题,也可能是逻辑错误。
要耐心地检查。
往往Keil软件只能检查出书写问题,对于功能实现的一些逻辑性的问题,是检查不出来。
所以,一定要认真地耐心地调试。
可以分模块进行功能调试,这样可以锁定目标纠错。
对于变量类型的定义,一定要认真分析。
原则上是能用字符类型的就不用整型的,能用长整型就不用浮点型。
需要注意的是,使用的变量不能超过所定义的类型范围,如果超过类型的赋值,软件编译是不会报错的,但是运行会出错。
程序编译成功后,可以将.hex文件烧写入单片机中。
从而完成功能的硬件实现。
同理,将文件烧入串行口调试助手软件中,用PC机进行数据发送。
5心得体会
本次的课程设计收获颇多,我达到了预期的目标和要求。
我和我的合作伙伴成功地完成了软件和硬件的测试,并且实现了所有的功能。
在此过程中,通过实践操作,进一步加深了对课本内容的理解。
并且掌握了编程语言与实际电路结合的设计方法。
在先前学习电子技术基础数字部分时,我们做了数字钟的课程设计,是用面包板等硬件实现各分的功能,而各部件间都得用导线连接,实现非常复杂。
而本学期学习单片机,将所有的功能用软件程序实现,再烧写到单片机中,就可以将所有功能集成在一块芯片上实现。
节省了很多硬件材料,在功能实现上,可以只需要修改程序,可以避免了拆除电路带来的麻烦。
在学习课本知识时,单纯的学习理论知识,了解单片机的内部结构及各部分的功能,以及实现方法。
都是纯理论性的知识,这次课程设计让我第一次有了用软件程序来实现硬件功能的经历,并且很有成就感。
在设计的过程中,我们遇到了很多障碍。
整个过程跌宕起伏。
起初,我们根据设计要求自己编写程序,在电脑上编译成功后就没再花心思去看。
而在实验箱上测试的时候,却一个功能也实现不了。
数码管不停地闪,同时蜂鸣器一直在响。
也不计时,外部中断和串行口中断也不能实现。
我们反复检查自己的程序,没有发现错误,编译也是成功的,我们变得手足无措。
最后到验收的时候,被逼无奈,于是参考同学的程序,修改自己的程序,但是主要设计思想已经不再是我们原本的设计初衷。
验收时,老师告诫我们,结果是次要的,重在编写代码的过程,是一个把理论运用于时间的过程,是对知识巩固的过程,结果可以复制,但是过程只有自己可以体会。
所以,我们决定按照自己的思路继续我们的设计。
最后,我们在与别人的交流中,明白了检查代码功能要分模块进行,不然即使有错误也不知道实在哪个环节出了问题。
于是我们一个模块一个模块的测试,最后,终于发现了问题所在,而最关键,最致命的错误就是变量的类型定义错误。
使用的变量超出了定义类型的范围,这在编译过程中不会被纠错,也不会被警告,但是硬件功能就是实现不了。
这就叫做细节决定成败。
所以,编写代码要分模块检验,并且要耐心地对细节进行检查。
这个过程是对我们能力、耐心和毅力的极大考验。
有时候,我们两个人都很郁闷,明明编译成功,可就是实现不了,还是不知道问题出在哪里。
有无助有绝望,曾经几乎放弃,直接参考别人程序,可是,最后我们还是成功地,靠自己成功地实现了所有功能,当然这其中有老师的教诲和鼓励,有同学们的指点。
几经周折,当每一个功能都顺利实现的那一刻,我们俩击掌相会慰藉,心中的激动和喜悦不言而喻。
在此次课程设计中,我体会到了,遇到问题、发现问题、想办法解决问题,最后取得成功的喜悦!
并且让我深深地感受到同班之间合作的重要性。
更重要的是,我知道了,程序设计本身就是细活,需要耐心和信心。
在想要放弃的时候,在坚持一下,找同学们交流交流,或者向老师请教,就一定会成功的。
在此,我感谢我们的老师,让我体会到靠自己努力设计的过程,感谢我们的同学们,给我提供的指导性的建议,感谢我的合作伙伴与我同甘共苦,共同进退,一起努力,一起享受成功的喜悦!
此次设计让我受益匪浅!
6参考文献
[1]田希晖、薛亮儒,C51单片机技术教程,人民邮电出版社。
[2]张友德、赵志英、涂时亮,单片微型机(第五版),复旦大学出版社。
[3]王为青、程国钢,单片机KeilCx51应用开发技术,人民邮电出版社。
[4]何坤金、丁海军,程序设计基础(C语言),北京航空航天出版社。
7附录:
定时闹钟程序
#include
unsignedcharcodeLED[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f};
unsignedchara,b,c,d,hour,min,flag;
intt;
//定义当前时间参量
unsignedcharchour,cmin,ca,cb,cc,cd;
//定义闹钟参量
unsignedchars[4];//串口需要的数组
sbitP3_7=P3^7;
voiddelay(unsignedcharx)
{
unsignedcharn1,n2;
for(n2=x;n2>0;n2--)
for(n1=125;n1>0;n1--);
}
//x=1为延时1ms。
voidf_time(void)//分离时、分的个位和十位
{
a=hour/10;//当前时间小时十位
b=hour%10;//当前时间小时个位
c=min/10;//当前时间分钟十位
d=min%10;//当前时间分钟个位
}
voiddisplay_time(void)//显示当前时间函数
{
unsignedchari;
f_time();
while
(1)
{
for(i=0;i<4;i++)
{
switch(i)
{
case0:
P2=0xEF;P0=LED[a];break;
case1:
P2=0xDF;P0=LED[b];break;
case2:
P2=0xBF;P0=LED[c];break;
case3:
P2=0x7F;P0=LED[d];break;
default:
break;
}
delay
(1);
}
}
}
voidt0()interrupt1//定时器0用于计时
{
TH0=0xdc;
TL0=0x00;
t++;
}
voidtimecount()
{
if(t==6000)
{
min++;
t=0;
if(min==60)
{
hour++;
min=0;
if(hour==24)
hour=0;
}
}
}
voidchange_time()interrupt0//外部中断0
{
flag++;//标识变量记录中断次数
if(flag==1||flag==2)
TR0=0;
if(flag==3)
{
TR0=1;
flag=0;
}
}
voidu1()//调节时间
{
if(flag==1&&P2^0==0)
{
hour++;
if(hour==24)hour=0;
}
if(flag==1&&P2^1==0)
{
min++;
if(min==60)
min=0;
}
display_time();
}
voidu2()//调节闹钟
{
if(flag==2&&P2^0==0)
{
chour++;
if(chour==24)chour=0;
}
if(flag==2&&P2^1==0)
{
cmin++;
if(cmin==60)
cmin=0;
}
display_clock();
}
voidser()interrupt4//串口中断用于调节时间和闹铃
{
unsignedcharj;
if(RI==1)
{
RI=0;
s[j]=SBUF;
switch(j)
{
case0:
hour=s[0];break;
case1:
min=s[1];break;
case2:
chour=s[2];break;
case3:
cmin=s[3];break;
default:
break;
}
display_time();
j++;
if(j==4)
j=0;
}
}
voidring()//闹钟响函数
{
unsignedchary;
f_time();
f_clock();
if((ca==a)&&(cb==b)&&(cc==c)&&
(cd==d))
{
for(y=0;y<3;y++)
{
P3_7=0;
delay(500);
P3_7=1;
}
}
}
voidmain(void)
{
IE=0x93;//开3个中断
TH0=0xdc;
TL0=0x00;
TR0=1;//启动T0
IT0=1;
TMOD=0x01;
SCON=0x50;
PCON=0x00;
while
(1)
{
display_time();
timecount();
u1();u2();
ring();
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片 C51 数字