#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();
}
/*************************************************************************/
|