最新基于51单片机的定时闹钟设计.docx
- 文档编号:24135352
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:35
- 大小:1.92MB
最新基于51单片机的定时闹钟设计.docx
《最新基于51单片机的定时闹钟设计.docx》由会员分享,可在线阅读,更多相关《最新基于51单片机的定时闹钟设计.docx(35页珍藏版)》请在冰豆网上搜索。
最新基于51单片机的定时闹钟设计
基于51单片机的定时闹钟设计
1系统设计………………………………………………………………1
1.1实验箱主要组件…………………………………………………………………………1
1.2系统框图及说明…………………………………………………………………………3
1.3系统软件设计……………………………………………………………………………3
1.3.1C51的编程基础……………………………………………………………………3
1.3.2系统软件设图……………………………………………………………………4
1.3.3部分复杂函数流程图……………………………………………………………5
2系统仿真………………………………………………………………6
2.1仿真软件…………………………………………………………………………………6
2.2仿真结果…………………………………………………………………………………7
3结论……………………………………………………………………7
3.1本课程设计的主要特点及贡献…………………………………………………………7
3.2改善建议…………………………………………………………………………………7
3.3自我体会…………………………………………………………………………………8
参考文献…………………………………………………………………9
附录……………………………………………………………………10
1单片机定时闹钟程序源代码……………………………………………………………10
2仿真软件ProteusISIS使用方法简单介绍……………………………………………20
3.1本课程设计的主要特点及贡献…………………………………………………………7
1系统设计
1.1实验箱主要组件
本课程设计使用的是河海大学常州校区刘玉宏老师设计的单片机课程实验箱中的“基础型实验”部分。
该部分主要由单片机最小系统,LED数码管显示部分,外部中断控制部分,独立式与行列式键盘按键输入部分,串行口通信部分,蜂鸣器与继电器等部分组成。
详细电路图见图1。
单片机最小系统部分由内含FLASHROM的STC89C52RC,EA接高电平;各并行口都加了10K的上拉电阻;晶振为11.0592M。
设置了上电复位和手动复位。
LED数码管显示部分由4位一体的数码管LED1、单个数码管LED2和8个独立的发光二极管L1—L7组成,都是共阴结构并联在一起接在单片机的P0口上。
LED1用于完成LED动态显示,用于本课程设计的时间显示,各个位选线为P2.4—P2.7,段码由P0口输出。
行列式和独立式键盘按键输入部分主要由P2.0-P2.3为行,P2.4-P2.7为列构成的4*4行列式键盘,K20-K27构成的独立式按键构成。
本课程设计中使用K20-K27构成的独立式按键,分别接在P2.0-P2.7上,当按键按下时,对应的口线输入0,同时相应的LED点亮。
蜂鸣器部分采用9012三极管驱动,其基极接到RD端,当RD端为低电平时,三极管导通,蜂鸣器响,否则关断。
串行口通信部分主要由USB转URAT电路构成,本课程设计中由此部分完成PC机与单片机的串行口通信,同时PC机的USB口同时承担给实验板供电的任务。
实验箱“基础型试验”其他电路部分介绍略,“基础型实验”部分实物图见图2。
图2实验箱“基础型实验”部分实物图
1.2系统框图及说明
本课程设计中的基于52单片机的定时闹钟系统主要由单片机最小系统模块,数码管译码和显示模块,键盘控制模块,串口通信模块,蜂鸣器模块等组成,系统框图见图3,其中箭头表示数据传送的方向。
1.3系统软件设计
1.3.1C51编程基础
由于本课程设计硬件模块主要依靠刘玉宏老师设计的单片机实验箱,所以本课程设计的重点放在在定时闹钟的软件设计上。
本课程设计的系统软件设计采用C语言,C语言是一种通用的程序设计高级语言,其代码利用率高,数据类型及运算符丰富,并具有良好的程序结构,适用于各种应用的程序设计,是目前使用较为广泛的单片机编程语言。
使用C语言对单片机进行编程具有以下优点:
(1)C51管理内部寄存器和存储器的分配,编程时,无需考虑不同存储器的寻址和数据类型等细节问题。
(2)程序由若干函数组成,具有良好的模块化结构。
(3)有丰富的子程序库可以直接使用,从而减少用户编程的工作量。
(4)C语言和汇编语言可以交叉使用,提高开发效率。
本课程设计采用的C语言编译器为KeilC51,该编译器以其代码紧凑和使用方法方便的特点优于其他编译器。
KeilC51开发单片机程序的大致步骤为:
输入源程序,新建工程,工程详细设置,源程序编译到目标代码文件等。
编译完成后通过少些软件和串口,可以将代码烧进单片机内部的FLASH程序存储器内。
1.3.2系统软件设计框图
单片机定时闹钟系统由多个函数构成,其中包括主函数,初始化函数,延时函数,键盘扫描函数等,图4为单片机定时闹钟软件系统各个函数框图。
图4单片机定时闹钟软件系统各个函数框图
1.3.3部分复杂函数流程图
键盘扫秒函数相对比较复杂,同时该函数也本课程设计中相对较为重要的一个函数,在设计中,我们使用到了四个按键,分别是K20、K21、K22、K23,其功能分别是,K21为调整时间/回复计时模式控制键,K20为调时/调闹钟时间模式控制按键,K22与K23分别为时间调整中加1与减1功能按键。
通过四个按键的配合使用,可以完成停止计时,修改时间,显示闹钟时间,修改闹钟时间等功能。
键盘扫描函数设计流程图如图5,同时图5也可以作为单片机定时闹钟实现功能操作的流程图。
图5键盘扫描函数流程图
另外在设计中,我们增加了一个新的功能,即通过串口在PC机上设定时间和闹钟,具体由程序中的串口通信函数实现。
利用PC上的串口调试助手软件向单片机一次性传送4个十六进制数依次作为调整时间的小时,调整时间的分,设定闹钟的小时,设定闹钟的分。
系统中串口通信函数的流程图见图6。
图6串口通信函数流程图
2系统仿真
2.1仿真软件
为了更好的验证系统软件设计的正确性,我们使用了ProteusISIS软件对系统进行了仿真。
我们使用ProteusISIS绘制了与实验向“基础型实验”部分相同的电路图,将使用Keil编译后的hex加载进入了单片机里面,结合仿真结果调整源代码,最终实现了设计要求的全部功能。
图7为我们根据本课程设计的要求结合实验箱绘制的仿真图。
2.2仿真结果
通过软件仿真和对源代码的调整,我们实现以下功能:
1、四个LED数码管从左到右显示“时时-分分”,无小数点,使用24小时计时制。
2、使用K20、K21、K22、K23、可以调整时间,设定闹钟时间,具体使用方法为:
系统复位前,按一次K20,可以显示目前所设定的闹钟时间;第一次操作时,按一次K21,停止计时,此时按一次K20,分位显示“99”,可以使用K22和K23调整分位的时间,此时再按一次K20,时位显示“99”,可以使用K22和K23调整时位的时间,此时再按K20,分位显示“88”,可以使用K22和K23设定闹钟分位的时间,再按下K20,时位显示“88”,可以使用K22和K23设定闹钟时位的时间。
调整时间和设定闹钟完成后,再按下一次K21,恢复计时。
第一次操作以后每次按K21两下进入调整时间和设定闹钟模式,再按K21一下恢复计时。
3、闹钟时间到时间到时,蜂鸣器发出“滴滴滴”闹铃声,另外,每一个整点蜂鸣器会发出“滴”的整点报时声。
4、可以通过串口在PC上设定时间和闹钟。
利用PC机上的软件串口调时助手可以和单片机定时闹钟系统进行通信。
向单片机传送“03300430”四个十六进制数以后,则此时钟时间为“03:
30”,设定的闹钟时间为“04:
30”,所以传送的四个十六进制数分别为“时间时位—时间分位—闹钟时位—闹钟分位”,需要注意的是,想单片机传送的是十六进制数而不是十进制数,在传送时应预先把时间调整为十六进制数。
3结论
3.1本课程设计的主要特点及贡献
本课程设计主要特点是利用C51编程实现基于单片机的定时闹钟,C51编程时本课程设计的核心和关键,如何编程实现定时闹钟的基本功能,如何修改和完善程序源代码,如何使源代码做到简洁可读性和可移植性强,等等都是我们在课程设计中关注的问题;本课程设计另外一个特点是利用仿真软件对单片机的定时闹钟程序进行了仿真,本次课程设计使用ProteusISIS软件进行了仿真,学习仿真软件的使用方法也是我们课程设计中很重要的一个步骤。
本课程设计主要完成了基于单片机的定时闹钟的设计,对学习和掌握单片机C语言编程有一定帮助,为日后深入学习单片机打下了一定的基础。
3.2改善建议
本课程设计中还有一些需要改善的方面:
一、按键只有四个,部分按键功能及操作过于复杂,在实际使用过程中不是特别的方便;
二、定时闹钟系统的稳定性有待提高,特别是对于用户的误操作处理能力不够强;
3.3自我体会
本通过本次课程设计,我学习到了很多,也收获了很多。
总结如下:
一、我对单片机的理论知识有了进一步的掌握,特别是对本次课程设计单片机两个比较核心的硬件扩展部分,即单片机的外接键盘,外接显示器的原理和实际应用有了熟练地理解和掌握。
二、我对单片机的C语言编程有了更深刻的认识和更扎实的掌握,虽然本次编写的源代码只有不到500行,只能算是一个很小的程序,但是这不到500行的程序,我们不断修改,不断尝试,对源代码各个模块的函数都有了一个非常深入的掌握。
三、本次课程设计,我们自学了仿真软件ProteusISIS,我们的自学能力和分析问题解决问题的能力有了提高,我们更是深刻掌握了仿真这种重要的细想方法,为以后进行较大项目的设计与开发奠定了初步的基础。
四、本次课程设计我们还体会到了团队协作精神和创新精神。
五、本次课程设计要感谢刘玉宏老师和刘艳老师对本课程设计的悉心指导。
参考文献
[1]田希晖,薛亮儒.C51单片机技术教程[M].北京:
人民邮电出版社,2007
[2]杨欣等.电子设计从零开始[M].北京:
清华大学出版社,2005
[3]刘玉宏.单片机实验和课程设计任务书[Z]
附录
1单片机定时闹钟程序源代码
#include
#include
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
#definefmqRD
sbitkey1=P2^0;//位声明//MODIFIED
sbitkey2=P2^1;
sbitkey3=P2^2;
sbitkey4=P2^3;
ucharcodetable[]={0x3f,0x06,0x5b,//数码管显示的数值
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0xbf,0x86,0xdb,//带小数点的数值
0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
voidplus();//函数声明
voidminus();
voidsint();
uchartable_1[6];//定义数组,数组内含有6个数值
uchartable_2[6];
ucharshi=1,fen=1,miao=30;//显示初始值
ucharshi1,fen1,miao1,shi2,fen2,miao2,shi3,fen3,miao3;//定义全局变量
ucharflag,flag1,flag2,cnt,cnt1,count;//定义全局变量
voiddelay(uchari)//延时函数,用于动态扫描数码管
{
ucharx,y;
for(x=i;x>0;x--)
for(y=110;y>0;y--);
}
voidinit()//初始化函数
{
TMOD=0X21;//工作方式1
TH0=(65536-50000)/256;//定时时间为:
50ms
TL0=(65536-50000)%256;
ET0=1;//打开定时器
EA=1;//开总中断
TR0=1;//启动定时器
SCON=0x50;//01010000SM1SM2=10,方式二REN=1允许接受(串口初始化)
TH1=0xFD;
TR1=1;//启动T/C1
ES=1;
}
voiddisplay()//显示子函数,用于显示时间数值
{
uchari,j;
table_1[0]=miao%10;//分离秒的各位与十位
table_1[1]=miao/10;
table_1[2]=fen%10+11;//分离分的各位与十位
table_1[3]=fen/10;
table_1[4]=shi%10+11;//分离时的各位与十位
table_1[5]=shi/10;
j=0x7f;//从秒到时的扫描
for(i=2;i<6;i++)
{
P2=j;
P0=table[table_1[i]];//显示数值
delay(10);
j=_cror_(j,1);//循环右移
}
}
voiddisplay_1()//显示子函数,用于显示定时时间
{
uchari,j;
table_2[0]=miao2%10;//以下含义同上
table_2[1]=miao2/10;
table_2[2]=fen2%10+11;
table_2[3]=fen2/10;
table_2[4]=shi2%10+11;
table_2[5]=shi2/10;
j=0x7f;
for(i=2;i<6;i++)
{
P2=j;
P0=table[table_2[i]];
delay(10);
j=_cror_(j,1);
}
}
voidshijian()//时间子函数
{
if(flag>=20)//判断是否到一秒
{
flag=0;//到了,则标志位清零
miao++;//秒加1
if(miao>=60)//判断秒是否到60s
{
miao=0;//到了,则清零
fen++;//分加1
if(fen>=60)//以下含义同上//MODIFIED
{
fen=0;
shi++;
if(shi>23)
shi=0;
}
}
}
}
voidkey_scan()//键盘扫描子函数
{
uchari;//定义局部变量
if(key1==0)//判断key1是否按下
{
while(!
key1)//防止掉显
{
if(cnt==0)
{
display();
}
if(cnt==3||cnt==4)
{
display_1();
}
if(cnt==1&&(cnt1==0||cnt1==2))
display_1();
if(cnt==2&&(cnt1==0||cnt1==2))
{display();
cnt=0;
}
if(cnt1==1&(cnt==1||cnt==2))
display();
}
cnt++;//记下按键key1按下的次数
cnt=cnt%5;
if(cnt==1&&cnt1==1)//以下含义同上
{
fen1=fen;
fen=99;
for(i=0;i<100;i++)
display();
fen=fen1;
}
if(cnt==2&&cnt1==1)
{
shi1=shi;
shi=99;
for(i=0;i<100;i++)
display();
shi=shi1;
}
if(cnt==3&&cnt1==1)
{
fen1=fen2;
fen2=88;
for(i=0;i<100;i++)
display_1();
fen2=fen1;
}
if(cnt==4&&cnt1==1)
{
shi1=shi2;
shi2=88;
for(i=0;i<100;i++)
display_1();
shi2=shi1;
}
}
if(key2==0)
{
while(!
key2)//防止掉显
{
if(cnt==0)
{
display();
}
if(cnt==3||cnt==4)
{
display_1();
}
if(cnt==1&&(cnt1==0||cnt1==2))
display_1();
if(cnt==2&&(cnt1==0||cnt1==2))
{display();
cnt=0;
}
if(cnt1==1&(cnt==1||cnt==2))
display();
}
cnt1++;
cnt1=cnt1%3;
if(cnt!
=0&&cnt1==1)//第一次按下,停止计数
TR0=0;
if(cnt1==2)
{
TR0=1;//开始计数
cnt=0;//按下次数清零
}
}
if(key3==0)//判断key3是否按下
{
while(!
key3)//防止掉显
{
if(cnt==0)
{
display();
}
if(cnt==3||cnt==4)
{
display_1();
}
if(cnt==1&&(cnt1==0||cnt1==2))
display_1();
if(cnt==2&&(cnt1==0||cnt1==2))
{display();
cnt=0;
}
if(cnt1==1&(cnt==1||cnt==2))
display();
}
plus();//调用加1的子函数
}
if(key4==0)//判断key3是否按下
{
while(!
key4)//防止掉显
{
if(cnt==0)
{
display();
}
if(cnt==3||cnt==4)
{
display_1();
}
if(cnt==1&&(cnt1==0||cnt1==2))
display_1();
if(cnt==2&&(cnt1==0||cnt1==2))
{display();
cnt=0;
}
if(cnt1==1&(cnt==1||cnt==2))
display();
}
minus();//调用减1子函数
}
}
voidplus()//加1子函数
{
if(cnt==1)//以下含义同上
{
fen++;
if(fen>59)
fen=0;
}
if(cnt==2)
{
shi++;
if(shi>23)
shi=0;
}
if(cnt==3)
{
fen2++;
if(fen2>59)
fen2=0;
}
if(cnt==4)
{
shi2++;
if(shi2>23)
shi2=0;
}
}
voidminus()//减1子函数
{
if(cnt==1)
{
fen--;
if(fen==255)
fen=59;
}
if(cnt==2)
{
shi--;
if(shi==255)
shi=23;
}
if(cnt==3)
{
fen2--;
if(fen2==255)
fen2=59;
}
if(cnt==4)
{
shi2--;
if(shi2==255)
shi2=23;
}
}
voidclock()//闹铃子函数
{
if(cnt1!
=1&&miao>=0&&miao<3)
{
if(fen2==fen)//是,在判断分是否相等
if(shi2==shi)//是,再判断时是否相等
{
flag1=0;//是,则标志位,flag1清零
while(!
(flag1==10))//判断flag1是否到20
{
fmq=0;//没有,则,继续驱动蜂鸣器响,时间约为:
1s
shijian();//调用时间子函数
display();//调用显示子函数
}
fmq=1;//关闭蜂鸣器
flag1=0;
while(!
(flag1==10))//判断flag1是否到20
{
fmq=1;//继续驱动蜂鸣器停,时间约为:
1s
shijian();//调用时间子函数
display();//调用显示子函数
}
fmq=1;
}
}
if(cnt1!
=1&&fen==0&&table_1[1]==0)
{
if(table_1[0]==0)
fmq=0;
if(table_1[0]==1)
fmq=1;
if(table_1[0]==2)
fmq=0;
if(table_1[0]==3)
fmq=1;
}
}
voidmain()
{
init();//调用初始化子函数
while
(1)
{
key_scan();//调用键盘扫描子函数
shijian();//时间子函数
clock();//闹钟子函数
//显示子函数
if(cnt==0)
{
display();
}
if(cnt==3||cnt==4)
{
display_1();
}
if(cnt==1&&(cnt1==0||cnt1==2))
display_1();
if(cnt==2&&(cnt1==0||cnt1==2))
{display();
cnt=0;
}
if(cnt1==1&(cnt==1||cnt==2))
display();
}
}
voidtime0()interrupt1//定时器0
{
TH0=(65536-50000)/256;//初值50ms
TL0=(65536-50000)%256;
flag++;//标志位
flag1++;
}
voidsint(void)interrupt4
{
unsignedchartemp;
flag2+
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最新 基于 51 单片机 定时 闹钟 设计