proteus仿真大作业数字时钟实验报告Word文件下载.docx
《proteus仿真大作业数字时钟实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《proteus仿真大作业数字时钟实验报告Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
从应用领域来看,单片机主要用来控制,所以又称为微控制器(MicrocontrollerUnit)或嵌入式控制器。
单片机是将计算机的基本部件微型化并集成在一块芯片上的微型
AT89C51是一个低功耗,高性能CMOS8位单片机,片内含4kBytesISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的AT89C51可为许多嵌入式控制应用系统提供高性价比的解决方案。
综上所诉,数字时钟设计方案采用单片机机型:
AT89C51;
计时方案设计采用单片机内部计数/定时功能,利用软件控制单片机实现数字时钟时间设置功能;
显示方案中利用单片机并行I/O端口,实现LED动态显示;
第二章数字时钟电路设计
2.1设计要求
设计并制作出具有以下功能的数字钟:
(1)自动计时,由六位LED显示器显示时、分、秒
(2)具备校准功能,可以设置当前时间。
(3)具备定时启闹功能,可以设置启闹时间,启闹10s后自动关闭闹铃
2.2数字电路模块图:
2.2模块简介:
(1)主程序函数main:
完成系统初始化,包括时钟、闹铃初始参数及初始标志的设定;
I/O端口、定时/计数器初始状态的设定:
更新显示时间,循环扫描按键,根据案件分别进行闹铃和时钟的设置管理。
(2)LED显示函数dispiay:
根据显示单元首地址显示时钟(或闹铃)时间,实现6位LED的动态显示功能。
(3)键盘检测函数keytest和查键值函数search:
这两个函数都属于键盘扫描模块,函数keytest判断是否有按键输入,函数search识别并返回行列式按键的键号。
(4)时钟设置函数ftion0:
根据用户按下0#键的次数,依次选择设置时钟的秒、分、时的修改标志位。
加1修改功能函数将根据该标志位进行时钟时间的设置修改。
(5)闹铃设置函数ftion1:
根据用户按下:
1#键的次数,依次选择设置闹铃的分、时的修改标志位。
加1修改功能函数将根据该标志位进行时钟闹铃的设
(6)加1修改功能函数cum:
用户按下2#键后,根据时钟和闹铃设置函数设置的标志位将时钟(或闹铃)相应的时、分、秒计数单元加1。
(7)闹铃判断启动函数alarm:
半段闹铃启动时间到否,若时间到,则启动闹铃,延时10s后自动关闹铃,并清除闹铃设置标志。
(8)定时器中断函数clock:
定时修改时钟参数中断服务子程序。
综上各模块功能,数字时钟设计方案采用单片机机型:
2.3系统功能操作实现
(1)键盘功能定义。
系统采用4*3矩阵键盘。
共计12个按键任务中使用了三个按键,0#、1#和2#键,其余按键为系统功能扩展预留。
0#键:
时钟参数表修改功能选择键。
按一次修改秒,按二次修改分,按三次修改小时,按四次确认修改完毕。
1#键:
闹铃时间设置功能选择键。
按一次修改分,按两次修改小时,按三次确认修改完成。
2#键:
增1功能键,每按一次该键,根据0#、1#键的选择结果将相应单元内容加1。
修改“小时”时,加到23后再加1“清零”;
修改“分”时,加到59后再加1“清零”。
(2)显示定义。
6位LED从左到右依次显示时、分、秒,采用24小时计时。
(3)系统工作流程设计
时间显示:
上电后,系统自动进入时钟显示,从00:
00:
00开始计时。
时间调整:
按下0#键,系统停止计时,进入时间设定状态,保持原有显示。
按一次修改秒表,按二次修改分,按三次修改小时,直至按四次确认修改完成,系统由设定后的时间开始计时显示。
闹铃设置/启闹/停闹:
按下1#键,数码管显示00:
00,进入闹铃设置状态。
等待键入启闹时间,按一次设置分,按两次设置小时,按三次确认设置完毕。
将启动定时启闹功能,并恢复时间显示。
当定时时间到,蜂鸣器鸣叫10s后停闹。
在闹铃设置过程中,系统继续计时。
在时间调整和闹铃设置状态下,均可以按2#键,采用增1方式修改相应的参数。
2.4方案设计元件清单
元件名称
数量
参数
名称
所属库
单片机
1
AT89C51
MCS8051
按钮
12
BUTTON
ACTIVE
晶振
12MHZ
CRYSTLE
DEVICE
电
阻
8
RES
3
电阻排
10K
RESPACK-8
电解电容
10uF/16V
GENELECT10U16V
CAPACITORS
瓷片电容
2
30pF
CERAMIC33P
或非门
-
71LS02
蜂鸣器
BUZZER
第三章Protues仿真电路
3.1绘制数字时钟电路Protues仿真原理图:
3.1.1启动ISIS7Professional软件
元件的加载:
找到原件后双击原件即可完成加载原件。
仿真电路绘制
放置元件→调整原布局→连线→绘制总线→放置网络标号
网络标号放置如下图所示。
3.1.3数字时钟原理图
连线后最终数字时钟电路原理图如下
电路检测
电路连接完毕后,单击运行按钮(如下图)检测电路是否有误,
如果电路如果无误进行软件检测。
3.2软件设计:
3.2.1运行keil软件编写程序
3.2.2编译、连接
将程序烧入单片机
3.2.4、程序运行
附录
程序:
/***************数字钟程序***************/
#pragmaSMALL
#include<
reg51.h>
absacc.h>
#defineucharunsignedchar
sbitP2_7=P2^7;
//定义蜂鸣器控制端口
/**************函数声明*************/
voiddelay(ucharx);
voiddisplay(uchar*p);
ucharkeyscan();
//扫描键盘有无键按下
ucharsearch();
//按键识别
voidalarm();
//闹钟判断启动
voidftion0();
//时钟修改
voidftion1();
//闹钟修改
voidcum();
//加1修改
/***************全局变量定义****************/
ucharclockbuf[3]={0,0,0};
//存放时钟时分秒的十进制数
ucharbellbuf[3]={0,0,0};
//存放闹钟时分秒的十进制数
ucharmsec1;
//10ms中断次数
ucharmsec2;
//1s循环次数
uchartimdata,rtimdata;
//时钟和闹钟修改位置标志
ucharcount;
//闹钟启动后10s计时单元
uchar*dis_p;
//显示缓冲区指针
bitarmbit;
//闹钟标志,为0闹钟未设定,为1已设定
bitrtimbit;
//闹钟是否启动标志,为1已启动
bitrhourbit;
//闹钟小时修改标志,为1正在修改闹钟小时
bitrminbit;
//闹钟分修改标志,为1正在修改闹钟分
bithourbit;
//时钟小时修改标志,为1正在修改时钟小时
bitminbit;
//时钟分修改标志,为1正在修改时钟分
bitsecbit;
//时钟秒修改标志,为1正在修改时钟秒
/****************主函数****************/
voidmain()
{
uchara;
armbit=0;
//清零闹钟标志位
msec1=0;
//设置10ms中断次数初值
msec2=0;
//设置1s中断次数初值
timdata=0;
//时钟内容修改位置记忆单元清零
rtimdata=0;
//闹钟内容修改位置记忆单元清零
count=0;
//闹钟启动后保持10s计时单元清零
TMOD=0x02;
//定时器T0为工作方式2
TL0=0x06;
//定时初始值为250us
TH0=0x06;
EA=1;
//中断总允许位开启
ET0=1;
//定时器0开中断
TR0=1;
//启动定时器T0
dis_p=clockbuf;
//将时钟值所在地址送入显示指针
while
(1)
a=keyscan();
//调用键盘扫描子程序
if(a==0x0f)
display(dis_p);
//无键输入调用显示程序
if(armbit==1)alarm();
//判断闹钟设定否,若设定则调用闹钟启动函数
}
else
//调用显示子函数作为延时去抖动
if(a!
=0x0f)//没有抖动,表示有键按下
a=search();
//调用查键值子函数
switch(a)
case0x00:
ftion0();
break;
//是时钟参数修改功能键,调用时钟设置子函数
case0x01:
ftion1();
//是闹钟参数修改功能键,调用闹钟设置子函数
case0x02:
cum();
//是加1功能键,调用加1修改功能子函数
default:
}
voiddelay(ucharx)
charj;
while(x--)
for(j=0;
j<
123;
j++);
//***************6位LED显示函数***************/
voiddisplay(uchar*p)
ucharbuffer[]={0,0,0,0,0,0};
uchark,i,j,temp;
ucharled[]={0x3f,0x06,0x58,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f
};
buffer[0]=p[0]/10;
buffer[1]=p[0]%10;
buffer[2]=p[1]/10;
buffer[3]=p[1]%10;
buffer[4]=p[2]/10;
buffer[5]=p[2]%10;
for(k=0;
k<
3;
k++)
{
temp=0xfe;
for(i=0;
i<
6;
i++)
P1=0xff;
//关显示
j=buffer[i];
P1=led[j];
//P1送断码
P0=~temp;
//P0对应端口低电平选位
temp<
<
=1;
delay(5);
//每一位显示延时
/**************键盘扫描函数************/
ucharkeyscan()
ucharc;
P0=0xf0;
c=P2;
c=c&
0x07;
//按键行输入为P2.0-P2.2,屏蔽无关位
return(c);
/**************查键值函数*************/
ucharsearch()
uchara,b,c,d,e;
c=0xfe;
//首列扫描字送变量c
a=0;
//首列号送a
P0=c;
//列扫描字送P0口
d=P2;
//读入P2口的行状态
if(d&
0x01==0){b=0;
}//第0行有键按下,第0行行首号送b
elseif(d&
0x02==0){b=4;
}//第1行有键按下,第1行行首号送b
elseif(d&
0x04==0){b=8;
}//第2行有键按下,第2行行首号送b
a++;
//扫描列号加1
c<
//修改列扫描字,扫描下一列
e=a+b;
//将行首号与列号相加,求键号
do{display(dis_p);
while((d=keyscan())!
=0x07);
//等待释放按键
return(e);
/***********闹钟判断启动函数*************/
voidalarm()
if((clockbuf[0]==bellbuf[0])&
&
(clockbuf[1]==bellbuf[1]))
P2_7=0;
rtimbit=1;
}//设置闹钟计时标志,时钟将进行10s计时标志
if(count==10)//判断闹钟保持10s时间到否
{
count=0;
//清除闹钟保持10s计时
P2_7=1;
//清除闹钟
armbit=0;
//清闹钟标志,否则闹钟设置将继续有效
rtimbit=0;
/*************时钟设置函数*************/
voidftion0()
TR0=0;
//关定时器
rhourbit=0;
//禁止闹钟时间参数修改,请闹钟修改标志
rminbit=0;
dis_p=clockbuf;
//将时钟缓冲区首地址送显示指针
rtimdata=0;
//清闹钟修改位置标志记录
timdata++;
//将时钟修改记录值加1
switch(timdata){
case0x01:
secbit=1;
//记录值为1,则将时钟秒修改标志置1
case0x02:
secbit=0;
minbit=0;
//记录值为2,则将时钟分修改标志置1
case0x03:
hourbit=1;
//记录值3,则将时钟时修改标志置1
case0x04:
hourbit=0;
//按4次则清时钟单元修改位置
//记录,定时器重新开启
default:
/***************闹钟设置函数**************/
voidftion1()
secbit=0;
//禁止时钟时间修改
minbit=0;
hourbit=0;
dis_p=bellbuf;
//设置闹钟显示标志
timdata=0;
//清时钟修改位置标志记录
rtimdata++;
//将闹钟修改记录值加1
switch(rtimdata)
rminbit=1;
break
;
//记录值为1,将闹钟分修改标志置1
rminbit=0;
rhourbit=1;
//记录值为2,将时钟分修改标志置1
case0x03:
//按3次则清闹钟单元修改位置记录
armbit=1;
//设置闹钟已设置标志位
//恢复时钟显示标志
break;
/*************加1修改功能函数**************/
voidcum()
if(secbit==1)
{
//时钟秒修改标志为1,秒单元内容加1
if(clockbuf[2]==59)clockbuf[2]=0;
elseclockbuf[2]++;
elseif(minbit==1)
//时钟分修改标志为1,分单元内容加1
if(clockbuf[1]==59)clockbuf[1]=0;
elseclockbuf[1]++;
elseif(hourbit==1)
//时钟小时修改标志为1,小时单元内容加1
if(clockbuf[0]==23)clockbuf[0]=0;
elseclockbuf[0]++;
elseif(rtimbit==1)
//闹钟分修改标志为1,分单元内容加1
if(bellbuf[1]==59)bellbuf[1]=0;
elsebellbuf[1]++;
elseif(rhourbit==1)
//闹钟小时修改标志为1,小时单元内容加1
if(bellbuf[0]==23)bellbuf[0]=0;
elsebellbuf[0]++;
/************定时器中断函数*************/
voidclock()interrupt1
EA=0;
//关中断
if(msec1!
=40)
msec1++;
else
//到10ms否,不到则msec1加1
if(msec2!
=100)msec2++;
//到1s否,不到则msec2加1
if(rtimbit==1)count++;
if(clockbuf[2]!
=59)clockbuf[2]++;
//到1min否,不到则clockbuf[2]加1
clockbuf[2]=0;
if(clockbuf[1]!
=59)clockbuf[1]++;
//到1h否,不到则clockbuf[1]加1
clockbuf[1]=0;
if(clockbuf[0]!
=23)
clockbuf[0]++;
//到24h否,不到则clockbuf[0]加1
elseclockbuf[0]=0;
}
}
//开中断
总结
历时一周的Protues仿真大型作业经过自己努力终于告一段落,在这次电子时钟电路大型作业仿真电路设计中自己学到了很多知识,同时对以前自己所学知识也进行了巩固,对知识的掌握更加牢固。
一周实训自己进一步认识到Protues仿真在电子电路仿真中的重要性,尤其在模拟电路、数字电路、单片机控制电路中应用方面,作为我们主要的专业课程之一,我觉得Protues仿真在单片机课程设计很有必要,而且很有意义。
在这次课程设计中,运用到了很多以前的专业知识,虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的一大收获。
另外,要做好一个课程设计,就必须做到:
在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;
要有一个清晰