智能八路抢答器设计.docx
《智能八路抢答器设计.docx》由会员分享,可在线阅读,更多相关《智能八路抢答器设计.docx(13页珍藏版)》请在冰豆网上搜索。
智能八路抢答器设计
智能八路抢答器设计
智能八路抢答器设计
1引言
1.1设计目的
此设计采用AT89C52单片机为核心控制元件,结合数码管、蜂鸣器、发光二极管等器件构成一个简易的八路抢答器。
利用了单片机的按键复位电路、时钟电路、定时中断等电路,设计的抢答器具有实时显示抢答功能。
1.2设计要求
(1)设计一个可供8人进行抢答的抢答器。
(2)系统设置复位按钮,按动后,重新开始抢答。
2设计方案及原理
2.1设计方案
(1)复位电路
89C52的复位输入引脚RST为89C52提供了初始化的手段,可以使程序从指定处开始执行,在89C52的时钟电路工作后,只要RST引脚上出现超过两个机器周期以上的高电平时,即可产生复位的操作,如果RST保持高电平,则单片机循环复位。
只有当RST由高电平变低电平以后,89C52才从0000H地址开始执行程序。
本系统采用按键复位方式的复位电路。
(2)时钟电路
89C52的时钟可以由两种方式产生,一种是内部方式,利用芯片内部的振荡电路;另外一种为外部方式。
本论文根据实际需要和简便,采用内部振荡方式。
89C52内部有一个用于构成振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是此放大器的输入端和输出端。
这个放大器与作为反馈元件的片外晶体或陶瓷谐振器一起构成一个自激振荡器。
(3)输入电路
抢答器输入信号由八个小按键控制,八个按键连接在P2口当有键按下的时候,就产生了有效的输入信号,使与这个按键相连的引脚变为低电平,产生一个低电平的输入信号。
2.2系统组成框图
该系统的组成框图如图1所示,在89C52单片机的P2口接上八个开关用于八路抢答;P3.2口接启动开关,用于主持人控制抢答是否开始;在RST脚接复位开关用于清零;在P1.0口接蜂鸣器用于开始提示和超时后报警;在P0口接三个数码管用于显示倒计时时间和抢答者的编号。
该系统还包括时钟电路部分。
图1系统组成框图
3硬件设计
3.1系统总体电路
图2系统总体电路图
3.2抢答按键电路
抢答按键电路采用八位开关依次接入P2口的8位,并通过编程实现抢答的优先判断,其电路如图4所示。
图4抢答按键电路
3.3数码管显示电路
显示电路采用三位共阳数码管,前两位为抢答倒计时,后一位在有选手抢答时,显示抢答成功者编号。
P0口外接上拉电阻驱动数码管,并输出段选码,P1.0~P1.2口作为三位数码管的位选端,通过动态扫描的方式来实现预期功能。
数码管显示电路如图3所示。
图3数码管显示电路
3.4蜂鸣器电路
蜂鸣器用以实现开始时提示、有选手抢答时提示以及时间用尽提示,外接在单片机的P3.7口上,其电路如图5所示。
图5蜂鸣器电路
3.5时钟电路
通过引脚XTAL1和XTAL2外接晶振和电容构成系统时钟,如图6所示。
图6时钟电路
4软件设计
4.1程序总体流程图
图7程序总体流程图
4.2分段程序设计
(1)延时程序段,即Delay()函数。
该函数用以调整单片机CPU处理指令的延时,实现数码管动态扫描显示、蜂鸣器发声等功能。
(2)数码管显示程序段,分为Display_1()和Display_2()两个函数。
前者用于在还没有选手抢答时显示问题倒计时,后者用于在有选手抢答后,数码管对时间和抢答成功者编号的显示。
(3)蜂鸣器发声程序段,即ring()函数。
用于控制蜂鸣器响一段时间。
(4)程序主函数,即main()。
该程序段用于指示单片机整个程序的入口,并设置好相应的参数、单片机处理的主要任务等。
(5)中断函数interrupt0(),用于触发主程序的执行,即打开定时器、开始倒计时等功能。
(6)定时器运行函数time0(),用于初始化定时器的初值以触发中断,实现准确倒计时的功能。
该函数的执行使定时器每10ms触发一次中断,每触发100次,即计时满1s,将倒计时的数字减一。
在倒计时未结束时,持续扫描键盘按钮,当有选手抢答时,将标志位置1,EA置0,并触发Display_2()的运行。
4.3编程语言编制程序
见附录
4.4调试结果
源程序经过KeilC51软件编译通过,并通过调试工具成功验证软件执行结果,成功生成可以被单片机CPU识别执行的HEX文件。
5系统仿真
5.1仿真结果
主持人按下Start按钮,倒计时开始,运行效果如图8所示。
图8倒计时阶段
有选手抢答时,倒计时停止,显示选手编号,系统停止响应其他抢答者的按键,直到主持人将系统复位,如图9所示。
图9抢答成功
5.2问题分析
(1)软件结构设计略显繁琐,会降低单片机执行效率,尚有待改进。
(2)系统功能仍可进一步扩充,使其更加智能化。
如可以加入最后五秒钟蜂鸣器报警功能、根据问题难易程度由主持人设置问题倒计时等功能。
(3)选手抢答按键判断可以采取矩阵键盘扫描方式,可方便后期扩充更多路数。
6设计总结
此方案设计的抢答器具有计时抢答功能,并且灵敏度高,实用性强,造价低廉,功能比较完善。
通过这次抢答器的设计我加深了对单片机各个方面知识的了解,基本掌握了利用单片机设计制作简单的电子系统的步骤和方法。
在整个设计过程中,我先进行了软件方面的设计。
通过去图书馆翻阅相关书籍、在网络上查看相关资料等方式对项目进行了一个初步的设计,并在word上做了基本的设计思路汇总,列出大概的整体框架和程序流程图。
之后我根据流程图写出基本的c语言程序。
这个程序中包括了初始化子程序、延时程序、中断程序、定时器程序、Led数码管显示程序等。
在多次检查程序后,我在keil里对源程序进行了编译。
Keil下方显示屏中出现了两个错误,经过检查,原因是没有通过sbit命令对接口进行定义。
经过对源代码的修改,再次运行时编译成功,之后我通过建立目标文件生成了.hex文件。
硬件方面,我根据设计需求在proteus仿真软件上进行了基本的硬件设计。
首先从元件库中选出了89C52芯片,之后我在P0口上连Led数码管显示电路,P2连选手按键抢答电路,P3口连蜂鸣器警报电路和start电路。
在这个整体过程中我认为最困难的步骤是找到适合抢答器设计的电容元件,为了解决这个问题,我上网查了大量资料,并结合自己的多次的实验,最终找到合适电路的电容。
在解决完这个问题后,我把hex文件烧录到AT89C52芯片中,但是系统无法响应Start按键触发的中断程序,按下Start按钮后,数码管只显示20而不开始倒计时。
于是我又重新回到工程文件中查找错误的根源所在,在确定了电路图连接无误后,我开始查找C语言源程序中存在的不能被编译器识别的错误,经过反复查找和对比相关资料,最终确定导致错误的原因是误把ET0的值赋成了0而没有开启计时器,经过改正后,系统运行正常。
参考文献
[1]王思明.《单片机原理及应用系统设计》.北京科学出版社,2012.09
[2]邹应全.《51系列单片机原理与实验教程》.西安电子科技大学出版社,2007.12
[3]周坚.《单片机轻松入门(第二版)》.北京航空航天大学出版社,2007.02
[4]周坚.《单片机C语言轻松入门》.北京航空航天大学出版社,2011.08
附录
C语言源程序
#include
#defineucharunsignedchar
#defineuintunsignedint
uintnum=20;
uintCount=0;
uintge=0;//个位
uintshi=2;//十位
uintn;
uinti;
uintm=0;
sbitP3_7=P3^7;
ucharflag=0;
ucharflag1=0;
uinttab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
voidDelay(i)
{
for(;i>0;i--);
}
voidDisplay_1()
{
P1=0x01;
P0=tab[shi];
Delay(200);
P1=0x02;
P0=tab[ge];
Delay(200);
}
voidDisplay_2()
{
P1=0x01;
P0=tab[shi];
Delay(200);
P1=0x02;
P0=tab[ge];
Delay(200);
P1=0x04;
P0=tab[n];
Delay(200);
}
voidring()
{
flag1=0;
P3_7=1;
Delay(1000);
P3_7=0;
}
main()
{
EA=1;//开总中断
EX0=1;//开外部中断0
IT0=1;//中断方式
TMOD=0x01;//定时器/计数器0工作于方式1
ET0=1;//开定时器/计数器0中断
TH0=0xd8;
TL0=0xf0;
P3_7=0;
while
(1)
{
if(flag!
=1)
Display_1();
if(flag==1)
Display_2();
if(flag1==1)
ring();
}
}
voidinterrupt0()interrupt0
{
TR0=1;
flag1=1;
}
voidtime0()interrupt1
{
TH0=0xd8;
TL0=0xf0;
Count++;
if(Count==100)
{
Count=0;
num--;
}
if(num!
=0&&P2==0xff)
{
shi=num/10;
ge=num%10;
flag=0;
}
if(num==0)
{
ring();
EA=0;
}
if(num!
=0&&P2!
=0xff)
{
switch(P2)
{
case0xfe:
n=1;flag=1;flag1=1;EA=0;break;
case0xfd:
n=2;flag=1;flag1=1;EA=0;break;
case0xfb:
n=3;flag=1;flag1=1;EA=0;break;
case0xf7:
n=4;flag=1;flag1=1;EA=0;break;
case0xef:
n=5;flag=1;flag1=1;EA=0;break;
case0xdf:
n=6;flag=1;flag1=1;EA=0;break;
case0xbf:
n=7;flag=1;flag1=1;EA=0;break;
case0x7f:
n=8;flag=1;flag1=1;EA=0;break;
default:
break;
}
}
}