情境13智能数字钟的设计与制作Word文档下载推荐.docx
- 文档编号:16972823
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:21
- 大小:195.48KB
情境13智能数字钟的设计与制作Word文档下载推荐.docx
《情境13智能数字钟的设计与制作Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《情境13智能数字钟的设计与制作Word文档下载推荐.docx(21页珍藏版)》请在冰豆网上搜索。
在任何位置再次按下闹铃键,则退出设置。
这将启动定时启闹功能,并恢复时间显示。
闹铃时间到,蜂鸣器鸣叫,直至重新按下闹铃键停闹。
软件设计
根据上述工作流程,软件设计可分为以下几个主要功能模块:
(1)主程序:
初始化与键盘监控,流程图如图13.2所示。
图13.2主程序流程图
(2)计时:
为定时器0中断服务子程序,完成刷新计时缓冲区的功能。
流程图如图13.3所示。
如前所述,系统定时采用定时器与软件循环相结合的方法。
定时器0每隔100ms溢出中断一次,则循环中断10次延时时间为1s,上述过程重复60次为1分,分计时60次为1小时,小时计时24次则时间重新回到00:
00。
设系统使用6MHz的晶振,定时器0工作在方式1,则100ms定时对应的定时器初值可由下式计算得到:
定时时间=(216-定时器0初值)×
(12/fosc),因此,定时器0初值=0x3cb0,即TH0=0x3c,TL0=0xb0。
图13.3计时程序流程图
(3)时间设置与闹钟设置:
由键盘输入设置当前时间与定时启闹时间。
流程图如图13.4所示。
将键盘输入的时间值合并为3位或2位压缩BCD码(时、分、秒)送入计时缓冲区和闹钟值缓冲区,作为当前计时起始时间或闹钟定时时间。
该模块的入口为计时缓冲区或闹钟值寄存区的首地址。
程序调用一个键盘设置子程序将键入的6位时间值送入显示缓冲区,然后将显示缓冲区中的6(或4)位BCD码合并为3(或2)位压缩BCD码,送入计时缓冲区或闹钟值缓冲区。
该程序同时作为时间值合法性检测程序,若键盘输入的小时值大于23,分和秒值大于59,则不合法,将取消本次设置。
另外为了设置时能明确当前设置位置,在等待键盘输入时,采用当前位闪烁显示提醒。
具体采用定时器1形成50ms中断,然后循环500ms显示另500ms不显示来完成。
图13.4时间设置和闹钟定时程序流程
(4)显示:
完成6位动态显示。
流程图如图13.5所示。
将显示缓冲区中的6位BCD码用动态扫描方式显示。
为此,必须首先将3字节计时缓冲区中的时、分、秒压缩BCD码拆分为6字节(百位、十位分别占有1字节)BCD码,这一功能由计时时间时分秒分拆送显示缓冲区子函数来实现。
需要注意的是,当按下时间或闹钟设置键后,在6(或4)位设置完成之前,应显示键入的数据,而不显示当前时间。
为此,我们设置了一个计时显示允许标志位,在时间/闹钟设置期间标志位1,不调用计时时间时分秒分拆送显示缓冲区子函数。
图13.5显示程序流程图
(5)键盘扫描:
判断是否有键按下,并求取键号。
流程图如图13.6所示。
图13.6键盘扫描流程图
(6)定时比较:
判断启闹时间到否?
如时间到,则启动蜂鸣器鸣叫。
流程图如图13.7所示。
图13.7定时比较流程图
将当前时间(计时缓冲区的值)与预设的启闹时间(闹钟设置寄存区的值)比较,二者完全相同时,启动蜂鸣器鸣叫,并置位闹钟标志位。
返回后,待重新按下闹铃键停闹,并清零闹钟标志。
源程序
#include<
at89x51.h>
#include<
absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
#definePORTXBYTE[0x7fff]/*8255控制口地址*/
#definePORTAXBYTE[0x7ffc]/*8255的A口地址*/
#definePORTBXBYTE[0x7ffd]/*8255的B口地址*/
#definePORTCXBYTE[0x7ffe]/*8255的C口地址*/
sbitalarm_beep=P1^0;
//闹铃驱动
sbitled1=P1^1;
sbitled2=P1^2;
ucharmsecond=0;
//时钟时间:
毫秒
ucharlocation;
//标记调整时间时位置
ucharbuffer;
//缓冲存储
uchartimes=0;
//内部计数
uchartimebuf[3]={0,0,0};
时,分,秒
ucharalarmbuf[2]={12,00};
//闹铃时间:
时,分
uchardispbuf[6]={0,0,0,0,0,0};
//显示缓冲区
bitalarm_fg=0;
//清零闹钟标志位
bittimeset_fg=0;
//允许计时显示
/*共阴极字型码表*/
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
0x40,0x00};
//01234567
//89abcdef
//-暗
/*定时器0中断服务子程序*/
/*6MHz晶振,定时100毫秒*/
voidclock(void)interrupt1
{
TL0=0xb7;
TH0=0x3c;
msecond++;
if(msecond==5){led1=~led1;
led2=~led2;
}//LED闪烁控制500ms
if(msecond==10)//1秒时间到
{
led1=~led1;
led2=~led2;
msecond=0;
timebuf[2]++;
if(timebuf[2]==60)//1分时间到
{
timebuf[2]=0;
timebuf[1]++;
if(timebuf[1]==60)//1时时间到
{
timebuf[1]=0;
timebuf[0]++;
if(timebuf[0]==24)timebuf[0]=0;
//1天时间到
}
}
}
}
/*定时器1中断服务子程序*/
voidflash(void)interrupt3
TL1=0x58;
//重置初值
TH1=0x9e;
times++;
if(times==10)//500ms时间到
buffer=dispbuf[location];
dispbuf[location]=17;
elseif(times==20)
times=0;
dispbuf[location]=buffer;
/*子函数*/
/*延时1ms*/
voiddelay()
uchari;
for(i=248;
i>
0;
i--){;
/*闹铃时间比较子程序*/
voidalarm(void)
if(timebuf[2]==0)//整分
if(timebuf[1]==alarmbuf[1])//分相同
if(timebuf[0]==alarmbuf[0])//时相同
alarm_beep=0;
//启动闹钟鸣叫
alarm_fg=1;
//置位闹钟标志
/*计时时间时分秒分拆送显示缓冲区*/
voidtime_to_disp(void)
ucharj=0;
for(i=0;
i<
3;
i++)
dispbuf[j]=timebuf[i]/10;
//取时分秒高4位
j++;
dispbuf[j]=timebuf[i]%10;
//取时分秒低4位
/*闹铃时间时分分拆送显示缓冲区*/
voidalarm_to_disp(void)
2;
dispbuf[j]=alarmbuf[i]/10;
dispbuf[j]=alarmbuf[i]%10;
/*显示子程序DISPLAY*/
voiddisplay(void)
uchari,selcode;
if(timeset_fg==0)time_to_disp();
//允须计时则刷新显示缓冲区
selcode=0xfe;
//首扫描码
6;
PORTB=0x00;
//段码送00关显示
PORTA=selcode;
//先送位选通信号
PORTB=table[dispbuf[i]];
//查表取段码
delay();
//延时1ms
selcode=(selcode<
<
1)|0x01;
//扫描显示下一数码管
/*键扫描函数*/
ucharkeyscan(void)
ucharscancode,tmpcode;
PORTB=0x00;
//关显示,消阴影
PORTA=0x00;
//发全0行扫描码
if((PORTC&
0x07)!
=0x07)//若有键按下
{
display();
//延时去抖动,以显示扫描时间做延时
alarm();
//闹铃时间比较
PORTA=0x00;
if((PORTC&
=0x07)//延时后再判断一次,去除抖动影响
{//有键按下逐行扫描
scancode=0xfe;
//首列扫描字
while((scancode&
0x10)!
=0)
PORTA=scancode;
//输出行扫描码
if((PORTC&
=0x07)//本行有键按下
{
tmpcode=PORTC|0xf8;
//保留行信息,只有该行数据位为0
tmpcode=(tmpcode<
4)|0x0f;
//行信息转换到高4位存储
/*返回特征字节码,为1的位即对应于行和列*/
do{
PORTA=scancode;
}while((PORTC&
=0x07);
//等键抬起
return((~scancode)+(~tmpcode));
}
elsescancode=(scancode<
//行扫描码左移一位
return(0);
//无键按下,返回值为0
/*主程序*/
uchargetkeynum(void)
ucharkey,keynum=0;
if((key=keyscan())!
=0)//调用键盘扫描函数
switch(key)
case0x11:
//第1行第1列
keynum=10;
//数字键0
break;
case0x21:
//第2行第1列
keynum=4;
//数字键4
case0x41:
//第3行第1列
keynum=8;
//数字键8
case0X12:
keynum=1;
//数字键1
case0X22:
keynum=5;
//数字键5
case0X42:
keynum=9;
//数字键9
case0X14:
keynum=2;
//数字键2
case0X24:
keynum=6;
//数字键6
case0X44:
keynum=11;
//校时键
case0X18:
keynum=3;
//数字键3
case0X28:
keynum=7;
//数字键7
case0X48:
keynum=12;
//闹钟时间
default:
break;
return(keynum);
/*键盘修改计时初值或闹铃时间子程序*/
voidmodify(uchardata*p,ucharnum)
uchari,buf;
ucharkey=0;
location=0;
num;
i++)//6位时间输入完否
do{TR1=1;
key=getkeynum();
display();
}while(key==0);
/*扫描键盘,并对键入数合法性检测,只有1-10*/
TR1=0;
times=0;
TL1=0x58;
TH1=0x9e;
//初始化,重要!
!
if(key==10)key=0;
//转换数字0
elseif(key>
10)break;
dispbuf[i]=key;
//键值送显示缓冲区
key=0;
//下次按键前,必须清零
location++;
buf=dispbuf[0]*10+dispbuf[1];
//时
if(buf>
23)return;
else*p=buf;
//送数据到时缓冲(计时或闹铃)
p++;
//地址调整
buf=dispbuf[2]*10+dispbuf[3];
59)return;
//送数据到分缓冲(计时或闹铃)
if(num>
4)
p++;
buf=dispbuf[4]*10+dispbuf[5];
if(buf>
else*p=buf;
//送数据到秒缓冲(计时)
/*主程序*/
voidmain(void)
{
ucharkeyin;
SP=0x50;
//设置堆栈区
PORT=0x89;
//8255初始化
alarm_beep=1;
//闹铃禁声
TMOD=0x11;
//定时器0工作在方式1,定时器1工作在方式1
TL0=0xb0;
//定时器0初始化,6MHz晶振定时时间100ms
//定时器1初始化,6MHz晶振定时时间50ms
ET0=1;
//定时器0允许中断
ET1=1;
//定时器1允许中断
EA=1;
TR0=1;
//启动定时器0
while
(1)
display();
//扫描显示
keyin=getkeynum();
//调用键盘扫描
if(keyin>
10)//是校时键或清闹键
if((keyin==12)&
&
(alarm_fg==1))
alarm_beep=1;
//闹钟正在闹响,停闹
alarm_fg=0;
//清零闹钟标志
else
led1=0;
//停止LED灯闪
led2=0;
timeset_fg=1;
//置位时间设置标志,禁止显示计时时间
if(keyin==11)
TR0=0;
//是则暂时停止计时
led1=0;
led2=0;
modify(timebuf,6);
else
alarm_to_disp();
//闹铃时分送显示缓冲前四位
dispbuf[4]=16;
dispbuf[5]=16;
modify(alarmbuf,4);
//调用时间设置/闹钟定时程序
TR0=1;
//重新开始计时
timeset_fg=0;
//清零时间设置标志,恢复显示计时时间
}//endofif(keyin>
10)
}//endofwhile
(1)
任务实施
1.利用proteus仿真软件绘制仿真电路原理图
2.C51程序的编译
按照情景一KeilC51编译软件的操作步骤对源程序进行编译和调试。
3.执行程序观察效果
将编译成功后的.HEX文件加载到CPU执行程序并软硬件联调。
4.拟制电气原理并设计印刷电路板图
假设外部仅提供9V直流电源,用Protel99完善绘制该任务详细电原理图并设计印刷电路板图。
5.书写设计报告
参考图13.8所列多功能计数器论文目录格式,将该任务完成情况整理完善形成论文。
摘要要求中英文。
图13.8多功能计数器论文目录
相关知识
1.KeilC与Proteus联合调试
(1)在KeilC中建立好项目文件以及编译成功后,单击“Project菜单/OptionsforTarget”选项或者点击工具栏的“optionfortarget”按钮
,弹出窗口,点击“Debug”按钮,出现如图所示页面。
在出现的对话框里在右栏上部的下拉菜单里选中“ProteusVSMMonitor”。
并且还要点击一下“Use”前面表明选中的小圆点。
再点击“Setting”按钮,设置通信接口,在“Host”后面添上“127.0.0.1”,如果使用的不是同一台电脑,则需要在这里添上另一台电脑的IP地址(另一台电脑也应安装Proteus)。
在“Port”后面添加“8000”。
设置好的情形如图所示,点击“OK”按钮即可。
最后将工程编译,进入调试状态,并运行。
(2)Proteus的设置
进入Proteus的ISIS,鼠标左键点击菜单“调试”,选中“使用远程调试设备”,如图所示。
打开与KeilC的工程文件所对应的图形文件,此后,便可实现KeilC与Proteus连接调试。
(3)KeilC与Proteus连接仿真调试
最后,将KeilC中的工程编译,进入调试状态,再看看Proteus,已经发生变化了。
这时再执行KeilC中的程序(单步、全速都可以,也可以设置断点等),Proteus已经在进行仿真了。
2.数码管技术资料
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 情境13 智能数字钟的设计与制作 情境 13 智能 数字 设计 制作