#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
bit OK; //開始搶答標志位,響鈴標志位
sbit speak=P3^7; //聲音輸出口
sbit start=P3^0; //開始
sbit end=P3^1; //終止
sbit add=P3^4; //+
sbit sub=P3^5; //-
//其中搶答設置時間,以及回答設置時間,采用的是單片機中斷口p3.2以及p3.3,故不用定義
sbit S1=P2^1;//第一個數碼管
sbit S2=P2^3;//第二個數碼管
sbit S3=P2^5;//第三個數碼管
sbit S4=P2^7;//第四個數碼管
uchar Q_T=20,H_T=30,qt,ht; //初始搶答時間,回答時間
uchar a=11,b=11,c=11,d=11,n,m=0,k; //數碼管顯示選手編號與計數值,計時器中斷次數,犯規選手號
/*****************************************************************************/
uchar code dis_7[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};
/* 共陰七段LED段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"*/
/********1毫秒延時子函數**********/
void delay1ms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++)
;
}
/*******************************響鈴標志子程序********************************/
void nose()
{speak=0;
delay1ms(500);
speak=1;
}
/********************************顯示子程序**********************************/
void display()
{
P0=dis_7[a]; //第一個數碼管顯示
S1=0; //打開第一個數碼管顯示
delay1ms(5); //稍作延時
S1=1; //關閉數碼管顯示
P0=dis_7[11];
S2=0;
delay1ms(5);
S2=1;
P0=dis_7[b];
S3=0;
delay1ms(5);
S3=1;
P0=dis_7[c];
S4=0;
delay1ms(5);
S4=1;
}
/************************************非法搶答*********************************/
void false()
{
if(P1!=0xff) //如果p1口不等于ff,則執行一下程序,否則跳過
{
if(P1==0xf7) //1號選手違規按下
{m=1;} //賦值1,送顯示
if(P1==0xfb) //2號選手違規按下
{m=2;} //賦值2,送顯示
if(P1==0xfd) //3號選手違規按下
{m=3;} //賦值3,送顯示
if(P1==0xfe) //4號選手違規按下
{m=4;} //賦值4,送顯示
if(P1==0xef) //5號選手違規按下
{m=5;} //賦值5,送顯示
if(P1==0xdf) //6號選手違規按下
{m=6;} //賦值6,送顯示
if(P1==0xbf) //7號選手違規按下
{m=7;} //賦值7,送顯示
if(P1==0x7f) //8號選手違規按下
{m=8;} //賦值8,送顯示
n=0; //計數器中斷次數清零
while(end==1) //停止按鍵未按下,循環以下
{ if(n<6) //若計數器中斷次數小于6,則執行以下
{a=10;b=10;c=10;//a,b,c均賦值10,不顯示
display(); //延時
speak=1;} //蜂鳴器關閉
if(n>=6) //若計數器中斷次數大于等于6,則執行以下程序
{a=m;b=11;c=11; //a賦值違規選手號數,b,c賦值11,顯示數碼管中間一橫
display(); //延時
speak=0;
} //開啟蜂鳴器
if(n==20) //若計數器中斷次數等于20,則執行以下程序
{n=0;} //清零
}
speak=1;m=0; //關閉蜂鳴器;違規搶答位清零
a=10;b=10;c=10; //a,b,c均賦值10
}
}
main()
{TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
EX0=1;
EX1=1;
OK=0;
speak=1;
TR0=1;
while(1) //無盡循環
{display(); //顯示程序
while(start==1) //開始未按下,循環以下程序
{false(); //違規子程序
display(); //顯示子程序
if(start==0) //若開始按鍵按下,則執行以下程序
{delay1ms(2); //稍作延時,防止抖動
while(start==0); //若開始按鍵按下,則執行以下程序
nose(); //響鈴子程序
OK=1; //開始搶答標志位
TR0=0;
qt=Q_T; //搶答時間賦初值
n=0; //計數器中斷次數清零
while(qt>0&&end==1&&OK==1&&P1==0xff) //搶答時間大于0且停止按鍵未按下且開始搶答標志為1且未有選手按鍵按下則執行以下程序
{TR0=1;
a=10; //a賦值10
b=qt/10; //b賦值搶答時間十位
c=qt%10; //c賦值搶答時間個位
display(); //調用顯示
speak=1;
if(n>20) //若計數器中斷大于20,則執行以下程序
{n=0; //n清零
qt--; //搶答時間減1
}
if(qt<=5) //如果搶答時間小于等于5,則執行以下程序
{if(n<7) //如果n小于7,則執行以下程序
{speak=1;
}
if(n>7)
{speak=0;}
}
}
if(qt==0) //如果搶答時間等于0
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
} //則a,b,c,d均置10;搶答標志,響鈴關閉,選手號,計數器中斷數均清零
if(end==0) //如果主持人按下終止按鍵
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
} //則a,b,c,d均置10;搶答標志,響鈴關閉,選手號,計數器中斷數均清零
if(P1!=0xff) //如果有選手按下按鈕,則執行以下程序
{k=P1; //p1口數值賦給k
nose(); //響鈴子程序
if(k==0xf7) //比較k的值
{m=1;} //賦對應選手號給m
if(k==0xfb) //跟以上一樣,以下以此類推
{m=2;}
if(k==0xfd)
{m=3;}
if(k==0xfe)
{m=4;}
if(k==0xef)
{m=5;}
if(k==0xdf)
{m=6;}
if(k==0xbf)
{m=7;}
if(k==0x7f)
{m=8;}
n=0; //n清零
ht=H_T; //回答時間賦初值
while(end==1&&ht>0) //當終止未按下且回答時間大于0,則循環以下程序
{TR0=1; //打開計時器
a=m; //a賦值選手號
b=ht/10; //b賦值回答時間十位
c=ht%10; //c賦值回答時間個位
display(); //調用顯示子程序
speak=1;
if(n==20) //如果計時器中斷次數等于20,則執行以下程序
{n=0; //清零
ht--; //回答時間減1
}
if(ht<=5) //如果回答時間小于等于5,則執行以下程序
{if(n<7)
{speak=1;
}
if(n>7)
{speak=0;
}
}
}
}
{a=10;b=10;c=10;d=10;OK=0;speak=1;m=0;n=0;
} //清零
}
}
}
}
/**********************************定時0中斷**********************************/
void time_intt0(void) interrupt 1
{TH0=0x3c;TL0=0xb0; //賦初值
n++;
}
/*****************************************************************************/
/********************************外中斷0**************************************/
void time_intt2(void) interrupt 0 //采用中斷設置時間
{while(end==1) //終止未按下,循環以下
{if(add==0) //如果+鍵按下,執行以下程序
{delay1ms(2); //稍作延時,防止抖動
while(add==0); //當+鍵等于0,則循環
if(Q_T>=99) //如果搶答時間大于等于99
{Q_T=0; //則搶答時間清零
}
else //否則
{Q_T++; //搶答時間加1
}
}
if(sub==0) //如果-鍵按下,執行以下程序
{delay1ms(2); //稍作延時,防止抖動
while(sub==0); //當-鍵等于零,則循環
if(Q_T<=0) //如果搶答時間小于等于0
{Q_T=99; //則搶答時間等于99
}
else //否則
{Q_T--; //搶答時間減1
}
}
a=10;b=Q_T/10;c=Q_T%10;display(); //a賦值10,b賦值搶答時間十位,c賦值搶答時間個位,調用顯示子程序
}
a=10;b=10;c=10;display(); //a,b,c均賦值10,調用顯示子程序
}
/*****************************************************************************/
/************************************外中斷1**********************************/
void time_intt3(void) interrupt 2 //采用中斷設置時間
{while(end==1) //解釋與上一個中斷一樣
{if(add==0)
{delay1ms(2);
while(add==0);
if(H_T>=99) //回答時間
{H_T=0;
}
else
{H_T++;
}
}
if(sub==0)
{delay1ms(2);
while(sub==0);
if(H_T<=0)
{H_T=99; //回答時間
}
else
{H_T--;
}
}
a=10;b=H_T/10;c=H_T%10;display(); //b,c賦值的是回答時間
}
a=10;b=10;c=10;display();
}
/*************************************************************************/
|