#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit P37=P3^7;
sbit P07=P0^7;
sbit P06=P0^6;
uchar m,a,b,c,i,k,s,r=0;
uint j,sum,d1=0,d2=0,d3=0,d4=0,d5=0,d6=0;
uchar code tab1[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //倒计时字符表
uchar code tab[6]={0x06,0x5b,0x4f,0x66,0x6d,0x7d}; //编号字符表
//头文件及参数定义
main() //主函数
{
//中断服务程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EA=1; //开中断总开关
EX0=1; //开外部中断INT0
IT0=1; //选择下降沿触发方式
TMOD=0x01; //定时器T0选择方式一
while(1) //等待中断
//跑马程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ for(k=0;k<6;k++)
{
P1=0x40; //P1口位选
for(i=0;i<6;i++)
{
if(P0==0xff) //无违规操作
{
P2=tab[k]; //P2对应输出字符
for(j=0;j<=25000;j++); //延时
P1=_cror_(P1,1); //左移一位
for(j=0;j<=25000;j++);
}
else //有违规操作
{
P1=0x02; //对应位数码管被选中
P2=0x6d;
for(j=0;j<=1000;j++);
P1=0x04;
P2=0x78;
for(j=0;j<=1000;j++);
P1=0x08;
P2=0x3f;
for(j=0;j<=1000;j++);
P1=0x10;
P2=0x73;
for(j=0;j<=1000;j++);
}
while(r==3) //3轮答题结束后显示对应位得分结果
{
P1=0x01;P2=tab1[d1];for(j=0;j<50;j++);
P1=0x02;P2=tab1[d2];for(j=0;j<50;j++);
P1=0x04;P2=tab1[d3];for(j=0;j<50;j++);
P1=0x08;P2=tab1[d4];for(j=0;j<50;j++);
P1=0x10;P2=tab1[d5];for(j=0;j<50;j++);
P1=0x20;P2=tab1[d6];for(j=0;j<50;j++);
}
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int0() interrupt 0 //进入中断(开始抢答)
{
P0=0xff; //初始化P0口开关无人拨开
for(m=9;m>=0;m--)
{
P1=0xff;
P2=0x00;
TR0=1; TMOD=0x01;
for(s=1;s<=20;) //定时器定时一秒
{
if(P0!=0xff)
{
switch(P0) //判开关
{
case 0xfe:{P2=0x06;sum=1;}break;
case 0xfd:{P2=0x5b;sum=2;}break;
case 0xfb:{P2=0x4f;sum=3;}break;
case 0xf7:{P2=0x66;sum=4;}break;
case 0xef:{P2=0x6d;sum=5;}break;
case 0xdf:{P2=0x7d;sum=6;}break;
}
if(P0!=0xff) goto ap1;
}
TH0=15536/256;
TL0=15536%256;
do{}while(!TF0);
s++;
TF0=0;
}
if(m==0) goto ap2;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ap1:
P1=~P0;
b=P2; //把P2口字符赋值给参数b
if(P0!=0xff)
{ r++; //抢答次数
//鸣笛程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for(a=0;a<sum;a++)
{
for(i=1;i<200;i++)
{
P37=~P37; //P37为喇叭开关控制
for(j=0;j<=100;j++);
}
for(i=1;i<200;i++)
for(j=0;j<=100;j++);
}
//对应位亮闪编号5次 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for(c=0;c<6;c++)
{ for(j=0;j<=25000;j++);
P1=0x01;
for(j=0;j<=25000;j++);
P1=0x00;
}
P1=~P0;
//答题倒计时 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for(m=9;m>=0;m--)
{
P2=tab1[m];
TR0=1; TMOD=0x01;
for(s=1;s<=20; s++)
{
while(P07==0) //拨P07答题正确 显示PASS
{ P1=0x01;P2=0x73;for(j=0;j<50;j++);
P1=0x02;P2=0x77;for(j=0;j<50;j++);
P1=0x04;P2=0x6d;for(j=0;j<50;j++);
P1=0x08;P2=0x6d;for(j=0;j<50;j++);
if(P07==1) //答题正确对应位加一分
{ if(sum==1) d1=d1+1;
if(sum==2) d2=d2+1;
if(sum==3) d3=d3+1;
if(sum==4) d4=d4+1;
if(sum==5) d5=d5+1;
if(sum==6) d6=d6+1;
goto ap2;
}
}
while(P06==0) //拨P06答题错误 显示ff
{ P1=0xff;P2=0x71;for(j=0;j<50;j++);
if(P06==1) goto ap2;
}
TH0=15536/256;
TL0=15536%256; //定时器初值
do{}while(!TF0); //查询等待定时
TF0=0;
}
if(P0==0xff) goto ap2; //开关拨回跳到判复位程序
}
//判开关复位程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ap2:
while(P0!=0xff)
{ P1=~P0; //位选对应选手数码管
P2=b; //P2口输出显示对应编号
if(P0==0xff) goto ap2; //开关复位 返回主程序中断点
}
}}
~~//
这个抢答器有跑马,鸣笛,判违规,倒计时等功能,
需要的芯片有AT89c51/52,和一个74ls573(可选择别的代替)
仅供大家参考,也欢迎各位指出程序中的不足,我也好改正。
|