基于单片机的抢答器课程设计.docx
《基于单片机的抢答器课程设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的抢答器课程设计.docx(15页珍藏版)》请在冰豆网上搜索。
基于单片机的抢答器课程设计
基于单片机的智能抢答器的设计
1引言
抢答器是为各类竞赛参赛者答题时进行抢答而设计的一种优先判决器电路,广泛应用于各种知识竞赛、文娱活动等场合。
传统的抢答器大部分是基于数字电路组成的,制作过程复杂,且准确性与可靠性不高,受现场环境影响大,成品面积大,安装、维护困难。
对于目前抢答器的功能描述,如抢答限时、选手答题计时及犯规组号抢答器具有抢答自锁、灯光指示、暂停复位、电子音乐报时、自动定时、工作模式的切换和时间设定等功能。
本文介绍一种以51系列单片机为控制核心的智能型抢答器的电路组成、设计思路和功能。
该抢答器除具有基本的强大功能外,还具有计时和报警功能。
它对采样的各路抢答信号进行分析,识别超前违规信号、有效抢答信号,并对它们进行处理,从而使每一次抢答过程都有效,保证了抢答过程的快速性、有效性、准确性、公平性。
2设计方案及原理
抢答器设计方案
(1)抢答器同时供8名选手或8个代表队比赛,分别用8个按钮“1”~“8”表示。
(2)设置一个系统清除和抢答控制的“开始”开关,该开关由主持人控制。
(3)抢答器具有锁存与显示功能。
即选手按动按钮,锁存相应的编号,并在LED数码管上显示,同时扬声器发出报警声响提示。
选手抢答实行优先锁存,优先抢答选手的编号一直保持到主持人将系统清除为止。
(4)抢答器具有定时抢答功能,且一次抢答的时间由主持人设定(如30秒)。
当主持人启动"开始"键后,定时器进行减计时,同时扬声器发出短暂的声响以提示抢答开始。
(5)参赛选手在设定的时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答的时间,并保持到主持人将系统清除或者答题计时结束为止。
(6)如果定时时间已到,无人抢答,本次抢答无效,系统报警并禁止抢答,定时显示器上显示FF
抢答器设计原理
该抢答器供不多于8名选手或8个代表队的抢答比赛使用。
每个选手的座位前安装一只抢答按钮开关和一只信号灯。
主持人的座位前安装一只复原按钮开关、一只蜂鸣器和一只抢答器工作状态指示灯。
每当主持人口头发出允许抢答的号令并按下开始抢答按钮之后,哪个队先按下座位上的按钮开关,该座位的信号灯就先被点亮,同时封锁其他按钮开关的活动,并且熄灭主持人座位上的状态指示灯和发出提示声,以表明此次抢答动作已经完成。
在主持人确认后,按下复原按钮,状态指示灯重新点亮,为下一次的抢答作好准备。
电路中的蜂鸣器LS是一只带有助音腔的压电陶瓷蜂鸣器,用于模拟发出报警声的功率放大器和喇叭。
LS可以看作是一个电容性负载,本身不能流过直流电流。
发声的原理是,作用在两个电极极板的电位在发生变化时,陶瓷材料就发生弯曲,从而振动空气发出声音。
3系统硬件设计
单片机介绍
AT89C51单片机主要有以下部件构成:
八位微处理器CPU、振荡电路、总线控制部件、中断控制部件、片内Flash存储器、片内RAM、并行I/O接口、定时器和串行I/O接口。
AT89C51单片机内部由CPU、4KB的FPEROM,128B的RAM,两个16位的定时/计数器T0和T1,4个8位的I/O端P0、P1、P2、P3等组成。
单片微机内部最核心的部分是CPU。
AT89C51的只要引脚如图所示。
图3.1AT89C51引脚图
系统原理电路图
基于以上各个模块的设计,可以设计出系统原理电路图,P3.0为开始抢答,P3.1为停止,P1.0-P1.7为八路抢答输入,数码管段选P0口,位选P2口低3位,蜂鸣器输出为P3.6口,RST复位,XTAL1和XTAL2接晶振电路。
系统原理电路图如图所示。
图3.2系统原理电路图
4系统软件设计
为了能够达到抢答的公平、公正、合理,应该在主持人发布抢答命令之前必须先设定抢答的时间,因而在编开始抢答前的程序得先编写设定时间的程序,当时间设好了之后,主持人发布抢答命令按下按键,程序开始打开定时中断开始倒计时,然后调用键盘扫描子程序,编写键盘扫描程序。
当在扫描到有人按下了答题键,马上关闭T0、调用显示程序、封锁键盘。
系统流程图设计
系统流程图如图所示。
5总结
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握单片机的开发技术是十分重要的。
回顾起此次单片机课程设计,至今我仍感慨颇多,的确,从选题到定稿,从理论到实践,在短短一星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说三极管PNP管脚不懂怎么放置,不懂分得二极管的正负极,对单片机汇编语言掌握得不好……通过这次课程设计之后,一定把以前所学过的知识重新温故。
这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在梁强老师的辛勤指导下,终于游逆而解。
同时,在梁强老师的身上我学得到很多实用的知识,在次我表示感谢!
同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
6参考文献
[1]李华,王思明,张明敏.单片机及应用[M].兰州:
兰州大学出版社.2001.
[2][M].北京:
北京航天航空大学出版社.2004
[3]高伟.AT89单片机原理及应用[M].北京:
国防工业出版社.2008
附录(程序代码)
源程序代码如下:
#include
#defineuintunsignedint
#defineucharunsignedchar
unsignedcharcodetable[]={0x40,0x79,/*共阴极数码管编码表0-f显示*/
0x24,0x30,0x19,0x12,0x02,0x78,0x00,
0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
sbitstart=P3^6;/*变量定义*/
sbitstop=P3^5;
sbitreset=P3^7;
sbitkey1=P1^0;
sbitkey2=P1^1;
sbitkey3=P1^2;
sbitkey4=P1^3;
sbitkey5=P1^4;
sbitkey6=P1^5;
sbitkey7=P1^6;
sbitkey8=P1^7;
sbitbuzzer=P3^4;
bitstart_flag=0;
bitstop_flag=0;
bitkey1_flag=0;
bitkey2_flag=0;
bitkey3_flag=0;
bitkey4_flag=0;
bitkey5_flag=0;
bitkey6_flag=0;
bitkey7_flag=0;
bitkey8_flag=0;
bitreset_flag=0;
bitaction=0;
ucharsecond=20;
uchartimer0_count=0;
ucharnumber=0;
ucharnumber_display=0;
voiddelay(uintz)/*延时函数delay()*/
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddisplay(ucharnumber,ucharsecond)/*数码管显示驱动函数display()*/
{
ucharsecond_first,second_second;
second_first=second/10;
second_second=second%10;
P2=0xfe;
P0=table[number];
delay
(2);
P2=0xfd;
P0=0x3f;
delay
(2);
P2=0xfb;
P0=table[second_first];
delay
(2);
P2=0xf7;
P0=table[second_second];
delay
(2);
}
voidstart_keyscan()/*开始键扫描函数start_keyscan()*/
{
if(start==0)
{
delay(8);
if((start==0)&&(!
start_flag))
{
start_flag=1;
action=1;
TR0=1;
}
}
else
{
start_flag=0;
}
}
ucharkey_scan8()/*八位抢答键扫描函数key_scan8()*/
{
if(key1==0)
{
delay(8);
if((key1==0)&&(!
key1_flag))
{
key1_flag=1;
number=1;
number_display=number;
}
}
else
{
key1_flag=0;
number=0;
}
if(key2==0)
{
delay(8);
if((key2==0)&&(!
key2_flag))
{
key2_flag=1;
number=2;
number_display=number;
}
}
else
{
key2_flag=0;
number=0;
}
if(key3==0)
{
delay(8);
if((key3==0)&&(!
key3_flag))
{
key3_flag=1;
number=3;
number_display=number;
}
}
else
{
key3_flag=0;
number=0;
}
if(key4==0)
{
delay(8);
if((key4==0)&&(!
key4_flag))
{
key4_flag=1;
number=4;
number_display=number;
}
}
else
{
key4_flag=0;
number=0;
}
if(key5==0)
{
delay(8);
if((key5==0)&&(!
key5_flag))
{
key5_flag=1;
number=5;
number_display=number;
}
}
else
{
key5_flag=0;
number=0;
}
if(key6==0)
{
delay(8);
if((key6==0)&&(!
key6_flag))
{
key6_flag=1;
number=6;
number_display=number;
}
}
else
{
key6_flag=0;
number=0;
}
if(key7==0)
{
delay(8);
if((key7==0)&&(!
key7_flag))
{
key7_flag=1;
number=7;
number_display=number;
}
}
else
{
key7_flag=0;
number=0;
}
if(key8==0)
{
delay(8);
if((key8==0)&&(!
key8_flag))
{
key8_flag=1;
number=8;
number_display=number;
}
}
else
{
key8_flag=0;
number=0;
}
if(number_display!
=0)
{
return1;
}
else
{
return0;
}
}
voidreset_keyscan()/*复位键扫描函数reset_keyscan()*/
{
if(reset==0)
{
delay(8);
if((reset==0)&&(!
reset_flag))
{
reset_flag=1;
number_display=0;
second=20;
}
}
else
{
reset_flag=0;
}
}
voidfengming()/*蜂鸣函数fengming(),脉宽t=1ms周期T
{=2ms,频率f=0.5khz,用以报警*/
buzzer=0;/*给P3.7口送高电平*/
delay(100);/*延时1ms*/
buzzer=1;
delay(100);
}
voidmain()/*主函数main()*/
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=0;
while
(1)
{
start_keyscan();
reset_keyscan();
while(action==1)
{if(second<=5&&second>0)
fengming();
while(!
key_scan8()&&!
stop==0)
{
display(number_display,second);
if(second==0)
{
second=20;
break;
}
}
TR0=0;
display(number_display,second);
action=0;
break;
}
display(number_display,second);
}
}
voidtimer0()interrupt1/*中断服务函数timer0()interrupt1*/
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
timer0_count++;
if(timer0_count==20)
{
timer0_count=0;
second--;
if(second<=5&&second>0)
fengming();
if(second==0)
{
TR0=0;
number_display=0;
action=0;
}
}
}
仿真图
图1开始时仿真
图2抢答后仿真