Proteus电子钟仿真实验高清版之欧阳育创编Word格式文档下载.docx
《Proteus电子钟仿真实验高清版之欧阳育创编Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Proteus电子钟仿真实验高清版之欧阳育创编Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。
该方案直接使用单片机并行口作为显示接口,无须外扩接口芯片,但占用资源较多,且动态扫描显示方式需占用CPU时间。
在非实时测控或单片机具有足够并行口资源的情况下可以采用。
这里采用动态显示方案。
第二章硬件描述及系统设计构思
2.1电子时钟功能模块
2.2系统硬件描述
1.控制器用AT89S51,12M晶振
2.数码管动态扫描驱动——P2口
3.数码管段码驱动——P1口
4.闹铃驱动——P1.0
5.调整键K1——P3.2(外部中断0,正常、调时、调分、调秒)
6.定时/正常切换键K2——P3.3
7.时间参数低位加1键K3——P3.4
8.时间参数高位加1键K4——P3.5
2.3系统设计构思
1.主流程是取时间参数,显示时间参数。
2.利用T0中断来完成计时、比较定时时间、驱动闹铃。
3.利用T1中断完成动态显示中,调整时间闪烁效果的定时。
4.利用外部中断0来完成调整选择功能。
5.利用外部中断1完成定时显示,当前时间显示的切换
6.K3、K4键完成时间参数的循环加1操作
2.4电子时钟电路原理图
如图为电子时钟电路原理图
第三章电子钟硬件介绍
3.1单片机的介绍
单片机也被称为微控制器(MicrocontrollerUnit),常用英文字母的缩写MCU表示单片机,它最早是被用在工业控制领域。
它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。
概括的讲:
一块芯片就成了一台计算机。
它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。
同时,学习使用单片机是了解计算机原理与结构的最佳选择。
单片机芯片
单片机是靠程序运行的,并且可以修改。
通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,这是别的器件需要费很大力气才能做到的,有些则是花大力气也很难做到的。
一个不是很复杂的功能要是用美国50年代开发的74系列,或者60年代的CD4000系列这些纯硬件来搞定的话,电路一定是一块大PCB板!
但是如果要是用美国70年代成功投放市场的系列单片机,结果就会有天壤之别!
只因为单片机的通过你编写的程序可以实现高智能,高效率,以及高可靠性!
3.2数码管的工作原理
a.七段数码管分共阳管和共阴管,使用时要注意区分,本项目使用共阳数码管。
即公共端接正极。
数码管引脚示意图如下:
b.该电路使用芯片74LS244来驱动发光两极管,74LS244芯片说明书如下,使用时注意判断芯片的引脚号,引脚示意图如下:
c.人眼的视觉暂停时间大约是0.02秒,当画面每秒变化超过24帧时,人眼会将这些快速变动的画面视作连续画面。
数码管动态显示正是利用了人的这一特性。
第四章控制系统的软件设计
4.1程序设计
本系统的软件系统主要可分为主程序、定时计数中断程序、时间调整程序、闹钟设置程序四大模块。
在程序设计过程中,加强了部分软件抗干扰措施,下面对部分模块作介绍。
/***************数字钟程序***************/
#include<
reg51.h>
#defineucharunsignedchar
sbitbuzzer=P2^7;
//定义蜂鸣器控制端口
/**************函数声明*************/
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;
//定时器1开中断
TR0=1;
//启动定时器T0
dis_p=clockbuf;
//将时钟值所在地址送入显示指针
P1=0x00;
buzzer=0;
while
(1)
a=keyscan();
//调用键盘扫描子程序
if(a==0x07)
display(dis_p);
//无键输入调用显示程序
if(armbit==1)alarm();
//判断闹钟设定否,若设定则调用闹钟启动函数
}
else
//调用显示子函数作为延时去抖动
if(a!
=0x07)//没有抖动,表示有键按下
{a=search();
//调用查键值子函数
switch(a){
case0x00:
ftion0();
break;
//是时钟参数修改功能键,调用时钟设置子函数
case0x01:
ftion1();
//是闹钟参数修改功能键,调用闹钟设置子函数
case0x02:
cum();
//是加1功能键,调用加1修改功能子函数
default:
}}}}
/***************6位LED显示函数***************/
voiddisplay(uchar*p)
{ucharbuffer[6]={0,0,0,0,0,0};
uchark,i,j,m,temp;
ucharled[]={0x3f,0x06,0x5b,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<
2;
k++)
{temp=0x01;
for(i=0;
i<
6;
i++)
j=buffer[i];
P0=~temp;
P1=led[j];
//P1送断码
temp<
<
=1;
for(m=0;
m<
100;
m++);
//每一位显示延时
//关显示
}}}
/**************键盘扫描函数************/
ucharkeyscan()
ucharc;
P0=0xf0;
c=P2;
c=c&
0x07;
//按键行输入为P2.0-P2.2,屏蔽无关位
return(c);
/**************查键值函数*************/
ucharsearch()
uchara,b,c,d,e;
//P2=0xfe;
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
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]))
{buzzer=1;
rtimbit=1;
}//设置闹钟计时标志,时钟将进行10s计时标志
if(count==10)//判断闹钟保持10s时间到否
count=0;
//清除闹钟保持10s计时
buzzer=0;
//清除闹钟
armbit=0;
//清闹钟标志,否则闹钟设置将继续有效
rtimbit=0;
}}
/*************时钟设置函数*************/
voidftion0()
if(rhourbit==1||rtimbit==1||rtimdata==1)
{secbit=0;
minbit=0;
hourbit=0;
else
TR0=0;
//关定时器
//将时钟缓冲区首地址送显示指针
timdata++;
//将时钟修改记录值加1
switch(timdata){
secbit=1;
//记录值为1,则将时钟秒修改标志置1
secbit=0;
minbit=1;
//记录值为2,则将时钟分修改标志置1
case0x03:
hourbit=1;
//记录值3,则将时钟时修改标志置1
case0x04:
//按4次则清时钟单元修改位置
//记录,定时器重新开启
/***************闹钟设置函数**************/
voidftion1()
if(secbit==1||minbit==1||hourbit==1||timdata==1)
{rhourbit=0;
rtimbit=0;
dis_p=bellbuf;
//设置闹钟显示标志
rtimdata++;
//将闹钟修改记录值加1
switch(rtimdata){
rminbit=1;
//记录值为1,将闹钟分修改标志置1
rminbit=0;
rhourbit=1;
//记录值为2,将时钟分修改标志置1
rhourbit=0;
//按3次则清闹钟单元修改位置记录
armbit=1;
//设置闹钟已设置标志位
//恢复时钟显示标志
/*************加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(rminbit==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++;
{msec1=0;
//到10ms否,不到则msec1加1
if(msec2!
=10)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;
//开中断
第五章电子时钟仿真结果
电子钟正常显示仿真:
启动闹钟:
设置定时数值:
(如图设置为10分钟)