//*******************
// 四路抢答器
//*******************
//功能:主持人按下k0(启停),启动后高位显示"E"
// 只要有人抢答就显示组号,并发出声音
//*********************
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
sbit beep=P3^3; //蜂鸣器端口
sbit k0=P3^2; //主持人启停按钮
bit bz ,qt; //bz=1表示有人抢答,qt=1表示允许抢答,
uchar zu,key; //
uint n;//
//===================
//延时子程序
//===================
void delay(uint tt)
{
uint s;
for(;tt>0;tt--)
for(s=123;s>0;s--);
}
//========================
//显示子程序:显示抢答的组号
//=======================
void disp()
{ P0=tab[zu]; //显示对应组号
P2=0xf7; //个位
delay(3);
P2=0xff; //关闭
if(qt)P0=tab[14]; // 若qt=1;千位显示“E” 表示启动
else P0=tab[15]; //否则 千位显示“F” 表示停止
P2=0xfe; //千位
delay(3);
P2=255; //关闭
}
//========================
//启、停按钮检测程序
//=======================
bit testk0()
{
k0=1;
if(!k0)
{disp();
if(!k0)
{qt=!qt;} //启停标志,qt=1表示允许抢答
while(!k0) //等待松开
disp();
}
return qt;
}
//===========
//抢答按钮检测程序
//============
void testkey()
{
P3|=0xf3; //11110011 屏蔽3.2 3.3
if((P3&0xf3)!=0xf3) //有键按下
{key=P3; //将P3键值送KEY缓存
key|=0x0c; //补一,便于计算
switch(~key)
{
case 0x10:zu=1;bz=1;break; //3.4按下显示1
case 0x20:zu=2;bz=1;break; //3.5按下显示2
case 0x40:zu=3;bz=1;break; //3.6按下显示3
case 0x80:zu=4;bz=1;break; //3.7按下显示4
default:break; //其他情况,跳出
}
EA=1; //开中断,蜂鸣器发声
while(bz) //bz=1表示有人抢答,则
{disp(); //显示
testk0(); //再检测启停按钮,当主持人再按下就清零
bz=qt; //当qt=0是,bz=0 跳出循环
}
bz=0;zu=0;//清零复位
EA=0; //,关中断
beep=1;
}
}
//===============
//主程序
//==============
void main()
{ beep=1; //蜂鸣器制1,关闭
n=0;
zu=0; //组号为0
bz=0; //标志=0表示关闭
TH0=0xFE; //
TL0=0x0c; //中断产生1KHZ信号,用来驱动蜂鸣器
EA=0; //
ET0=TR0=1;
TMOD=1;//
while(1)
{
disp(); //显示
if(testk0()) //当K0按下后,bz=1时
{testkey();} //执行检测抢答按键子程序
}
}
//====================
// 蜂鸣器1khz发生中断T0
//====================
void time0() interrupt 1
{
TH0=0xFe; //
TL0=0x0c; // 0.5ms T=1mS
beep=!beep; //产生高低变化信号
n++; //计算叫的次数
if(n==2000) //叫2000次
{n=0;EA=0;beep=1;} //关闭发声,关闭中断
}
//===========================