电子设计竞赛预赛时钟论文Word文件下载.docx
《电子设计竞赛预赛时钟论文Word文件下载.docx》由会员分享,可在线阅读,更多相关《电子设计竞赛预赛时钟论文Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
尽管其各具特色,名称各异,但作为集CPU、RAM、ROM(或EPROM)、I/O接口、定时器/计数器、中断系统为一体的单片机,其原理大同小异。
由于单片机具有体积小、重量轻、价格便宜、功耗低,控制功能强及运算速度快等特点,因而在国民经济建设、军事及家用电器等各个领域均得到了广泛的应用。
按照单片机的特点,其应用可分为单机应用与多机应用。
在一个应用系统中,只使用1片单片机称为单机应用,这是目前应用最多的一种方式。
单片机应用的主要领域有:
测控系统,智能仪表,机电一体化产品,智能接口,智能民用产品
2.2MCS—51示意图及引脚功能
MCS—51系列单片机芯片均为40个引脚,HMOS工艺制造的芯片采用双列直插(DIP)方式封装,其引脚示意及功能分类如图2―3所
图2―3MCS—51系列单片机引脚及总线结构
(a)管脚图;
(b)引脚功能分类
1.主电源引脚Vcc和Vss
VCC(40脚):
接+5V电源正端;
VSS(20脚):
接+5V电源地端。
2.外接晶体引脚XTAL1和XTAL2
XTAL1(19脚):
接外部石英晶体的一端。
在单片机内部,它是一个反相放大器的输入端,这个放大器构成了片内振荡器。
当采用外部时钟时,对于HMOS单片机,该引脚接地;
对于CHMOS单片机,该引脚作为外部振荡信号的输入端。
XTAL2(18脚):
接外部晶体的另一端。
在单片机内部,接至片内振荡器的反相放大器的输出端。
当采用外部时钟时,对于HMOS单片机,该引脚作为外部振荡信号的输入端;
对于CHMOS芯片,该引脚悬空不接
3.控制信号或与其它电源复用引脚
控制信号或与其它电源复用引脚有RST/VPD、
和
等4种形式。
(1)RST/VPD(9脚):
RST即为RESET,VPD为备用电源,所以该引脚为单片机的上电复位或掉电保护端。
(2)
(30脚):
当访问外部存储器时,ALE(允许地址锁存信号)以每机器周期两次的信号输出,用于锁存出现在P0口的低8位地址。
(3)
(29脚):
片外程序存储器读选通信号输出端,低电平有效。
(4)
(31脚):
为访问外部程序存储器控制信号,低电平有效。
4.输入/输出(I/O)引脚P0口、P1口、P2口及P3口
(1)P0口(39脚~32脚):
P0.0~P0.7统称为P0口。
(2)P1口(1脚~8脚):
P1.0~P1.7统称为P1口,可作为准双向I/O接口使用。
(3)P2口(21脚~28脚):
P2.0~P2.7统称为P2口,一般可作为准双向I/O接口。
(4)P3口(10脚~17脚):
P3.0~P3.7统称为P3口。
2.3晶振电路
单片机的定时控制功能是由片内的时钟电路和定时电路来完成的,而片内的时钟产生有两种方式:
一种是内部时钟方式;
一种是外部时钟方式,如图2―4(a)、(b)所示。
图2―4HMOS型MCS—51单片机时钟产生方式
(a)内部振荡器方式;
(b)外部振荡器方式
采用内部时钟方式时,如图2―4(a)所示。
片内的高增益反相放大器通过XTAL1、XTAL2外接作为反馈元件的片外晶体振荡器(呈感性)与电容组成的并联谐振回路构成一个自激振荡器,向内部时钟电路提供振荡时钟。
振荡器的频率主要取决于晶体的振荡频率,一般晶体可在1.2~12MHz之间任选,电容C1、C2可在5~30pF之间选择,电容的大小对振荡频率有微小的影响,可起频率微调作用。
2.4复位电路
通过某种方式,使单片机内各寄存器的值变为初始状态的操作称为复位。
MCS-51单片机的复位是由外部的复位电路来实现的。
复位引脚RST通过一个斯密特触发器与复位电路相连,斯密特触发器用来抑制噪声,在每个机器周期的S5P2,斯密特触发器的输出电平由复位电路采样一次,然后才能得到内部复位操作所需要的信号MCS—51单片机在时钟电路工作以后,在RST/VPD端持续给出2个机器周期的高电平就可以完成复位操作(一般复位正脉冲宽度大于10ms)。
复位分为上电复位和外部复位两种方式。
图2―12MCS—51单片机复位参考电路
(a)上电复位电路;
(b)上电/外部复位电路
。
上电复位:
上电复位电路是—种简单的复位电路,只要在RST复位引脚接一个电容到VCC,接一个电阻到地就可以了。
上电复位是指在给系统上电时,复位电路通过电容加到RST复位引脚一个短暂的高电平信号,这个复位信号随着VCC对电容的充电过程而回落,所以RST引脚复位的高电平维持时间取决于电容的充电时间。
为了保证系统安全可靠的复位,RST引脚的高电平信号必须维持足够长的时间。
3硬件设计及描述
3.1总体设计
电子闹钟应包括秒信号发生器、时间显示电路、按键电路、供电电源以及闹铃指示电路等几部分。
单片机采用STC89C52型。
电子闹钟的系统框图如下所示:
图1
电子闹钟的主电路指的是图1中虚线框内部分,主要涉及到CPU电路和按键按钮电路。
主机的设计具体地说有:
1)系统时钟电路设计;
2)系统复位电路设计;
3)按键与按钮电路设计;
4)闹铃声指示电路设计。
3.2系统时钟电路设计
对于时间要求不是很高的系统,只要按图进行设计就能使系统可靠起振并稳定运行。
但由于原理图中的C1、C2电容起着系统时钟频率微调和稳定的作用,因此,在本闹钟系统的实际应用中一定要注意正确选择参数(30±
10PF),并保证对称性(尽可能匹配),选用正牌厂家生产的瓷片或云母电容,如果可能的话,温度系数要尽可能低。
实验表明,这2个电容元件对闹钟的走时误差有较大关系。
3.3系统复位电路的设计
智能系统一般应有手动或上电复位电路。
复位电路的实现通常有两种方式:
1)RC复位电路;
2)专用μP监控电路。
前者实现简单,成本低,但复位可靠性相对较低;
后者成本较高,但复位可靠性高,尤其是高可靠重复复位。
对于复位要求高、并对电源电压进行监视的场合,大多采用这种方式。
本次课程设计采用了上电按钮电平复位电路。
3.4闹钟指示电路设计
闹铃指示可以有声或光两种形式。
本系统采用声音指示。
关键元件是蜂鸣器。
蜂鸣器有无源和有源两种,前者需要输入声音频率信号才能正常发声,后者则只需外加适当直流电源电压即可,元件内部已封装了音频振荡电路,在得电状态下即起振发声。
市场上的有源蜂鸣器分为3V、5V、6V等系列,以适应不同的应用需要。
闹钟电路是用比较器来比较计时系统和定时系统的输出状态,如果计时系统和定时系统的输出状态相同,则发出一个脉冲信号,再和一个高频信号混合,送到放大电路驱动扬声器发声,从而实现定时闹响的功能。
其电路设计参见系统原理图。
本次采用P3.3口接扬声器
3.5时间显示电路设计
本次课程设计采用了8位数码管显示电路。
在8位LED显示时,为了简化电路,降低成本,采用动态显示的方式,8个LED显示器共用一个8位的I/O,8位LED数码管的位选线由P2控制,而将其相应的段选线并联在一起,由一个8位的I/O口控制,即P0口。
译码显示电路将“时”、“分”、秒”计数器的输出状态菁七段显示译码器译码,通过LED显示器显示出来。
到达定时电路时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现闹铃。
校时电路时用来对“时”、“分”、“秒”显示数字进行校对调整的。
3.6按键设计:
一般采用复位式开关,P3.0、P3.1、P3.2分别连接3个按键,实现调模式,时间加和时间减;
3.7指示设计:
分别用红色和绿色来表示上午和下午,P3.4接红色,P3.5接绿色。
3.8电源设计
由于单片机是5伏电压供电,故应当设计一个电源,把220V交流电源转换成直流5V电压,需采用稳压管7805。
电路图如下:
4软件设计流程及描述
4.1概述
软件设计的重点在于秒脉冲信号的产生、显示的实现、以及按键的处理等方面。
基于软件的秒脉冲信号通常有延时法和定时中断法。
延时法一般采用查询方式,在延时子程序前后必然需要查询和处理的程序,导致误差的产生,因此其秒脉冲的精度不高;
中断法的原理是,利用单片机内部的定时器溢出中断来实现。
例如,设定某定时器每1000ms中断1次,则1次的周期为1s。
本系统中所使用的晶振频率为12MHZ。
4.2程序流程图
4.3函数模块及功能
(1)voiddisplay()
显示时间以及显示调节时间和闹钟时间的闪烁;
(2)voidkey()
键盘功能函数,实现3个按键有关的模式转换以及数字加一减一;
(3)voidinit()
初始化设置中断;
(4)voidtime1()interrupt3
定时器1中断函数,实现计时功能。
(5)main()
主函数
5仿真及运行结果
5.1Proteus仿真电路图
5.2运行结果
能正常显示时分秒,设置时间,设置闹钟,上午和下午指示正常。
6心得体会
首先在做本次设计的过程中,我感触最深的当属查阅大量的设计资料了。
为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。
我们是在做单片机实习,我们一切都要有据可依,有理可寻,不切实际的构想永远只能是构想,永远无法升级为设计。
其次,在这次设计中,我们运用到了以前所学的专业课知识,如:
C语言、模拟和数字电路知识等。
虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。
最后,在设计之前,我们要对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;
要有一个清晰的思路和一个完整的的软件流程图;
在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;
要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;
在实习过程中遇到问题是很正常的,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。
但是从中学到的知识会让我受益终身。
发现、提出、分析、解决问题和实践能力提高都会受益于我在以后的学习、工作和生活中。
附:
源程序
#include<
reg51.h>
unsignedcharled[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
//用一维数组定义-9、横杠、全灭共阳
unsignedchara[8];
unsignedcharsecond=0,minute=0,hour=0;
unsignedcharminute1=0,hour1=0;
unsignedcharb[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//扫描共阳
unsignedchark=0;
unsignedinttemp;
//记录毫秒为秒的变量
unsignedcharM,S_flag;
//M是模式,更新时间的种模式加上正常模式S_flag闪烁标志
sbitK1=P3^0;
sbitK2=P3^1;
sbitK3=P3^2;
sbitBEEP=P3^3;
sbitled1=P3^4;
sbitled2=P3^5;
voiddelay(unsignedn)//0.2毫秒
{
intx,y;
for(x=0;
x<
n;
x++)
for(y=0;
y<
24;
y++);
}
voidinit()
{
M=0;
S_flag=0;
//闪烁标志位
TMOD=0x10;
//定时器以方式定时
TH1=0xfc;
TL1=0x18;
EA=1;
//打开总中断
ET1=1;
//允许定时器中断
TR1=1;
//开启定时器(开始定时计数)
}
voidtime1()interrupt3//定时器中断函数
//定时ms
temp++;
if(temp==1000)//配合定时器定时s
{temp=0;
second++;
}
if(second==60)
{second=0;
if(minute<
59)
minute++;
else{minute=0;
hour++;
hour%=24;
}
}
if(hour>
=0&
&
hour<
12){led2=1;
led1=0;
elseif(hour<
=24){led1=1;
led2=0;
if(hour1==hour&
minute1==minute&
second<
10)//闹钟时间到
{
BEEP=!
BEEP;
}
if(temp%250==0)//每ms
S_flag=!
S_flag;
//闪烁标志位取反
if(k==8)k=0;
P1=a[k];
P2=b[k++];
delay
(1);
P2=0x00;
}
voiddisplay()
switch(M)
{
case0:
{
a[0]=led[hour/10];
a[1]=led[hour%10];
a[2]=led[10];
a[3]=led[minute/10];
a[4]=led[minute%10];
a[5]=led[10];
a[6]=led[second/10];
a[7]=led[second%10];
}break;
case1:
if(S_flag==1)
{
a[0]=led[hour/10];
a[1]=led[hour%10];
}
else
a[0]=led[11];
a[1]=led[11];
case2:
a[3]=led[minute/10];
a[4]=led[minute%10];
a[3]=led[11];
a[4]=led[11];
case3:
a[0]=led[hour1/10];
a[1]=led[hour1%10];
a[3]=led[minute1/10];
a[4]=led[minute1%10];
a[6]=led[11];
a[7]=led[11];
case4:
a[0]=led[hour1/10];
a[1]=led[hour1%10];
a[3]=led[minute1/10];
a[4]=led[minute1%10];
voidkey()
if(K1==0)
delay(10);
//延时去抖
if(K1==0)//按K1进行模式切换
{M++;
if(M==5)
while(!
K1);
//等待按键释放
}
if(M!
=0)
{
//模式--调时
if(K2==0)
{
delay(10);
//延时去抖
if(K2==0)//加键按下
{
if(hour<
23)hour++;
elsehour=0;
}
while(!
K2);
//等待按键释放
}
if(K3==0)
if(K3==0)
{
if(hour>
0)hour--;
elsehour=23;
}
K3);
}break;
case2:
//模式--调分
{
if(K2==0)
{
if(minute<
59)minute++;
elseminute=0;
if(K3==0)
if(minute>
0)minute--;
elseminute=59;
}
}break;
case3:
//模式--闹钟调时
{
if(K2==0)
{
delay(10);
{
if(hour1<
23)
hour1++;
elsehour1=0;
}
while(!
}
if(K3==0)
if(K3==0)
{if(hour1>
0)
hour1--;
elsehour1=23;
}
}break;
case4:
//模式--闹钟调分
{
{
if(minute1<
minute1++;
elseminute1=0;
}
while(!
if(K3==0)//减键按下
{if(minute1>
minute1--;
elseminute1=59;
}break;
}
voidmain()
init();
while
(1)
{
key();
display();