产品选型

基于单片机的八路抢答器 单片机实例分享,如何设计八路抢答器

小编 2024-11-24 产品选型 23 0

单片机实例分享,如何设计八路抢答器

单片机作为可编程器件,简化了电路的设计、方便了逻辑设计,从此再也不用使用一大堆电路做硬件逻辑了。拆开任何一件功能稍微复杂一点电子产品,里边都可以看到单片机的身影。学会单片机对找工作也很有利,而且待遇还不错,今天就从实例分享的角度和大家共享一个案例,用单片机来实现一个抢答器。

在电视节目中,经常看到抢答器出现在知识竞赛、答题竞赛节目中,如江苏卫视的《一站到底》,抢答器可以准确、公正、直观、公平的显示出抢答选手的编号,可以更好的促进各选手之间的竞争意识,营造紧张的抢答气氛,增加节目的趣味性和观赏性。

抢答器的设计框图

抢答器要实现如下功能:抢答功能、显示功能、倒计时功能、自锁功能。节目后台需要控场,拥有抢答器的绝对控制权。功能需求 如下:

开始、结束功能 :只有按下开始按键后,现场选手才可以开始抢答,否则抢答事件不被处理视为无效;

自锁、互锁功能 :为了保证抢答的公平性,在开始抢答后,第一个按下抢答的视为有效抢答,产生有效抢答后其他抢答视为无效;计时、设置功能 :后台/主持人可以设置抢答时间的长短,以倒数秒的方式显示,增强紧张气氛;显示、声音功能 :用数码管显示倒计时秒数,选手抢答成功后显示抢答者编号和剩余时间;

在该设计中,按键采用机械式的四腿按键来实现,按键数量10个;显示采用三位数码管来实现,两位显示时间,一位显示选手编号;声音提示用蜂鸣器来实现。核心器件采用51单片机来实现。其功能框图如下图所示。

1-抢答器功能框图

按键输入电路设计

该抢答器设计中总共有10个按键,其中8个按键用于给用户抢答用,所代表的编号为1-8,另外两个按键分别为开始键和结束键,由主持人或者后台控制。由于8路输入抢答按键具有互锁功能,所以只要有一个有效输入后,其他抢答都是无效的,这个功能可以在程序中实现,为了方便程序设计,这里采用8输入与非门来实现,所用型号为74LS30,该与非门有8路输入,1个输出,功能框图如下所示。

2-74LS30与非门框图

8个按键作为74LS30的输入,输出通过NPN三极管接入51单片机的外部中断0接口,以中断的方式实现按键功能的检测,单片机的中断资源为低电平有效,为了提高电路稳定性在三极管的集电极上加入上拉电阻,以防误动作。

3-按键输入电路设计

开始和结束两个按键采用独立式按键设计,占用掉单片机的两个IO口,程序中采用轮询来实现。

数码管显示电路设计

显示部分采用数码管来实现,根据设计要求,两位用于显示倒计时时间,最大可以显示99;一位用于显示选手编号,故需要3颗数码管,该设计中采用共阳数码管来实现,所谓共阳数码管是指公共端接高电平,段选管脚接低电平后相应的字段才会被点亮。共阴数码管正好相反,公共端接低电平,段选管脚接高电平后相应的字段才会被点亮。数码管的实物图如下所示。

4-数码管实物图

数码管的引脚比较多,除了8个段选管脚外,还有公共端/位选引脚,如果用三颗独立的数码管可能需要较多单片机引脚资源,为了解决这个问题,本例设计采用74HC595作为数码管驱动。74HC595是串入并出的移位寄存器,只需要三个引脚就可以控制8个引脚的输出,而且还可以实现级联。所以74HC595通常在数码管驱动和点阵屏中应用比较多。

这三颗数码管中,分为时间显示和编号显示两组,用到三颗74HC595,其中两颗级联用于控制时间显示的数码管,总共用到6个单片机的IO口,驱动电路如下图所示。

5-数码管驱动电路

蜂鸣器发声电路设计

需求中提到发声设计,当有效按键事件发生时,蜂鸣器发声作为提示音,当倒计时进入5秒之内后还没有人按键抢答时,蜂鸣器每隔1秒发声,制造现场紧张的气氛,提高节目的观赏性和娱乐性,增强节目效果。本例中选择了蜂鸣器,蜂鸣器驱动电路如下图所示。

6-蜂鸣器驱动电路

由于单片机的IO口驱动能力有限,所以采用三极管来驱动,这里选用了PNP三极管。三极管驱动蜂鸣器时工作于饱和状态,为了让三极管充分饱和,将蜂鸣器接在了三极管的集电极,这个地方初学者在设计电路时要注意。图中当单片机的IO口输出低电平时蜂鸣器工作发声。

抢答器程序设计

该设计使用keil5作为编程环境,涉及到数码管显示、按键检测/互锁、蜂鸣器发声、定时器等相关功能模块的程序编写。程序设计的流程图如下所示。

7-程序设计流程图

程序的功能逻辑介绍如下,上电后数码管显示FFF字样,并首先检测“开始”按键是否按下,如果没有按下开始按键则表示抢答未开始。如果按下了开始按键,抢答器启动,秒显示开始倒计时,有人按下抢答键时蜂鸣器发声、倒计时停止并显示抢答者编号,整个抢答事件结束,直到主持人/后台按下结束按键后再显示FFF。如果倒计时进入5秒内,仍未有人抢答,则每个整秒蜂鸣器响一次,直至结束。

以上为程序逻辑设计和程序的流程图讲解,下面介绍各功能模块的程序设计。

首先介绍数码管的程序编写 ,再编写程序时,都会预先定义好数码管的字段表,根据共阳数码管和共阴数码管的不同,其字段表也是不一样的,但是两者是互补的,数码管可显示的字段表如下图所示。

8-数码管字段表

程序代码如下:

/*共阳数码管的0-9数字字码表*/

uchar code seg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x8e,0xff};

其次是按键部分 ,抢答按键采用中断来实现,开始/结束按键采用轮询实现,部分定义代码如下所示。

//定义抢答按键

sbit KEY_1=P0^0; //1

sbit KEY_2=P0^1; //2

sbit KEY_3=P0^2; //3

sbit KEY_4=P0^3; //4

sbit KEY_5=P0^4; //5

sbit KEY_6=P0^5; //6

sbit KEY_7=P0^6; //6

sbit KEY_8=P0^7; //6

//定义开始/结束按键

sbit START = P2^4;

sbit STOP = P2^5;

仿真电路的设计和验证

在做板子之前,先用Proteus仿真软件做了仿真。Proteus仿真支持51单片机并可以实现运行程序的功能,当把程序写好后加载至Proteus即可实现程序的调试,Proteus还可以与Keil软件实现联调功能。所设计的仿真电路如下图所示。

9-仿真电路-初始显示FFF字样

在上电初期,显示“FFF”字样,前两个数码管代表倒计时时间,后一个数码管代表抢答者的编号。按下开始按键后,抢答器开始工作,如下图所示。

10-抢答成功界面

上图表示,在倒计时时间还有7秒的时候,5号选手完成了有效抢答,直至主持人/后台按下结束后再显示FFF,否则一直显示该界面。

抢答器的焊接调试

为了实现功能验证,选择用万用板手工焊接实现这个设计。最终的实物图如下所示:

11-最终实物图正面

电源供电为DC5V,可以使用电池盒供电,也可以选择5V输出的手机充电器供电,导线走在了电路板正面,虽然丑了点,但是方便一点。电路板的反面如下图所示。

12-最终实物图背面

反面是用焊锡连接实现的。由于功能不是很复杂,程序写完后,调试了没几次就完成了功能,前文中所描述的功能都实现了。按键互锁的功能也实现了。下图是通电运行的界面,表示5号抢答者在倒计时28秒的时候抢答成功,这时候其他抢答者的按键无效。只有开始或者结束按键是其作用的。

13-抢答成功界面

该抢答器的设计虽然是一个很简单的练手项目,但是却涉及到了单片机中最常用的外设电路,可以帮助初学者熟悉数码管、按键、蜂鸣器的使用和控制方法。初学者可以借助这个产品熟悉单片机开发过程中所用的各种软件和产品开发的流程。

对这个电路进行PCB Layout,设计个外壳就成了一个不错的产品。还可以增加蓝牙模块或者WiFi模块,实现电子屏的控制和显示,再把功能完善一下,就可以用在舞台上了。

51单片机学习27-小设计之八路抢答器

这篇讲8路抢答器

硬件组成:单片机最小系统+数码管+按键+蜂鸣器

仿真图:

程序:

源代码:

#include<reg51.h>

#define uint unsigned int

#define uchar unsigned char

sbit D0=P0^0;//指示灯

sbit beep=P0^1;//蜂鸣器

sbit K0=P0^2;//开始抢答按键

sbit S1=P0^3;//答题计时键

sbit S2=P0^4;//开始抢答时间调整键

sbit S3=P0^5;//答题计时时间调整键

sbit K1=P2^0;//1号选手抢答按键

sbit K2=P2^1;//2号选手抢答按键

sbit K3=P2^2;//3号选手抢答按键

sbit K4=P2^3;//4号选手抢答按键

sbit K5=P2^4;//5号选手抢答按键

sbit K6=P2^5;//6号选手抢答按键

sbit K7=P2^6;//7号选手抢答按键

sbit K8=P2^7;//8号选手抢答按键

char s;

uchar num=0;

char time1;//抢答时间

char time2;//答题限时时间

uint m,n;//T0,T1定时器定一秒时

bit flag1,flag2,flag3,flag4;//标志位

bit aa,bb;//时间调整标志位

//延时子函数

void delay(uint z)

{

uint x,y;

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

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

}

uchar code table1[]={

//共阴数码管段码值

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

uchar code table2[]={

//共阴数码管位码值

0xf7,0xfb,

0xfd,0xfe

};

//初始化子函数

void init()

{

TMOD=0x11;

TH0=(65536-2000)/256;

TL0=(65536-2000)%256;

TH1=(65536-2000)/256;

TL1=(65536-2000)%256;

ET0=1;

ET1=1;

EA=1;

//P0=0x00;

P1=0x00;

time1=10;

time2=10;

flag2=1;

}

//开始键扫描子函数

void key1()

{

uchar i=100;

if(K0==0)

{

delay(10);

if(K0==0)

{

while(K0==0&&i)

{

i--;

delay(10);

}

TR0=1;

s=time1;

m=0;

flag1=1;

flag2=1;

flag3=1;

num=0;

beep=1;

D0=1;

flag4=0;//清除违规标志位

aa=0;

bb=0;

}

}

}

//选手抢答按键扫描子函数

void key()

{

uchar i=100;

if(K1==0)

{

delay(10);

if(K1==0)

{

while(K1==0&&i)

{

i--;

delay(10);

}

num=1; //数码管显示1号"1"

TR0=0; //关闭定时器0,时间停止

TR1=1; //打开定时器1,使扬声器响一声

flag2=0;//关闭开始键标志位,使再按其他七个键不会响应

}

}

if(K2==0) //下面七个键的处理同上

{

delay(10);

if(K2==0)

{

while(K2==0&&i)

{

i--;

delay(10);

}

num=2;

TR0=0;

TR1=1;

flag2=0;//重要

}

}

if(K3==0)

{

delay(10);

if(K3==0)

{

while(K3==0&&i)

{

i--;

delay(10);

}

num=3;

TR0=0;

TR1=1;

flag2=0;

}

}

if(K4==0)

{

delay(10);

if(K4==0)

{

while(K4==0&&i)

{

i--;

delay(10);

}

num=4;

TR0=0;

TR1=1;

flag2=0;

}

}

if(K5==0)

{

delay(10);

if(K5==0)

{

while(K5==0&&i)

{

i--;

delay(10);

}

num=5;

TR0=0;

TR1=1;

flag2=0;

}

}

if(K6==0)

{

delay(10);

if(K6==0)

{

while(K6==0&&i)

{

i--;

delay(10);

}

num=6;

TR0=0;

TR1=1;

flag2=0;

}

}

if(K7==0)

{

delay(10);

if(K7==0)

{

while(K7==0&&i)

{

i--;

delay(10);

}

num=7;

TR0=0;

TR1=1;

flag2=0;

}

}

if(K8==0)

{

delay(10);

if(K8==0)

{

while(K8==0&&i)

{

i--;

delay(10);

}

num=8;

TR0=0;

TR1=1;

flag2=0;

}

}

}

//数码管显示子函数

void display()

{

if(flag1==1) //开始键按下,开始计时抢答

{

if(num!=0)//如果有人抢答,则显示相应的几号

{

P1=table1[num];//显示几号抢到了

P3=table2[0];

delay(2);

P1=0;

P3=0xff;

}

else //否则没人抢答,则前面不显示几号

{

P1=0x00;

P3=0xff;

}

P1=table1[s/10]; //下面为显示抢答倒计时

P3=table2[2];

delay(2);

P1=0;

P3=0xff;

P1=table1[s%10];

P3=table2[3];

delay(2);

P3=0xff;

P1=0x00;

}

else //如果开始键没有按下,则显示F FF(若有违规者,则显示违规号码及 FF)或时间调整

{

if(flag4==1)//违规显示

{

if(num!=0)

{

P1=table1[num];//显示几号违规了

P3=table2[0];

delay(2);

P1=0x00;

P3=0xff;

P1=table1[15]; //下面显示 FF,表示违规了

P3=table2[2];

delay(2);

P1=0x00; //消隐

P3=0xff;

P1=table1[15];

P3=table2[3];

delay(2);

P1=0x00;

P3=0xff;

}

else

{

P1=0x00;

P3=0xff;

}

}

else//没有人违规才显示调整时间

{

if(aa==1)

{

P1=0x76; //第一位数码管显示"5(S)"(表示抢答时间调整)

P3=table2[0];

delay(2);

P1=0x00;

P3=0xff;

P1=table1[time1/10];//下面显示调整的抢答时间

P3=table2[2];

delay(2);

P1=0x00;

P3=0xff;

P1=table1[time1%10];

P3=table2[3];

delay(2);

P1=0x00;

P3=0xff;

}

else if(bb==1)

{

P1=0x38; //第一位与第二位数码管合起来显示"T",表示答题时间调整

P3=table2[0];

delay(2);

P1=0x00;

P3=0xff;

P1=table1[time2/10];

P3=table2[2];

delay(2);

P1=0x00;

P3=0xff;

P1=table1[time2%10];

P3=table2[3];

delay(2);

P1=0x00;

P3=0xff;

}

else //否则显示F FF

{

P1=table1[15];

P3=table2[0];

delay(2);

P1=0x00;

P1=table1[15];

P3=table2[2];

delay(2);

P1=0x00; //消隐

P3=0xff;

P1=table1[15];

P3=table2[3];

delay(2);

P1=0x00;

P3=0xff;

}

}

}

}

//调整时间键扫描子函数

void key2()

{

uchar i=100;

if(S2==0) //抢答时间调整

{

delay(10);

if(S2==0)

{

while(S2==0&&i)

{

i--;

delay(10);

}

time1++;

if(time1==61)

{

time1=10;

}

aa=1;//将抢答时间标志位置1

bb=0;//同时关闭答题时间标志位

}

}

if(S3==0) //答题时间调整

{

delay(10);

if(S3==0)

{

while(S3==0&&i)

{

i--;

delay(10);

}

time2++;

if(time2==61)

{

time2=10;

}

bb=1;

aa=0;

}

}

}

//主函数

void main()

{

uchar i=100;

init();//调用初始化子函数

while(1)

{

key1();//调用开始键扫描子函数

if((flag1==0)&(flag2==1))//当开始键没按下及没有人违规时才可进行时间调整

{

key2();

}

if((flag1==1)&(flag2==0))//当开始键按下及有人抢答才进行开始回答计时倒计时

{

if(S1==0)

{

delay(10);

if(S1==0)

{

while(S1==0&&i)

{

i--;

delay(10);

}

s=time2;

TR0=1;

m=0;

TR1=1;

}

}

}

if((flag1==0)&(flag2==1))//违规

{

key();

if(num!=0) //开始键没有按下时,有人按下了抢答器,则置违规标志位

{

flag4=1;

D0=0;

}

}

if((flag1==1)&(flag2==1))//如果开始键按下且抢答键没有人按下,则进行八路抢答键扫描

{

key();

}

display();//显示到数码管上

}

}

//定时器0中断子函数

void t0() interrupt 1

{

TH0=(65536-2000)/256;//2ms

TL0=(65536-2000)%256;

if(flag3)//开始(START)键按下,嘟一声(长1秒),表示开始抢答

{

beep=~beep;

}

else

beep=1;

if(s<5)//抢答时间快到报警,隔1秒响一声且红灯闪烁,响三声

{

if(s%2==0)

{

flag3=1;

D0=0;

}

else

{

flag3=0;

D0=1;

}

}

m++;

if(m==500) //1秒

{

m=0;

s--;

flag3=0;//关闭开始键按下响一秒的嘟声

if(s==-1)

{

s=20;

TR0=0;

flag1=0;//显示F FF

flag2=1;

num=0;

D0=1;

}

}

}

//定时器1中断子函数

void t1() interrupt 3//定时器1处理有人按下抢答器嘟一声(长1秒)

{

TH1=(65536-2000)/256;

TL1=(65536-2000)%256;

beep=~beep;

n++;

if(n==500)

{

n=0;

TR1=0;

}

}

仿真结果:

相关问答

单片机 四人 抢答器的 程序和连接方式?

先来个汇编的程序,P1接一个共阳极数码管,P0低4位接4个抢答按键,主持人复位采用单片机复位按钮实现。ORG0000HSTART:MOVA,P0...先来个汇编的程序,P1接一个...

单片机的 智能 抢答器 实现了什么?

智能抢答器实现了可以精准的抢答回答问题智能抢答器实现了可以精准的抢答回答问题

st89c52 单片机抢答器 按键功能?

抢答器的按键功能是通过按压接通电路,提供输入脉冲。抢答器的按键功能是通过按压接通电路,提供输入脉冲。

如何快速按 抢答器

抢答器由单片机以及外围电路组成,由于采用单片机,使得外围电路非常简单,但是功能并不比一般的抢答器少。功能描述如下:1、涵盖抢答题、抢答限时、...

单片机的 独立键盘有什么用?

很多的嵌入式或者单片机系统中,一般都需要向嵌入式或者单片机系统输入信息的外设,以及嵌入式或者单片机向外输出信息的外设我们常见的显示屏,数码管等就是嵌...

单片机 复位电路,按下k键电容C11为什么能放电?

我是电子及工控技术,我来回答这个问题。作为单片机最小系统之一的复位电路在单片机中占有很重要的位置,今天我就和朋友们聊聊这方面的事。复位电路介绍一般来...

单片机 p3口第二功能是什么(简答题) - 懂得

单片机P3口第二功能,各位定义如下:P3.0RXD(串行口输入);P3.1RXD(串行口输出);P3.2/INT0(外部中断0输入);P3.3/INT1(外部中断1输入);P3.4T0(P3口....

基于单片机的 电梯控制系统难不难做?

基于单片机的电梯控制系统,其原理实现并不难,通过采集按键选择停留的楼层,单片机系统结合楼层信息,控制电动机转动,控制电梯停留在相应的楼层。电梯控制系统...

目前常用的 单片机 型号有哪些?都有什么优缺点?

现在市场上的单片机型号可以说是非常多的,其中有通用型的单片机,还有专用型的单片机。专用型单片机一般我们不常见到。今天我们结合这个问题来介绍一下目前常...

单片机 技术是一门即将被淘汰的技术吗?

感谢邀请答题!目前来说,这十几年内是不可能淘汰的,即使面临着人工AI、大数据和云计算等技术的多方面竞争,单片机也可以说是立于不败之地!毕竟需求放在那里。...

猜你喜欢