C语言源程序
#include#define unchar unsigned char
#define unit unsigned int
#define Data_port P0 //数码管数据口
#define Bit_sel_port P1 //数码管位选口
#define Key_port P2//抢答按键输入口
sbit Bee=P3.7; //蜂鸣器控制引脚
unit timer_out=60;//定时60s
unit Count=0;
unit single=0;//个位
unit decade=6;//十位
unit n;
unit i;
unchar start_flag=0;//启动抢答标志
unchar ans_flag=0;//已抢答标志
unit seg_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//七段数码管字形表
void Delay(i)//延迟函数
{
for(;i>0;i--);
}
void Display_time()//显示抢答时间
{
Bit_sel_port=0x01;
Data_port=seg_tab[decade];
Delay(200);
Bit_sel_port=0x02;
Data_port=seg_tab[single];
Delay(200);
}
void Display_num_time()//显示抢答组编号和时间
{
Bit_sel_port=0x01;
Data_port=seg_tab[decade];
Delay(200);
Bit_sel_port=0x02;
Data_port=seg-tab[single];
Delay(200);
Bit_sel_port=0x04;
Data_port=seg_tab[n];
Delay(200);
}
main()
{
EX0=1;//开外部中断INT0
IT0=1;//外部中断方式为下降沿
TMOD=0x01;//定时/计时器0工作与模式1
TH0=0xd8;
TL0=0xef;
ET0=1;//开定时/计数器0中断,定时20ms
Bee=0;//蜂鸣器停止
EA=1;//开关中断
while(1)
{
if(star_flag==0)//抢答未开始
{
if(Key_port!=0xFF)
{
Bee=1;//蜂鸣器启动,抢答违规处理
while(1);//进入死循环,按复位键重新启动
}
}
else//抢答开始
{
if(ans_flag!=1)//无人抢答,显示时间
Dislay_time();
else//显示时间和抢答组编号
Delay_num_time();
}
}
void Interrupt0() interrupt0
{
Bee=1;//提示开始抢答
Delay(200);
Bee=0;
TR0=1;//启动抢答后使能定时器
start_flag=1;//启动抢答标志置位
}
void Timer0() interrupt1
{
TH0=0xd8;
TL0=0xef;
Count++;
if(Count==50)
{
Count=0;
timer_out--;
}
if(timer_out!=0&&Key_port==0xff)
//如果时间未到且无抢答键按下
{
decade=timer_out/10; //显示当前剩余时间
single=timer_out%10;
ans_flag=0;
}
if(time_out==0) //超时时间到,启动蜂鸣器,停止计时器
{
Bee=1;
EA=0;
}
if(timer_out!=0&&Key_port!=0xff)
//如果时间未到且抢答键按下
{
switch(Key_port)
{
case 0xfe:n=1;ans_flag=1;EA=0;break;
case 0xfd:n=2;ans_flag=1;EA=0;break;
case 0xfb:n=3;ans_flag=1;EA=0;break;
case 0xf7:n=4;ans_flag=1;EA=0;break;
case 0xef:n=5;ans_flag=1;EA=0;break;
case 0xdf:n=6;ans_flag=1;EA=0;break;
case 0xbf:n=7;ans_flag=1;EA=0;break;
case 0x7f:n=8;ans_flag=1;EA=0;break;
default:break;
}
}
}