毕业设计(论文)-基于STC89C52单片机的倒计时器设计
目
录
设计要求1
1
方案论证与对比1
1.1
方案一1
1.2
方案二1
1.3
方案对比与选择1
2
单元电路设计与计算2
2.1
STC89C52简介2
2.2时钟振荡电路的设计3
2.3复位电路的设计3
2.4数码管显示电路的设计4
2.5
独立按键电路的设计5
3
系统软件设计6
3.1
倒计时主程序流程6
3.2
定时器工作流程7
4
系统功能测试与整体指标8
5
详细仪器清单9
6
总结与思考及致谢10
参考文献10
附录一:倒计时器DXP原理图11
附录二:倒计时器电路PCB板图12
附录三:实物图13
附录四:程序14
倒计时器
设计任务与要求
本项目是由单片机执行设定的程序,在数码管显示倒计时的时间,且能由单片机接受矩阵键盘设定的时间。由4位数码管做显示,能够实现5种倒计时模式,通过控制按键进行选择9999s-0s、999s-0s、99s-0s、9s-0s、开始值由人工输入-0s。
1
方案论证与对比
现在,在许多领域中,定时器得到了广泛的应用,比如在体育比赛中的计时器;游戏中的倒计时;红绿灯,交通控制器,闹钟等等。可见倒计时器在社会中的重要性。当然,设计倒计时器的方法很多,以下是两个设计方案。
1.1
方案一
基于STC89S52单片机的LCD液晶显示模块1602显示的倒计时器。主要是以单片机来控制,用按键来设定倒计时初始时刻的值,用按键来进行倒计时初值的选择,LCD1602液晶作为显示模块来显示倒计时间。
1.2
方案二
基于STC89S52单片机的数码管显示模块显示的倒计时器。主要是以单片机来控制,用按键来设定倒计时初始时刻的值,按键来进行倒计时初值的选择。采用以软件为主的接口方法,即不使用专门的硬件译码器,而采用软件程序进行译码。
1.3方案对比与选择
比较两个方案,我们发现,方案二总体比方案一好。首先方案一虽然硬件电路简单,但造价较高,且在编写程序实现所要求的功能时较难,而方案二所用的显示模块是比较熟悉的数码管,编写程序是相对容易,且电路造价不高,因此,综合考虑之后决定采用方案二。
2单元电路设计
LED数码管倒计时器以STC89C52单片机为核心,起着控制作用,系统包括四位数码管显示电路,按键电路,复位电路,时钟振荡电路。倒计时的总体框图如下图1所示:
STC89C52
数码管显示电路
时钟振荡电路
独立按键电路
复位电路
图1
倒计时的总体框图
2.1
STC89C52简介
STC89C52是一种低功耗、高性能CMOS8位微控制器,具有
8K
在系统可编程Flash
存储器。在单芯片上,拥有灵巧的8
位CPU
和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
具有以下标准功能:
8k字节Flash,512字节RAM,
32
位I/O
口线,看门狗定时器,内置4KB
EEPROM,MAX810复位电路,2个16
位
定时器/计数器,一个6向量2级中断结构,全双工串行口。另外
STC89X52
可降至0Hz
静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU
停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35MHz,6T/12T可选。
图2
STC89C52引脚图
2.2
时钟振荡电路的设计
单片机必须在时钟的驱动下才能工作。在单片机内部有一个时钟振荡电路,只要外界一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。本系统使用的是内部时钟方式。时钟电路如下图2所示。一般选用石英晶体振荡器。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容C1、C2的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。本系统的C1、C2的值为30pf。
图3
时钟振荡电路
2.3复位电路的设计
在上电或复位过程中,控制CPU的复位状态:这段时间内让CPU保持复位状态,而不是一上电或刚复位完毕就工作,防止CPU发出错误的指令、执行错误操作,也可以提高电磁兼容性能。
无论用户使用哪种类型的单片机,总要涉及到单片机复位电路的设计。而单片机复位电路设计的好坏,直接影响到整个系统工作的可靠性。许多用户在设计完单片机系统,并在实验室调试成功后,在现场却出现了“死机”、“程序走飞”等现象,这主要是单片机的复位电路设计不可靠引起的。
基本的复位方式基本的复位方式基本的复位方式基本的复位方式
单片机在启动时都需要复位,以使CPU及系统各部件处于确定的初始状态,并从初态开始工作。89系列单片机的复位信号是从RST引脚输入到芯片内的施密特触发器中的。当系统处于正常工作状态时,且振荡器稳定后,如果RST引脚上有一个高电平并维持2个机器周期(24个振荡周期)以上,则CPU就可以响应并将系统复位。单片机系统的复位方式有:手动按钮复位和上电复位。此系统我们选用了手动按钮复位,手动按钮复位需要人为在复位输入端RST上加入高电平(图1)。一般采用的办法是在RST端和正电源Vcc之间接一个按钮。当人为按下按钮时,则Vcc的+5V电平就会直接加到RST端。手动按钮复位的电路如所示。由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。
图4
复位电路
2.4
数码管显示电路的设计
led数码管(LED
Segment
Displays)是由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。led数码管常用段数一般为7段有的另加一个小数点,还有一种是类似于3位“+1”型。位数有半位,1,2,3,4,5,6,8,10位等等,led数码管根据LED的接法不同分为共阴和共阳两类,了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,除了它们的硬件电路有差异外,编程方法也是不同的。共阴和共阳极数码管的内部电路,它们的发光原理是一样的,只是它们的电源极性不同而已。颜色有红,绿,蓝,黄等几种。led数码管广泛用于仪表,时钟,车站,家电等场合。选用时要注意产品尺寸颜色,功耗,亮度,波长等。在这里我们使用的是8段数码管显示(包含小数点),通常在显示上我们采用的方法一般包括两种:一种是静态显示,另一种是动态显示。其中静态显示的特点是显示稳定不闪烁,程序编写简单,但占用端口资源多,所耗得电能较大;动态显示的特点是显示稳定性没静态好,程序编写复杂,但是相对静态显示而言占用端口资源少。在本设计中,为了减少端口资源,降低电能消耗,采用的是动态显示方法。本系统的倒计时时间的最大范围是9999S,要显示出最大范围的值,从而可知数码管显示电路要用到4位数码管。
图5
数码管显示电路原理图
2.5
独立按键电路设计
通过5个独立按键控制不同的5种工作方式。因为第五种工作方式为可调的
倒计时模式,所以另外加了四个调初始值的按键,一个计时开始/停止键。
图6
独立按键电路图
3
系统软件设计
3.1
倒时计器主程序流程图
程序的的开始时先设定定时器0,先给定时,器装初值。检测按键是否按下,如果有按键按下,进入相应的倒计时方式。定时器0的定时时间是50ms,每当进入定时中断一次变量aa自动加一,当aa等于20时即为计时一秒,此时计时器清零,重新赋初值,并且之前设定的倒计时初值num值自动减一,同时进行相关的显示
。
开始
检测按键
进入相应工作方式
等待进入中断
进入中断aa++
aa=20?
计数器清零
num--
相应的显示
重设计数初值,启动
N
Y
图7
主程序流程图
Y
3.2定时器0的中断程序流程
定时器0的定时时间是50ms,用作扫描数码管显示,在定时器0开启时,定时器0开始定时,此时主程序正常运行,当定时器0的定时时间到时,主程序不在执行,开始进入中断程序,在中断程序中,若计时了1s就对时间进行处理且计数标志清零,赋值给相应的变量且减1,若没有则计数标志就进行加1,若倒计时的时间为零则重新赋值,中断程序执行完后返回主程序。如图8所示。
开始
初始化及T0中断设定
设置堆栈指针
计数器预清零
设置计数器初值
开中断允许
等待中断
图8定时器0的中断程序流程图
4系统功能测试
硬件调试的主要任务是排除硬件故障,其中包括设计错误和工艺性故障。
1、脱机检查:用万用表逐步按照电路原理图检查印制电路中所有器件的各引脚,尤其是电源的连接是否正确:检查数据总线、地址总线和控制总线是否有短路等故障,顺序是否正确;检查各开关按键是否能正常开关,是否连接正常;各限流电阻是否短路等内容。为了保护芯片,应先对各IC电位进行检查,确定其无误后再插入芯片检查。2、联机调试:暂时拔掉89C52芯片,将仿真器的40仿真插入89C52的芯片插座进行调试,检验键盘/显示接口电路是否满足要求设计。可以通过一些简单的测软件来查看接口工作是否正常。例如,我们可以设计一个软件,使89C52的P1、P2口输出55H或AAH,同时读P3口,运行后用万用表检查相应端口电平是否一高一低,在仿真器中检查读入的P3口8位是否为1,如果正常则说明89C52正常工作。还可以设计一个使所有LED全显示“8.”的静态显示程序来检验LED的好坏。如果运行测试结果与预期不符,很容易根据故障现象判断故障原因并采取针对性措施排除故障。开始时,数码管的亮度不够理想。经检查知,是段选电阻(接P0口的限流电阻)太大。最后,换成470欧的电阻后,数码管显示正常。
软件调试的任务是利用开发工具进行在线仿真调试,发现和纠正程序错误,同时也能发现硬件故障。程序的调试应一个模块一个模块地进行,首先单独调试各功能子程序,检验程序是否能够实现预期的功能,接口电路的控制是否正常等.最后逐步将各子程序连接起来进行联调。本系统的程序的编写就是在Keil
C软件中用C语言完成的。在程序中用到了一个定时器,为了使倒计时的时间准确,必须计算对定时器的初值,当程序完成之后,生成HEX文件。再利用Proteus软件进行仿真。
经过仿真和实际测试,在实际使用时完全没有闪烁。在程序中,定时器50ms中断一次,变量
aa自增,中断20次时,秒的显示自减,误差很小大约为0.1%。电路中的五个按键可以分别用来设定倒计时的计数范围,系统由5V电源来驱动。经过测试与分析,此系统稳定可用,满足设计要求。
5
详细仪器清单
表格1
仪器清单
仪器名称
数量
STC89C52
1
独立按键
10
USB接口
1
开关
2
四位共阴极数码管
1
晶振12M
1
1K电阻
8
200R电阻
8
30PF电容
2
8.2K电阻
1
470R电阻
1
22UF电容
1
6
总结与致谢
在设计倒计时器课程设计的过程中,我深切体会到,实践是理论运用的最好检验。本次设计是对我这一学期所学知识的一次综合性检测和考验,无论是动手能力还是理论知识运用能力都得到了提高,同时加深了我对网络资源认识,大大提高了查阅资料的能力和效率,使我有能有更多的时间去设计软件部分。本系统要求我们要有丰富的编程经验,还要能会看单片机开发板原理图,能熟悉那些I/O口的作用,且能够准确的运用数电等多方面的知识。在软件调试过程中,我学会不少的东西,掌握一些调试软件的方法。在设计仿真图和设计电路图中,对Proteus、Keil和Protel等软件掌握的更加牢固,而且所设计的基于单片机的倒计时器,精确度高,达到了应用要求这次课程设计使我掌握了很多实践知识,在老师和同学的帮助下对单片机有了进一步的了解。这次课程设计对我来说有着深远的意义,让我对未来的路又看得清楚了些。在此我要深深的感谢那些传授我知识的老师们,是你们无私的奉献,才会有如今掌握一定知识的我们。
参考文献
[1]
朱定华,戴汝平.单片微机原理与应用[M]
北京:清华大学出版社,2003
[2]
楼然苗,李光飞.单片机课程设计指导[M].北京航空航天大学出版社,2007
[3]
张鑫,单片机原理及应用(2版)[M].电子工业出版社,2010
[4]
谭浩强著.
C程序设计(第二版)[M].
清华大学出版社,1999
附录一:倒计时器DXP原理图
附录二:倒计时器电路PCB板图
附录三:实物图
附录四:程序
#include
/*设计者:杜斌、张帆*/
#define
uchar
unsigned
char
#define
uint
unsigned
int
char
temp1[4];
char
temp2[3];
char
temp3[2];
char
temp4[1];char
temp5[4],a;
char
code
duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit
key1=P2^0;
sbit
key2=P2^1;
sbit
key3=P2^2;
sbit
key4=P2^3;sbit
key5=P3^6;
sbit
start5=P3^5;
sbit
JIAQIAN=P2^4;
sbit
JIABAI=P2^5;
sbit
JIASHI=P2^6;
sbit
JIAGE=P2^7;
uint
num1=9999,num2=999,num3=99,num4=9,num5=0,t,i;
void
delay(uint
t);
void
main()
{
P1=0xf0;
P0=0x3f;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{
if(key1==0)
{
delay(10);
if(key1==0)
{
key1=0;
for(i=0;i10000)
num5=0;
}
while(!JIAQIAN);
delay(20);
while(!JIAQIAN);
}
if(JIABAI==0)
{
delay(10);
if(JIABAI==0)
{
num5=num5+100;
if(num5>10000)
num5=0;
}
while(!JIABAI);
delay(20);
while(!JIABAI);
}
if(JIASHI==0)
{
delay(10);
if(JIASHI==0)
{
num5=num5+10;
if(num5>10000)
num5=0;
}
while(!JIASHI);
delay(20);
while(!JIASHI);
}
if(JIAGE==0)
{
delay(0);
{
num5=num5+1;
if(num5>10000)
num5=0;
}
while(!JIAGE);
delay(20);
while(!JIAGE);
}
for(i=0;i0))
{
num5--;}
}
}
}
28