八路抢答器
1、流程
裁判按下复位键,抢答器进入抢答模式,各组人员才可以通过抢答按钮进行抢答,抢答结果显示在抢答器上。
2、实现
使用单片机对输入的电平信号处理(低电平有效):1路为复位,8路为抢答。复位前对8路抢答状态进行判断,防止作弊。一次性对8路抢答器状态进行采样,将结果存储在num数组内,最大可存储4路同时抢答结果。LED显示部分由T0定时器每3ms动态将num数组的结果点亮。蜂鸣器的时长由T0定时器控制
3、原理图
4、代码
#include<AT89X51.H>
#include<stdio.H>
#include<stdlib.H>
sfr WDTRST = 0xA6;
#define OUTPORT1 P0
#define OUTPORT2 P2
#define BELL P3_5
#define CLR P3_4
#define INPORT P1
Static unsigned char code digital[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0xe1,0x91,0x88,0x86,0xa0,0xa1,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x58,0x00}; //字库码"0,1,2,3,4,5,6,7,8,j,y,r,e,a,d,0.,1.,2.,3.,4.,5.,6.,7.,8."
static unsigned char code select[]={0xff,0xfb,0xf7,0xef,0xdf}; //选位字码
static unsigned char rycle=0x00; //当前数码管显示位控制
static unsigned char data num[5]={0x4,0x0e,0x09,0x0A,0x09};//检测结果
static unsigned char data i,j;
static unsigned char data count;//蜂鸣器警报时长
static unsigned char bdata temp; //8位取样数据
static bit state=0x00 ;//复位状态保存
static unsigned int sum[]={0x00,0x00}; //复位键检测时间/自动复位的时长
static bit timeCLR=0x00;//自动复位状态
static bit stateCLR=0x00; //首次状态保留
void delay(char t);
void ready();
void init()
{
P0 = 0xff;
P1 = 0xff;
P2 = 0xff;
P3 = 0xFF;
EX0 = 0x00;
EX1 = 0x00;
ET1 = 0x00;
ES = 0x00;
ET2 = 0x00;
WDTRST = 0x1E;
WDTRST = 0xE1;
BELL = 0;
TMOD=0x11;
EA=0x01;
TR0=0x00;
ET0=0x00;
TL0=0x18; //T0=130ms
TH0=0x02;
count=0;
TL1=0x24; //T1=4.5ms
TH1=0xfa;
TR1=0x01;
ET1=0x01;
}
void belltime() interrupt 1
{
TL0+=0x18;
TH0+=0x02;
if(!count--)
{
BELL=0x00;
ET0=0x00;
TR0=0x00;
}
}
void display() interrupt 3
{
TL1+=0x24;
TH1+=0xFA;
if(rycle<=num[0])
{
OUTPORT1 = digital[num[rycle]];
OUTPORT2 = select[rycle];
++rycle;
}else rycle=0x00;
if(!CLR)
{
sum[0]++;
if(sum[0]>666&&stateCLR)
{
timeCLR=!timeCLR;
stateCLR=0;
state=!state; //避免按复位键超时,导致状态重复反转
}
}else
{
sum[0]=0;
stateCLR=1; //复位键退出,将状态设置为可复位状态
}
if(timeCLR&&!state)
{
if(sum[1]++>2333) //在有抢答结果的情况下,等待复位
{
if(temp==0xff) //防作弊
{
ready();
}else
{
sum[1]=2167-(int)666*rand(); //延迟0.5-2.5S
}
}
}else sum[1]=0;
}
void delay(char t)
{
count=t;
TL0=0x18;
TH0=0x02;
ET0=0x01;
TR0=0x01;
}
void main()
{
init();
while(1){
WDTRST=0x1E;
WDTRST=0xE1;
temp = INPORT; //对8个连接器同时采样
if(!CLR&&temp==0xff)
{
ready();
}
for(i=1,j=0;i<=8&&state;i++) //8个连接器状态检测
{
if(!(temp & 0x01))
{
j++;
num[0]=j; //num[0]存放首批按下的连接器个数
num[j]=(j>1?i+0x0f:i); //存放按下状态的连接器序列
BELL=0x01;
delay(1);
}
temp >>= 1;
}
if(j>0) state=0; //判断是否抢答成功,成功就禁止再次抢答
}
}
void ready()
{
num[0]=0x04;
num[4]=0x0b;
num[3]=0x0c;
num[2]=0x0e;
num[1]=0x0a;
state=0x01;
BELL=0x01;
delay(1);
}
5、成品效果