基于51單片機(jī)的八路搶答器設(shè)計
基于51單片機(jī)的八路搶答器設(shè)計,基于,51,單片機(jī),八路,搶答,設(shè)計
//包含頭文件
#include
//宏定義
#define uchar unsigned char
#define uint unsigned int
sbit start=P3^0; //主持人按鍵開始
sbit reset=P3^1; //復(fù)位
sbit add1=P3^2; //搶答時間調(diào)整,加1
sbit dec1=P3^3; //搶答時間調(diào)整,減1
sbit add2=P3^4; //答題時間調(diào)整,加1
sbit dec2=P3^5; //答題時間調(diào)整,減1
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit k5=P1^4;
sbit k6=P1^5;
sbit k7=P1^6;
sbit k8=P1^7; //選手按鍵
sbit beep=P3^6; //蜂鳴器
bit qd; //搶答標(biāo)志位,=1時開啟搶答
bit dt; //答題標(biāo)志位,=1時開啟答題
bit disp_qd_dt; //顯示搶答還是答題時間標(biāo)志位,=0時是顯示搶答時間,=1時是顯示答題時間
//uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}; //0-9代碼
unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x45,0xDF,0xD7, 0xCE,0xC7,0xDC}; //數(shù)字0-9的編碼 和H q d
uchar shiwei,gewei,xuanshou,count,p,second;
uchar qd_time=30,dt_time=60; //搶答時間,默認(rèn)30S,答題時間,默認(rèn)60S
uint t,m,n,a,a1,a2,a3,a4,a5,a6,a7,a8;
void Timer()
{
TMOD=0x01; //定義工作方式
TH0=0x3C; //初值15536,計數(shù)50000次,每次1uS,總計50ms
TL0=0xB0;
IE=0x82; //這里是中斷優(yōu)先級控制EA=1(開總中斷),ET0=1(定時器0允許中斷),這里用定時器0來定時
TR0=0; //開啟定時器定時
}
void tim(void) interrupt 1 using 1 //為定時中斷T0
{
TH0=0x3C; //重新賦值
TL0=0xB0;
TR0=1;
count++; //計數(shù)一次時50ms,20次為1s
if((second<=10)&&(count==10)&&(dt==1)) //計時到500ms時,根據(jù)需要蜂鳴器閃爍
beep=0;
if(count==20) //20*50ms=1秒
{
count=0;
if(second>=1)
second--; //秒減1
else
TR0=0;
if((second<=10)&&(dt==1)) //當(dāng)秒見到10以下時,控制蜂鳴器閃爍鳴響
beep=1;
}
}
void delay(uint z) //延時函數(shù)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--); //約1ms
}
void display (void) //顯示函數(shù)
{
unsigned char shiwei,gewei,xuanshou;
shiwei=tab[second/10]; //將秒數(shù)據(jù)拆開成兩個一位數(shù)
gewei=tab[second%10];
xuanshou=tab[p];
P0=gewei; //送入P0口的gewei數(shù)據(jù)
P2=0x7F; //個位位選
delay(5); //延時5ms
P2=0xFF; //關(guān)閉位選,防止出現(xiàn)鬼影 下同
P0=shiwei; //顯示十位
P2=0xBF; //打開顯示時間十位的位選
delay(5);
P2=0xFF;
P0=0x80; //顯示橫線
P2=0xDF;
delay(5);
P2=0xFF;
P0=xuanshou;
P2=0xEF; //選手位選
delay(5);
P2=0xFF;
}
void keyscan(void) //按鍵掃描函數(shù)
{
if(add1==0) //判斷搶答時間加鍵是否按下
{
display(); //延時去抖
if(add1==0) //再次判斷按鍵是否按下
{
p=11; //顯示q 代表搶答時間設(shè)置
disp_qd_dt=0; //顯示搶答時間
qd_time++; //搶答時間加
if(qd_time>=99) //最大值可以加到99
qd_time=99;
}
second=qd_time; //將搶答時間賦值秒數(shù)據(jù),用于計時
do
display(); //調(diào)用顯示函數(shù)
while(add1==0); //按鍵釋放
}
if(dec1==0) //鍵按鍵是否按下
{
display(); //用顯示函數(shù)代替延時去抖,防止按下按鍵時屏幕的閃爍
if(dec1==0) //再次判斷按鍵是否按下
{
p=11; //顯示q
disp_qd_dt=0; //標(biāo)志位置0
qd_time--; //搶答時間減
if(qd_time<=1) //時間減最低值1
qd_time=1;
}
second=qd_time; //將搶答時間賦值秒,用于倒計時
do
display(); //調(diào)用顯示函數(shù)
while(dec1==0); //按鍵釋放
}
if(add2==0) //答題時間設(shè)置參照搶答時間設(shè)置部分注釋
{
display();
if(add2==0)
{
p=12;
disp_qd_dt=1;
dt_time++;
if(dt_time>=99)
dt_time=99;
}
second=dt_time;
do
display();
while(add2==0);
}
if(dec2==0)
{
display();
if(dec2==0)
{
p=12;
disp_qd_dt=1;
dt_time--;
if(dt_time<=1)
dt_time=1;
}
second=dt_time;
do
display();
while(dec2==0);
}
}
void init() //初始化函數(shù)
{
t=0;
beep=1;
p=10; //選手號初始為顯示H,表示等待
second=qd_time; //將搶答時間賦值秒
}
void main() //主函數(shù)
{
uchar i;
init(); //調(diào)用初始化函數(shù)
Timer(); //定時器設(shè)置
while(1) //循環(huán)
{
if((qd==0)&&(dt==0))
keyscan(); //掃描按鍵
display(); //顯示函數(shù)
if(start==0) //主持人按下開始鍵
{
if((qd==0)&&(dt==0)) //在非搶答,非答題狀態(tài)下
{
p=10; //顯示H
disp_qd_dt=0; //標(biāo)志位置0
second=qd_time; //搶答時間賦值秒
qd=1; //開始搶答
}
beep=0; //蜂鳴器長響一聲
for(i=0;i<20;i++) //此處用于延時
{
display();
}
beep=1; //關(guān)閉蜂鳴器
TR0=~TR0; //定時器開關(guān)取反(就是一個開關(guān),按一個就計時,再按一下就停止)
do
display(); //調(diào)用顯示函數(shù)
while(!start); //等待釋放按鍵
}
if(reset==0) //復(fù)位按鍵按下時
{
display(); //顯示函數(shù)用做延時去抖
if(reset==0) //再次判斷按鍵是否按下
{
disp_qd_dt=0; //標(biāo)志位置0
second=qd_time;
t=0;
p=10; //顯示H
TR0=0; //停止計時
beep=1;
qd=0;
dt=0; //停止搶答和答題計時
}
do
display();
while(!reset);
}
if(qd==1) //開始搶答后,才檢測選手按鍵的狀態(tài)
{
{
if(k1==0) //1號選手按下時
{
display(); //顯示函數(shù)用作延時去抖
if(k1==0); //再次判斷按鍵是否按下
do display();
while(!k1); //按鍵釋放
t=1; //搶答序號置1
qd=0; //停止搶答
dt=1; //準(zhǔn)備答題
}
else if(k2==0) //其他選手按鍵掃描參考1號選手按鍵注釋
{
display();
if(k2==0);
do
display();
while(!k2);
t=2;
qd=0;
dt=1;
}
else if(k3==0)
{
display();
if(k3==0);
do display();
while(!k2);
t=3;
qd=0;
dt=1;
}
else if(k4==0)
{
display();
if(k4==0);
do display();
while(!k2);
t=4;
qd=0;
dt=1;
}
else if(k5==0)
{
display();
if(k5==0);
do display();
while(!k2);
t=5;
qd=0;
dt=1;
}
else if(k6==0)
{
display();
if(k6==0);
do display();
while(!k2);
t=6;
qd=0;
dt=1;
}
else if(k7==0)
{
display();
if(k7==0);
do display();
while(!k2);
t=7;
qd=0;
dt=1;
}
else if(k8==0)
{
display();
if(k8==0);
do display();
while(!k2);
t=8;
qd=0;
dt=1;
}
}
if(t) //有選手按下按鍵時,t的值不為0,進(jìn)入此if語句
{
switch(t) //判斷t的值
{
case 1: //t的值為1時,就是選手1按下按鍵
{
TR0=0; //停止計時
p=1; //數(shù)碼管顯示選手號碼
second=dt_time; //答題時間賦值秒
beep=0; //蜂鳴器響
for(i=0;i<20;i++) //此處用于延時
{
display();
}
beep=1; //蜂鳴器延時后關(guān)閉
qd=0;break; //qd置0,搶答環(huán)節(jié)結(jié)束,跳出switch語句
}
case 2: //t為2時就是2號選手按下按鍵
{
TR0=0; //以下參考1號選手注釋/|\即可
p=2;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 3:
{
TR0=0;
p=3;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 4:
{
TR0=0;
p=4;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 5:
{
TR0=0;
p=5;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 6:
{
TR0=0;
p=6;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 7:
{
TR0=0;
p=7;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
case 8:
{
TR0=0;
p=8;
second=dt_time;
beep=0;
for(i=0;i<20;i++)
{
display();
}
beep=1;
qd=0;break;
}
}
}
if(dt==1) //答題標(biāo)志開啟時
{
if(start==0) //開始按鍵此時按下時
{
display();
if(start==0)
{
beep=0; //蜂鳴器鳴響一聲
for(i=0;i<20;i++)
{
display();
}
beep=1;
TR0=1; //開啟定時器計時答題時間
}
}
}
}
if(second==0) //為0時報警
{
beep=0; //蜂鳴器報警
qd=0;
dt=0; //搶答和答題標(biāo)志清零
}
}
}
收藏