毕业设计8路抢答器系统的设计精品.docx
《毕业设计8路抢答器系统的设计精品.docx》由会员分享,可在线阅读,更多相关《毕业设计8路抢答器系统的设计精品.docx(28页珍藏版)》请在冰豆网上搜索。
![毕业设计8路抢答器系统的设计精品.docx](https://file1.bdocx.com/fileroot1/2023-1/23/c18ff6d5-4a9d-422b-994a-9ef8bd254f31/c18ff6d5-4a9d-422b-994a-9ef8bd254f311.gif)
毕业设计8路抢答器系统的设计精品
前言
转眼大三即将结束,一直以来都在不停的问自己3年来到底学到了什么,我也一直很迷惘,很为自己毕业后着急。
站在人来人往的校园里完全没有一个立足点去审视自己的能力,一直在等待着能自己实践的机会。
我们的专业老师明白学生的心理,高瞻远瞩,在6月份给我们专业安排了一次综合课程设计,由学生自己选择课题,自己设计,自己制出产品。
这样的一个安排我很是高兴,听到这消息我就暗暗的告诉自己一定好好努力做这次设计,结果并不是最重要的,就象我们老师说的:
能实现固然是最好,即使不能成功,只要我们认真去做了,依然能够学到很多东西,尤其是动手能力和实战经验。
本次所做的课程设计就是一个集抢答、计分功能于一体的一个电子产品,讲述了电路各部分的设计原理及所能实现的功能,它要求要对各种锁存器、计数器、定时器、显示器以及多谐振荡器等多种数字电子芯片以及AT89S52熟悉,并能加以运用。
虽然现在市面上有很多类似的成熟产品,但本次设计旨在提高动手能力,把握整体设计的步骤,从这个层面来讲,仍然很有意义。
1.总体设计方案
1.1数字抢答器方案
1.1.1运用完全的数字电路方案
系统各部分采用中小规模集成数字电路,用机械开关按钮作为控制开关,完成抢答输入信号的触发。
该方案的特点是中小规模集成电路应用技术成熟,性能可靠,能方便地完成选手抢答的基本功能,但是由于系统功能要求较高,所以电路连接集成电路相对较多,而且过于复杂,并且制作过程工序比较烦琐,使用不太方便。
1.1.2运用带微处理的器方案
该系统采用51系列单片机AT89C51作为控制核心,该系统可以完成运算控制、信号识别以及显示功能的实现。
由于用了单片机,使其技术比较成熟,应用起来方便、简单并且单片机周围的辅助电路也比较少,便于控制和实现。
整个系统具有极其灵活的可编程性,能方便地对系统进行功能的扩张和更改。
MCS-51单片机特点如下:
<1>可靠性好:
单片机按照工业控制要求设计,抵抗工业噪声干扰优于一般的CPU,程序指令和数据都可以写在ROM里,许多信号通道都在同一芯片,因此可靠性高,易扩充。
<2>单片机有一般电脑所必须的器件,如三态双向总线,串并行的输入及输出引脚,可扩充为各种规模的微电脑系统。
<3>控制功能强:
单片机指令除了输入输出指令,逻辑判断指令外还有更丰富的条件分支跳跃指令。
方案比较及其选用依据,显然方案二比方案一简单的多,不但从性能上优于方案一,而且在使用上及其功能的实现上都较方案一简洁,并且由于单片机具有优越的高集成电路性,使其工作速度更快、效率更高。
另外AT89C511单片机采用12MHz的晶振,提高了信号的测量精度,并且使该系统可以通过软件改进来扩张功能。
而方案一采用了中小规模集成电路,有其复杂的电路性能,从而可能会使信号的输入输出产生延时及不必要的误差。
依此依据选择方案二比较适合。
其原理框图如下:
图..1
2.单元模块设计
2.1抢答器电路设计计
2.1.1电源电路
一个系统要想正常的工作就必须要有稳定的电源提供,如果电源不稳定的话系统变无法正常的工作,
该系统的整个电路的工作电压都为5V,如果采用单独的线性电路,电路的纹波会很大这样系统可能会无法正常的工作,因此我们采用了一块稳压芯片7805。
他是一款5V的稳压芯片能将电压变得更加的平滑。
电源电路如图:
图2..电源电路
2.1.2时钟电路
单片机必须在时钟的驱动下才能工作。
在单片机内部有一个时钟振荡电路,只需要外接一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。
时钟电路如图2所示。
图3..外部振荡源电路
一般选用石英晶体振荡器。
此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。
电路中两个电容C1,C2的作用有两个:
一是帮助振荡器起振;二是对振荡器的频率进行微调。
C1,C2的典型值为20PF。
单片机在工作时,由内部振荡器产生或由外直接输入的送至内部控制逻辑单元的时钟信号的周期称为时钟周期。
其大小是时钟信号频率的倒数,常用fosc表示。
图中时钟频率为12MHz,即fosc=12MHz,则时钟周期为1/12µs。
2.1.3复位电路
单片机的第9脚RST为硬件复位端,只要将该端持续4个机器周期的高电平即可实现复位,复位后单片机的各状态都恢复到初始化状态,其电路图如图3所示:
图4..复位电路
图3中由按键RESET1以及电解电容C3、电阻R2构成按键及上电复位电路。
由于单片机是高电平复位,所以当按键RESET1按下时候,单片机的9脚RESET管脚处于高电平,此时单片机处于复位状态。
当上电后,由于电容的缓慢充电,单片机的9脚电压逐步由高向低转化,经过一段时间后,单片机的9脚处于稳定的低电平状态,此时单片机上电复位完毕,系统程序从0000H开始执行。
值得注意的是,在设计当中使用到了硬件复位和软件复位两种功能,由上面的硬件复位后的各状态可知寄存器及存储器的值都恢复到了初始值,而前面的功能介绍中提到了倒计时时间的记忆功能,该功能的实现的前提条件就是不能对单片机进行硬件复位,所以设定了软复位功能。
软复位实际上就是当程序执行完毕之后,将程序指针通过一条跳转指令让它跳转到程序执行的起始地址。
2.1.4显示电路
该电路的显示电路由4个LED共阴极管作为显示时间和选手号码,当然采用LCD液晶显示其也可以但是考虑到成本的问题,和实用性我们选择了LED,成本大大的降低,显示电路采用74LS04进行锁存,将P0口的数据进行锁存,这样P0口可以作为其他的用途了。
动态显示当中由于人们的视觉残留没一部分必须停留约为5-20ms才能完全的显示。
显示通过软件程序控制LED的动态显示显示程序如下:
voiddisplay(ucharbaiwei,shiwei,gewei,xuanshou)//显示函数
{
suo=1;
P2=0xf7;//打开显示时间十位的位选
delay1(5);
P2=0xfb;//打开显示时间十位的位选
delay1(5);
P2=0xfd;//个位位选
delay1(5);
P2=0xfe;//选手位选
delay1(5);
suo=0;
}
4位七段数码管显示电路如图4所示。
图5..共阴极数码管
2.1.5键盘扫描电路的设计
键盘扫描电路分为独立式和矩阵键盘在选手按键的时侯可以选择矩阵键盘,也可以选择独立键盘,但是在这里没有必要选择矩阵式键盘,当选择矩阵键盘时,选手个数可以达到16个。
键盘点路图如下:
图6..抢答按键及调整按键
在图5中8个选手按键分别接入单片机的P1.0~P1.7端口,然后通过反相器连到P3口的中断0端口,单片机通过读取P1.0~P1.7的值来判断当前输入的是8个抢答按键中的哪一个。
然后出发一次中断,抢答时间调整和回答时间调整接到单片机的P3.3和P3.4接口,加一及减一按键接到单片机的P3.5和P3.6接口。
图7..开始、结束按键
在图6中,开始及结束按键接到单片机的10、11脚,这里用到了单片机10、11脚复合功能中的IO端口功能,单片机通过读取10、11脚的P3.0、P3.1的IO端口值来判断当前是否处于抢答开始状态或抢答结束状态。
按键的触点在闭合和断开时均会产生抖动,这时触点的逻辑电平是不稳定的,如不妥善处理,将会引起按键命令的错误执行或重复执行。
现在一般均用软件延时的方法来避开抖动阶段,这一延时过程一般大于5ms,例如取10-20ms。
如果监控程序中的读键操作安排在主程序(后台程序)或键盘中断(外部中断)子程序中,则该延时子程序便可直接插入读键过程中。
如果读键过程安排在定时中断子程序中,就可省去专门的延时子程序,利用两次定时中断的时间间隔来完成抖动处理。
在键盘扫描电路中开始按键和选手按键都通到了中断0,当开始键和选手按键按下是都会触发一次中断,然后扫描按键判断是哪一个按键按下的,如果是选手按下抢答按键时则非法处理,如果时主持人按下时则按照正常的抢答流程进行抢答。
51单片机大外部中断经过初始化后,当外部引脚变为低电平后片出发一次中断。
中断处理函数如下:
voidinit()//中断定时器初始化函数
{
TMOD=0x01;
EA=1;
TH0=0x3C;
TL0=0xB0;
ET0=1;
EX0=1;
IT0=1;
EX1=1;
}
voidint0()interrupt0//中断0函数
{
temp=1;
}
中断1为判断主持人停止键,当主持人在答题时间按下停止时,答题变立刻停止,
voidint1()interrupt2//中断0函数
{
temp_int0=1;
}
2.1.6报警电路
我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单片机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调,使喇叭发出不同的声音。
当在最后的5秒的时侯蜂鸣器变产生报警,以提醒选手们抢答时间或答题时间将要结束了。
报警程序如下:
If(t==5)
{
Beep=1;
}
当有选手提前答题的时候蜂鸣器便持续发出响声。
本文设计如图8所示。
图中单片机的14脚输出具有复合功能,此处用到了单片机17脚的IO端口功能,单片机通过内部定时器的操作实现交替变换的波形输出驱动扬声器发声。
图8报警电路
2.1.7系统复位设计
使CPU进入初始状态,从0000H地址开始执行程序的过程叫系统复位。
从实现系统复位的方法来看,系统复位可分为硬件复位和软件复位。
硬件复位必须通过CPU外部的硬件电路给CPU的RESET端加上足够时间的高电位才能实现。
上电复位,人工按钮复位和硬件看门狗复位均为硬件复位。
硬件复位后,各专用寄存器的状态均被初始化,且对片内通用寄存器的内容没有影响。
但是,硬件复位还能自动清除中断激活标志,使中断系统能够正常工作,这样一个事实却容易为不少编码人员所忽视。
软件复位就是用一系列指令来模拟硬件复位功能,最后通过转移指令使程序从0000H地址开始执行。
对各专用寄存器的复位操作是容易的,也没有必要完全模拟,可根据实际需要去主程序初始化过程中完成。
而对中断激活标志的清除工作常被遗忘,因为它没有明确的位地址可供编程。
有的编程人员用020000(LJMP0000H)作为软件陷阱,认为直接转向0000H地址就完成了软件复位,就是这类错误的典型代表。
软件复位是使用软件陷阱和软件看门狗后必须进行的工作,这时程序出错完全有可能发生在中断子程序中,中断激活标志已置位,它将阻止同级中断响应。
由于软件看门是高级中断,它将阻止说要中断响应,由此可见清除中断激活标志的重要性。
在所有的指令中,只有RETI指令能够清除中断激活标志。
出错处理程序ERR主要完成这一功能,其他的善后工作交由复位后的系统去完成。
程序一般先关中断,以便后续处理能顺利进行,然后用两个RETI指令代替两个LJMP指令,从而清除了两级中断激活标志。
有相应软件陷阱捕捉来的程序可能没有全部激活两个标志,这也无妨。
有复位时系统的历史状况,可将复位分为“冷启动”和“热启动”。
“冷启动”时,系统的状态全部无效,进行彻底的初始化操作;而“热启动”时,对系统的当前状态进行修复和有选择的初始化。
系统初次上电投入运行时,必须是“冷启动”,以后由抗干扰措施引起的复位操作一般均为“热启动”初次上电投入运行时,必须是“冷启动”,以后由抗干扰措施引起的复位操作一般均为“热启动”。
为了使系统能正确决定采用何种启动方式,常用上电标志来区分,如图9所示:
图9系统复位策略图
2.2系统整体硬件电路
2.2.1整体硬件电路
PROTEL是PORTEL公司推出的EDA软件,在电子行业的CAD软件中,它当之无愧地排在众多EDA软件的前面,是电子设计者的首选软件,它较早就在国内开始使用,在国内的普及率也最高,有些高校的电子专业还专门开设了课程来学习它,几乎所有的电子公司都要用到它,许多大公司在招聘电子设计人才时在其条件栏上常会写着要求会使用PROTEL。
它包含了电原理图绘制、模拟电路与数字电路混合信号仿真、多层印制电路板设计(包含印制电路板自动布线)、可编程逻辑器件设计、图表生成、电子表格生成、支持宏操作等功能,并具有Client/Server(客户/服务器)体系结构,同时还兼容一些其它设计软件的文件格式,如ORCAD,PSPICE,EXCEL等,其多层印制线路板的自动布线可实现高密度PCB的100%布通率。
1、运用PROTEL工具画出原理电路:
图11整体电路图
图12PCB电路图
2、三维PCB图
图13三维PCB图
2.2.1本章小结
本章是抢答器的系统仿真部分,并对抢答器的各个流程做出了具体仿真结果。
从仿真图上可以进一步得出结论:
利用单片机设计的抢答器工作性能稳定,延迟时间小,电路结构简单,是一个实用、创新性的电路设计。
3.软件设计
3.1系统主程序设计
为了能够达到抢答的公平、公正、合理,应该在主持人发布抢答命令之前必须先设定抢答的时间,因而在编开始抢答前的程序得先编写设定时间的程序,当时间设好了之后,主持人发布抢答命令按下P1.7按键,程序开始打开定时中断开始倒计时,然后调用键盘扫描子程序,编写键盘扫描程序。
当在扫描到有人按下了答题键,马上关闭T0、调用显示程序、封锁键盘。
主程序流程图:
图14
3.2主程序清单
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitsuo=P2^4;
sbitbeep=P2^7;
sbitwei1=P2^0;
sbitwei2=P2^1;
sbitwei3=P2^2;
sbitled=P0;
sbitkai=P3^2;
sbittin=P3^3;
sbitjiaf=P3^0;
sbitjianf=P3^1;
sbitjias=P3^5;
sbitjians=P3^6;
sbitque=P3^7;
sbitxuanshou=P2^5;
sbitxx=P2^6;
#include"wenjian.h"
ucharcodetale[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x71};
ucharfen1=20,fen2=20,fen3=20,fen4=20,fen5=20,fen6=20,fen7=20,fen8=20;
ucharscore_one=1,score_two=2,score_three=3,score_four=4;
ucharscore;
uchartemp,t;
ucharf;
ucharque1=0;
uchartime1=10,time2=10;
uchartemp_int0;
voiddelay1(uintz)//延时函数
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidinit()//中断定时器初始化函数
{
}
voidint0()interrupt0//中断0函数
{
temp=1;
}
voidint1()interrupt2//中断0函数
{
temp_int0=1;
}
voidtime0(void)interrupt1//计数器0中断,设置计数器计数,50ms中断
{
t++;
}
voiddisplay(ucharbaiwei,shiwei,gewei,xuanshou)//显示函数
{
suo=1;
P2=0xf7;//打开显示时间十位的位选
delay1(5);
P2=0xfb;//打开显示时间十位的位选
delay1(5);
P2=0xfd;//个位位选
delay1(5);
P2=0xfe;//选手位选
delay1(5);
suo=0;
}
ucharpanduan()//判断是哪一个选手按下键
{
uchari=0,b=0;
if(kai==0)
b=9;
switch(P1)
{
case0xfe:
b=1;break;
case0xfd:
b=2;break;
case0xfb:
b=3;break;
case0xf7:
b=4;break;
case0xef:
b=5;break;
case0xdf:
b=6;break;
case0xbf:
b=7;break;
case0x7f:
b=8;break;
}
returnb;
}
ucharfenshu(ucharb,h)//b为选手所选的分数,h为对应的选手号//
{
ucharx;
while(xx==1&&temp_int0==0);
if(jiaf==0&&temp_int0==0)
{
delay1(10);
if(jiaf==0)
{
switch(h)
{
case1:
fen1=fen1+b;x=fen1;break;
case2:
fen2=fen2+b;x=fen2;break;
case3:
fen3=fen3+b;x=fen3;break;
case4:
fen4=fen4+b;x=fen4;break;
case5:
fen5=fen5+b;x=fen5;break;
case6:
fen6=fen6+b;x=fen6;break;
case7:
fen7=fen7+b;x=fen7;break;
case8:
fen8=fen8+b;x=fen8;break;
}
}
}
if(jianf==0&&temp_int0==0)
{
delay1(10);
if(jianf==0)
{
switch(h)
{
case1:
fen1=fen1-b;x=fen1;break;
case2:
fen2=fen2-b;x=fen2;break;
case3:
fen3=fen3-b;x=fen3;break;
case4:
fen4=fen4-b;x=fen4;break;
case5:
fen5=fen5-b;x=fen5;break;
case6:
fen6=fen6-b;x=fen6;break;
case7:
fen7=fen7-b;x=fen7;break;
case8:
fen8=fen8-b;x=fen8;break;
}
}
}
returnx;
}
voidma(uchara)
{
ucharh;
uchars;
uchartemp2;
suo=0;
s=time2;
h=a;
/*switch(a)
{
case1:
fen=fen1;break;
case2:
fen=fen2;break;
case3:
fen=fen3;break;
case4:
fen=fen4;break;
case5:
fen=fen5;break;
case6:
fen=fen6;break;
case7:
fen=fen7;break;
case8:
fen=fen8;break;
}*/
temp2=P0&0xf0;
while(temp2==0xf0&&temp_int0==0){temp2=P0&0xf0;}
if(temp2!
=0xf0&&temp_int0==0)
{
delay1(10);delay1(10);
if(temp2!
=0xf0)
{
switch(temp2)
{
case0xe0:
score=score_one;break;
case0xd0:
score=score_two;break;
case0xb0:
score=score_three;break;
case0x70:
score=score_four;break;
}
TR0=1;
while(s>0&&que1==0&&temp_int0==0)
{
if(t==20)
{
t=0;s--;
if(s==0)
{ET0=0;f=fenshu(score,h);que1=1;TR0=0;break;}
}
if(xuanshou==0)
{
delay1(20);
if(xuanshou==0)
{
que1=1;
f=fenshu(score,h);TR0=0;break;
}
}
display(tale[s%100%10],tale[s%100/10],tale[s/100],tale[a]);
}
que1=0;
while(temp_int0==0)display(tale[f%100%10],tale[f%100/10],tale[f/100],tale[a]);
}
}
}
voidpanduan1()
{
uchari;
uchartemp2;
uchartemp1;
ucharbiao=0;
temp2=time1;
temp_int0=0;
if(temp==1&&temp_int0==0)
{
temp=0;
temp1=panduan();
switch(temp1)
{
case9:
temp1=0;
while(temp2>0&&biao==0&&temp_int0==0)
{
temp1=panduan();
switch(temp1)
{
case0:
break;
case1:
{display(tale[10],tale[10],tale[10],tale[1]);ET0=0;ma
(1);biao=1;break;}
case2:
{display(tale[10],tale[10],tale[10],tale