一.系统设计依据

抢答器由计数器、寄存器、集成定时器和译码显示等组合、时序电路组成。可分为抢答电路,定时电路,报警电路等几个单元部分。每个单元电路分别可以处理一些抢答竞赛中的基本问题。 本次课程设计设计的是一个多路定时抢答器,是一个多于两位选手参赛的一个抢答器,具有锁存和显示功能。

同时有主持人控制系统的清零和抢答的开始。抢答开始后,若有任何一名选手按动抢答按钮,抢答器就会显示该选手编号直至系统被主持人清零,并有扬声器发出提示,同时其他人再抢答就无效了。这次设计的抢答器还有自动定时功能,主持人可以设定选手答题的时间。当主持人启动“开始”键后,定时器会自动减计时,这个会显示在显示器上。选手只有在抢答时间内抢答才有效,若在答题时间内没有选手答题,时间到时,报警电路就会发出警报亮灯并且禁止抢答。

二. 设计目的

通过设计学习单片机最小系统的基本设计方法,掌握单片机应用系统的开发调试过程。

(1)学习单片机开发工具功能、特点和使用方法。

(2)学会单片机控制系统程序的编制和编制和调试方法。

(3)设计单片机抢答器硬件电路,绘制出电路原理图。

(4)编制并调试出键盘扫描程序和显示驱动程序。

(5)掌握单片机定时器的基本用法,编制出定时器的中断程序。

三.系统工作介绍

本系统采用单片机作为整个控制核心。控制系统主要由:显示模块、控制模块、报警模块、抢答模块组成。工作时,该系统通过矩阵键盘输入抢答信号,经单片机的处理,输出控制信号,利用一个4位数码管来完成显示功能并伴随蜂鸣器报警,用按键来让选手进行抢答,在数码管上显示哪一组先答题,从而实现整个抢答过程。

当主持人按下开始键时,向单片机P3.2引脚输入一个低电平信号,表示整个电路开始工作,此时数码管前两位显示选手编号(无人抢答显示00),后两位显示倒计时剩余时间。若在25秒内仍然无人抢答,蜂鸣器在最后5秒发出连续报警,提示抢答时间快要结束;若在30秒内有人抢答,并且抢答成功,则将选手编号显示在数码管前两位上,后两位显示抢答剩余时间,同时蜂鸣器发出一声报警,提示其他没有抢答的选手此题已被人抢答成功。若在抢答过程中遇见特殊情况,主持人则可以通过时间加,时间减按键来进行时间调节。若要开始新的一轮抢答,主持人按下复位键再按开始键即可。

此次用单片机控制的抢答器思路简单明了,可操作性强,可靠性高,扩展功能强,能够完全实现普通抢答器的基本功能。

【IoT】抢答器设计_数码管


图2-1 单片机抢答器设计方案


四.抢答器的原理

抢答器的工作原理是采用单片机最小系统,用程序查询方式采用动态显示组号。主持人按下开始抢答键才可以抢答。主持人没有按下开始抢答按纽(P3.0),有人抢答则抢答违规,报警并显示组号,主持人按下开始抢答开关重新抢答。主持人按下开始抢答按纽(P3.0),蜂鸣响声提示,数码管30秒倒计时抢答,蜂鸣器响声提示并显示他的组号,30秒内有人抢答则开始60秒倒计时(60秒内必须回答完问题),最后五秒倒计时警报。单片机最小系统、抢答按键模块(四位并行数码显示)、显示模块、显示驱动模块、抢答开关模块、蜂鸣器音频输出模块。

五. 程序代码


主程序

void main()

{

init();

if(k==0) //主持人按下开始键

{

Timer();

delay(10);

while(!k);

while(1)

{

dis();

m=0;

n=0;

if(secnotallow==10){beep=1;delay(500);beep=0;}

if(secnotallow==0) {

TR0=0;n=1;

if(k==0)

{beep=1;delay(500);beep=0;secnotallow=29;TR0=1;m=1;}

}

if(n==0)

{

if(k1==0) {delay(5);if(k1==0);while(!k1);t=1;}

else if(k2==0) {delay(5);if(k2==0);while(!k2);t=2;}

else if(k3==0) {delay(5);if(k3==0);while(!k2);t=3;}

else if(k4==0) {delay(5);if(k4==0);while(!k2);t=4;}

else if(k5==0) {delay(5);if(k5==0);while(!k2);t=5;}

else if(k6==0) {delay(5);if(k6==0);while(!k2);t=6;}

else if(k7==0) {delay(5);if(k7==0);while(!k2);t=7;}

else if(k8==0) {delay(5);if(k8==0);while(!k2);t=8;}

else if(k==0) {delay(5);if(k==0);while(!k);t=0;i=0;secnotallow=29;beep=1;delay(500);beep=0;TR0=1;}

}

while(t)

{

if(m==0) //开关,保证程序只执行一次

{

switch(t)

{

case 1:

{

TR0=0;i=1;secnotallow=0;beep=1;delay(500);beep=0;

a1=0;a2=1;a3=1;a4=1;a5=1;a6=1;a7=1;a8=1;m=1;break;

}

case 2:

{

TR0=0;i=2;secnotallow=0;beep=1;delay(500);beep=0;

a2=0;a1=1;a3=1;a4=1;a5=1;a6=1;a7=1;a8=1;m=1;break;

}

case 3:

{

TR0=0;i=3;secnotallow=0;beep=1;delay(500);beep=0;

a3=0;a1=1;a2=1;a4=1;a5=1;a6=1;a7=1;a8=1;m=1;break;

}

case 4:

{

TR0=0;i=4;secnotallow=0;beep=1;delay(500);beep=0;

a4=0;a1=1;a2=1;a3=1;a5=1;a6=1;a7=1;a8=1;m=1;break;

}

case 5:

{

TR0=0;i=5;secnotallow=0;beep=1;delay(500);beep=0;

a5=0;a1=1;a2=1;a3=1;a4=1;a6=1;a7=1;a8=1;m=1;break;

}

case 6:

{

TR0=0;i=6;secnotallow=0;beep=1;delay(500);beep=0;

a6=0;a1=1;a2=1;a3=1;a4=1;a5=1;a7=1;a8=1;m=1;break;

}

case 7:

{

TR0=0;i=7;secnotallow=0;beep=1;delay(500);beep=0;

a7=0;a1=1;a2=1;a3=1;a4=1;a5=1;a6=1;a8=1;m=1;break;

}

case 8:

{

TR0=0;i=8;secnotallow=0;beep=1;delay(500);beep=0;

a8=0;a1=1;a2=1;a3=1;a4=1;a5=1;a6=1;a7=1;m=1;break;

}

}

}



if(a1==0) //选手1的分数

{ secnotallow=score1;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score1+=1;if(score1==99)score1=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score1-=1;if(score1==0)score1=60;}

dis();

}


else if(a2==0)

{ secnotallow=score2;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score2+=1;if(score2==99)score2=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score2-=1;if(score2==0)score2=60;}

dis();

}


else if(a3==0)

{ secnotallow=score3;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score3+=1;if(score3==99)score3=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score3-=1;if(score3==0)score3=60;}

secnotallow=score3;

dis();

}


else if(a4==0)

{

secnotallow=score4;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score4+=1;if(score4==99)score4=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score4-=1;if(score4==0)score4=60;}

secnotallow=score4;

dis();

}


else if(a5==0)

{

secnotallow=score5;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score5+=1;if(score5==99)score5=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score5-=1;if(score5==0)score5=60;}

secnotallow=score5;

dis();

}


else if(a6==0)

{

secnotallow=score6;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score6+=1;if(score6==99)score6=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score6-=1;if(score6==0)score6=60;}

secnotallow=score6;

dis();

}


else if(a7==0)

{

secnotallow=score7;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score7+=1;if(score7==99)score7=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score7-=1;if(score7==0)score7=60;}

secnotallow=score7;

dis();

}


else if(a8==0)

{

secnotallow=score8;

dis();

if(m1==0) {delay(5);if(m1==0);while(!m1);beep=1;delay(100);beep=0;score8+=1;if(score8==99)score8=60;}

else if(m2==0) {delay(5);if(m2==0);while(!m2);beep=1;delay(100);beep=0;score8-=1;if(score8==0)score8=60;}

secnotallow=score8;

dis();

}


if(k==0){i=0;t=0;secnotallow=29;beep=1;delay(500);beep=0;TR0=1;}

while(!k);


}


}

}

}


定时器子程序

void Timer()

{

TMOD|=0x01;

TH0=0xd8; //初值55536,计数10000次,每次1US,总计10ms

TL0=0xf0;

IE=0x82; //这里是中断优先级控制EA=1(开总中断),ET0=1(定时器0允许中断),这里用定时器0来定时

TR0=1;

}


void tim(void) interrupt 1 using 1 //为定时中断TR0

{

TH0=0xd8; //重新赋值

TL0=0xf0;

count++;

if(count==100) //100*10ms=1秒

{

count=0;

second--; //秒减1

}

}


延时子程序

void delay(uint z) //延时函数

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}


显示子程序

void display (uchar shiwei,gewei,xuanshou) //显示函数

{

P2=0xfe; //打开显示时间十位的位选

P0=shiwei;//显示十位

delay(5);


P2=0xfd; //个位位选

P0=gewei;

delay(5);


P2=0xf7; //选手位选

P0=xuanshou;

delay(5);

}​