单片机课设完整版.docx
《单片机课设完整版.docx》由会员分享,可在线阅读,更多相关《单片机课设完整版.docx(30页珍藏版)》请在冰豆网上搜索。
单片机课设完整版
摘要
近几年,单片机在各个领域得到广泛的应用。
从工业到人们的日常生活,大部分的科技产品都是通过单片机来控制。
在它问世之前,自动控制设备得不到广泛的应用,这是因为控制设备的体积庞大,耗电量大,价格昂贵。
在第一台微处理器成功研制不久,第一个单片机就问世了。
因为其小巧的体积,低功耗,以及高效的性能,单片机受到了大家的欢迎。
本设计利用Atmel公司的AT89C52单片机对电子时钟进行开发,设计了实现所需功能的硬件电路,应用C语言进行软件编程,并用Proteus软件进行演示、验证。
主要介绍用单片机内部的定时/计数器来实现电子时钟的方法,本设计由单片机AT89C52芯片为核心,辅以必要的电路,构成了一个单片机的数字电子时钟。
它的计时周期为24小时,显满刻度为“23时59秒”,且配有4个独立按键,可以灵活地调节时间和日期,并具有一定的扩展性。
关键词:
单片机;数字电子钟;数码管驱动显示电路。
1简介
1.1基于单片机的数字钟介绍
1.单片机的介绍:
“单片机”就是将计算机的基本部件集成到一块芯片上,包括CPU(CentralProcessingUnit)、ROM(ReadOnlyMemory)、RAM(RandomAccessMemory)、并行口(ParallelPort)、串行口(SerialPort)、定时器/计数器(Timer/Counter)、中断系统(InterruptSystem)、系统时钟及系统总线等。
计算机系统已明显地朝巨型化、单片化、网络化三个方向发展。
巨型化发展的目的在于不断提高计算机的运算速度和处理能力,以解决复杂系统计算和高速数据处理,比如系统仿真和模拟、实时运算和处理。
单片化是把计算机系统尽可能集成在一块半导体芯片上,其目的在于计算机微型化和提高系统的可靠性,这种单片计算简称单片机。
单片机的内部硬件结构和指令系统主要是针对自动控制应用而设计的所以单片机又称微控制器MCU(MicroControllerUnit)。
用它可以很容易地将计算机嵌入到各种仪器和现场控制设备中,因此单片机又叫做嵌入式微控制器(EmbeddedMCU)。
单片机自20世纪70年代问世以来,以其鲜明的特点得到迅猛发展,已广泛应用于家用电器、智能玩具、智能仪器仪表、工业控制、航空航天等领域,经过30多年的发展,性能不断提高,品种不断丰富,已经形成自动控制的一支中坚力量。
据统计,我国的单片机年容量已达1~3亿片,且每年以大约16%的速度增长,但相对于国际市场我国的占有率还不到1%。
这说明单片机应用在我国有着广阔的前景。
对于从事自动控制的技术人员来讲,掌握单片机原理及其应用已经成为必不可少的学习任务。
单片机的应用十分广泛,在工业控制领域、家电产品、智能化仪器仪表、计算机外部设备,特别是机电一体化产品中,都有重要的用途。
2.数字钟介绍:
本设计中的数字钟的核心是AT89C52单片机,,硬件电路主要由四部分构成:
时钟电路,复位电路,键盘以及显示电路。
时钟是将小时、分钟、秒钟显示于人的肉眼的计时装置。
而单片机模块中最常见的正是数字钟,数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
而LED电子定时时钟是以单片机为基础的数字电路实现对时、分、秒的数字显示的数字计时装置,它的计时周期为12小时,另外应有校时功能和一些显示日期、闹钟等附加功能。
由于时钟的实用性和在人们生活中的重要性,所以尝试设计以单片机为核心的数字时钟是很有意义的。
钟表原先的报时功能已经原不能满足人们日益增长的要求,现代的电子时钟多带有类似自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、通断动力设备、甚至各种定时电气的自动启用等功能。
1.2本系统的特点和功能介绍
1.特点:
我所设计的是LED显示的自动报时系统,是一种基于单片机技术的电子产
品,用到的单片机芯片是AT89C52芯片,除此之外还包括晶振电路和复位/时钟电路构成单片机最小应用系统,还有按键电路,显示电路,报时电路等等。
计时方案采用软件控制利用AT89C52单片机内部的定时/计数器进行定时,配合软件延时实现时、分的计时。
2.本单片机报时控制系统具备以下功能:
(1)有电子时钟,定时闹铃功能。
(2)时钟显示功能:
4位LED从左到右依次显示“时时分分”,采用12小时制显示。
(3)采用4个独立按键(移位键、加1键、减1键、校时置入键)
移位键:
每按动移位键一次,小数点从左向右移动1位。
加1键:
对小数点所在位的数什进行十进制加1。
减1键:
对小数点所在位的数值进行十进制减1。
校时置入键:
将显示的时间值置入实时时钟的计时缓冲区。
(4)预设定时时间到则发出闹铃声。
2硬件设计
2.1总体设计方案
本以数码管驱动显示的闹钟,是以单片机及外围接口电路为核心硬件,辅以其他外围硬件电路,用软件程序来实现的。
单片机定时报时控制系统硬件原理图如下图所示。
图2-1总体设计方案图
2.1.1AT89C51的介绍
AT89S51是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4kBytesISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89S51有40个引脚,与MCS—51系列单片机引脚完全兼容。
如图2-2所示。
其各自引脚功能如下:
Vcc:
电源电压。
GND:
地。
P0口:
P0口是一组8位漏极开路型双向I/O接口,也即地址/数据总线复用口。
当访问外部数据存储器或程序存储器时,这组口线分时转换地址和数据总线复用,在访问期间激活内部上拉电阻。
在FLASH编程时,P0口接受指令字节,而在程序校验时,输出指令字节。
P1口:
P1口是一个带内部上拉电阻的8位双向I/O接口,P1的输出缓冲级可驱动4个TTL逻辑门电路。
FLASH编程和程序校验时,P1接收低8位地址。
P2口:
P2口是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动4个TTL逻辑门电路。
在访问外部程序存储器或16位地址的外部数据存储器时P2口送高8位地址数据。
FLASH编程或校验时,P2亦接收高位地址和其他控制信号。
P3口:
P3口是一组带有内部上拉电阻的8位双向I/O接口。
P3口输出缓冲级可驱动4个TTL逻辑门电路。
RST:
复位输入。
ALE/
:
当访问外部数据时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
对FLASH存储器编程时,该引脚还用于输入编程脉冲(
)。
EA/VPP:
外部访问允许。
:
程序储存允许。
输出是外部程序存储器的度选通信号。
XTAL1:
振荡器反相放大及内部是钟发生器的输入端。
XTAL2:
振荡器反相放大器的输出端。
2.2硬架结构设计
2.2.151单片机的最小系统(见图2-2、2-3、2-4所示)
在晶振电路中XTAL1、XTAL2为AT89C52中连接晶振的管脚,本系统中所使用的晶振频率为12MHZ。
XTAL1为振荡器反相放大器及内部时钟发生器的输入端,XTAL2为振荡器反相放大器的输出端。
其中电容C8、C9起着系统时钟频率微调的作用,因此,在本定时报时系统的实际应用中一定要注意正确选择参数(30±10PF),并保证对称性(尽可能匹配),可能的话,温度系数要尽可能的低。
实验表明这两个电容元件对时钟走时误差有较大关系。
本系统采用了RC复位电路,其实现简单,成本低,但复位可靠性相对较低。
当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。
2.2.2显示部分设计
作为本次设计中使用的核心元件AT89C51,其结构如下图:
图2-2引脚图
晶振与复位电路主要作用是保证电子钟时间的走时精准度和其复位,是电子钟使用与设计中主要的模块,也是校验时钟是否合格的硬性标准。
复位/时钟电路如图2-3所示。
图2-3复位/时钟电路
用4位LED七段数码管作为显示器,到达定时时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现报时。
其驱动电路简单。
采用了四个三极管和四个5.1K的电阻,还有八个510欧姆的限流电阻。
图2-4数码管驱动显示电路
2.2.3电源部分设计
AT89C51系列单片机工作电源范围宽达4~5.5V。
单片机供电方式有两种:
①集成稳压电源方式②电池供电
①集成稳压电源方式:
利用变压器、整流、滤波、稳压自制电源如图2-5所示。
图2-4稳压电源电路
②电池供电:
由于电池携带方便,此次设计采用此方式,供电电压直流5V。
图2-6供电指示电路
2.2.4报时部分的设计
报时指示可以有声或光两种形式,本系统采用声音指示。
关键元件是蜂鸣器,蜂鸣器有无源和有源两种,前者需要输入声音频率信号才能正常发声,后者则只需外加适当直流电源电压即可,元件内部已封装了音频震荡电路,在得电状态下即起振发声。
市场上的有源蜂鸣器分为3V、5V、6V等系列,以适应不同的应用需要,本系统采用5V有源蜂鸣器实现报时。
由软件产生方波输出经三极管放大后驱动蜂鸣器发音,不用硬件振荡电路,电路图如图2-7所示。
图2-7报时电路
2.2.5键盘部分的设计
如果设置过多按键,将会占用较多I/O口,而且会给布线带来不便,因此采用4个独立按键。
由于按键较少,在修改时间时就不能直接输入,只能通过加或减完成,稍为麻烦一些,但其程序简单,而且并不需要经常修改时间。
图2-8按键电路
2.2.6总体硬件电路图
通过Proteus画出的总体硬件电路图如下所示。
图2-9总体硬件电路图
2.6.7proteus仿真
图2-10proteus仿真
3软件部分
3.1部分设计思想的说明
软件设计的重点在于秒脉冲信号的产生、显示的实现、以及按键的处理等。
基于软件的秒脉冲信号通常有延时法和中断法。
延时法一般采用查询方式,在延时子程序前后必然需要查询和处理的程序,导致误差的产生,因此其秒脉冲精度不高;中断法的原理是,利用单片机内部的定时器溢出中断来实现。
本系统中所使用的晶振频率为12MHZ,采用中断的方法实现计时操作。
根据工作流程,软件设计可分为以下几个功能模块:
1、主程序:
是系统软件的主框架。
结构化程序设计一般有“自上而下”和“自下而上”两种方式,“自上而下”法的核心就是主框架的构建。
它的合理与否关系到程序最终的功能的多少和性能的好坏。
2、计时:
系统定时采用定时器与软件循环相结合的方法。
定时器0每隔100MS溢出中断1次,则循环中断10次延时时间为1S,上述过程重复60次为1MIN,分计时60次为1H,小时计时12次则时间重新回到00:
00,如果使用时钟芯片,系统就不怕掉电且时间精确。
但这种芯片比较贵,况且,设计本系统主要是为了学习单片机程序的编写和调试以及设计硬件电路的一些方法,因此采用软件的方法来计时而没有采用价格较高的时钟芯片。
3、时间设置:
由键盘出入设置当前时间。
4、LED数码管扫描显示:
完成4位LED显示。
5、键盘扫描:
判断是否有键按下,无键按下则循环等待,有键按下则求承诺键号并将键号送累加器A返回。
程序中的去抖延时和循环等待延时都用显示子程序来代替,从而保证随时刷新显示,软件的去抖动的实质是软件延时,即检测到某一键状态发生变化后延时一段时间,再检测该按键的状态是否还保持着,如是则作为按键处理,否则,视为抖动,不予理睬。
去抖中的延时时间一般参考资料多描述为10ms,实际应用中,应大于20ms,会导致按一次作多次处理,影响程序正常执行。
键盘管理程序的功能是检测有无键闭和,如有键闭和,消除抖动,根据键号转接到相应的键处理程序。
6、报时处理:
判断时间是否到否,如时间到,则启动报时处理程序。
闹铃判别与闹铃处理的关键在于判别何时要进行闹铃,当任一位发生改变(进位)时,就必须进行闹铃判别,比较当前计数时间与定时时间是否相等,若相等则将闹铃标志位置数,开始响铃。
为了避免响铃影响显示,采用了每显示几屏以后在显示程序中出现脉冲,驱动蜂鸣器,不会影响显示。
之后对按键进行判断。
3.2C语言、keil、proteus的介绍
3.2.1C语言
C语言是目前世界上流行、使用最广泛的高级程序设计语言。
C语言对操作系统和系统使用程序以及需要对硬件进行操作的场合,用C语言明显优于其它高级语言,许多大型应用软件都是用C语言编写的。
C语言具有绘图能力强,可移植性,并具备很强的数据处理能力,因此适于编写系统软件,三维,二维图形和动画它是数值计算的高级语言。
C语言发展迅速,而且成为最受欢迎的语言之一,主要因为它具有强大的功能。
许多著名的系统软件,如DBASEⅢPLUS、DBASEⅣ都是由C语言编写的。
用C语言加上一些汇编语言子程序,就更能显示C语言的优势了,象PC-DOS、WORDSTAR等就是用这种方法编写的。
3.2.2keil
KeilC51是美国KeilSoftware公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。
Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。
运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。
如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。
3.2.3proteus
Proteus软件是英国Labcenterelectronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。
它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。
3.3参考程序
#include
#defineucharunsignedchar
#defineuintunsignedint
/////////////////////////////////////////////////////////////////////////////
//sbitP07=P0^7;
sbitP27=P2^7;//时10
sbitP26=P2^6;//时个
sbitP25=P2^5;//分10
sbitP24=P2^4;//分个
sbitsw0=P1^6;//3.7时
sbitsw1=P3^0;//3.6分
sbitsw2=P3^5;//3.5启动
sbitsw3=P1^3;//3.3总开关
//sbitsw4=P3^2;//3.4
//sbitled=P0^7;
sbitP20=P2^0;//喇叭
sbitP21=P2^1;//继电器
ucharmiao,k,a,b;//
ucharshi,fen,shi10,shi1,fen10,fen1,jsshi,jsfen;
ucharjsshi10,jsshi1,jsfen10,jsfen1;
codeucharsz[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
///////////////////////////////////////////////////////////////////////////
voidxianshijs(ucharjsshi10,ucharjsshi1,ucharjsfen10,ucharjsfen1);
voidxianshi(ucharshi10,ucharshi1,ucharfen10,ucharfen1);
voiddelay(uinti);
voidchushihua();
voidshifenmiao();
voidanjian();
///////////////////////////////////////////////////////////////////////////
voiddelay(uinti)//扫描延时
{
uintt;
t=i;
while(t--);
}
voidchushihua()//初始化
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
EA=1;
shi=12;
fen=12;
miao=0;
jsshi=01;
jsfen=01;
}
voidxianshi(ucharshi10,ucharshi1,ucharfen10,ucharfen1)//显示时分秒
{
shi10=shi/10;
shi1=shi%10;
fen10=fen/10;
fen1=fen%10;
P0=sz[shi10];
P27=0;
delay(5);
P27=1;
P0=sz[shi1];
if(k==10)P0&=0x7f;//取点(H)
P26=0;
delay(5);
P26=1;
P0=sz[fen10];
P25=0;
delay(5);
P25=1;
P0=sz[fen1];
P24=0;
delay(5);
P24=1;
}
voidxianshijs(ucharjsshi10,ucharjsshi1,ucharjsfen10,ucharjsfen1)//显示时分秒
{
jsshi10=jsshi/10;
jsshi1=jsshi%10;
jsfen10=jsfen/10;
jsfen1=jsfen%10;
P0=sz[jsshi10];
P27=0;
delay(5);
P27=1;
P0=sz[jsshi1];
if(k==10)P0&=0x7f;//取点(H)
P26=0;
delay(5);
P26=1;
P0=sz[jsfen10];
P25=0;
delay(5);
P25=1;
P0=sz[jsfen1];
P24=0;
delay(5);
P24=1;
}
voidt0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
k++;
b++;
}
voidshifenmiao()//时分秒进位
{
if(k==20)
{k=0;
miao++;
}
if(miao==60)
{
miao=0;
fen++;
}
if(fen==60)
{
fen=0;
shi++;
}
if(shi==24)shi=0;
}
///////////////////////////////
voidajsw0jia()//shi+
{
if(sw0==0)
{
delay(50);
if(sw0==0)
{
do
{
while(sw0==0);
delay(50);
}
while(sw0==0);
shi++;
if(shi==24)shi=0;
}
}
}
voidajsw1jia()//fen+
{
if(sw1==0)
{
delay(50);
if(sw1==0)
{
do
{
while(sw1==0);
delay(50);
}
while(sw1==0);
fen++;
if(fen==60)
{
fen=0;
}
}
}
}
/////////////////////////////////////
/*voidajsw0jian()//shi-
{
if(sw0==0)
{
delay(50);
if(sw0==0)
{
do
{
while(sw0==0);
delay(50);
}
while(sw0==0);
shi--;
if(shi==-1)
{
shi=23;
}
}
}
}
voidajsw1jian()//fen-
{
if(sw1==0)
{
delay(50);
if(sw1==0)
{
do
{
while(sw1==0);
delay(50);
}
while(sw1==0);
fen--;
if(fen==-1)
{
fen=59;
}
}
}
}*/
////////////////////////////////////
voidqidong()//启动
{
if(sw2==0)
{
delay(50);
if(sw2==0)
{
do
{
while(sw2==0);
delay(50);
}
while(sw2==0);
TR0=1;
}
}
}
///////////////////////////////////
voidanjian()
{
if(sw3==0)
{
delay(50);
if(sw3==0)
{
do
{
while(sw3==0);
delay(50);
}
while(sw3==0);
a++;
if(a==4)a=0;
}
}
switch(a)
{
case1:
{
ajsw0jia();
ajsw1jia();
break;
}
case2:
{
//ajsw0jian();
//ajsw1jian();
qidong();
break;
}
/*case3:
{
//qidong();
break;
}
*/
case3:
{
xianshijs(jsshi10,jsshi1,jsfen10,jsfen1);
if(sw0==0)
{
delay(50);
if(sw0==0)
{
do
{
while(sw