2011年11月

1、流程
裁判按下复位键,抢答器进入抢答模式,各组人员才可以通过抢答按钮进行抢答,抢答结果显示在抢答器上。

2、实现
使用单片机对输入的电平信号处理(低电平有效):1路为复位,8路为抢答。复位前对8路抢答状态进行判断,防止作弊。一次性对8路抢答器状态进行采样,将结果存储在num数组内,最大可存储4路同时抢答结果。LED显示部分由T0定时器每3ms动态将num数组的结果点亮。蜂鸣器的时长由T0定时器控制

3、原理图
3edd751exb1376dbafc0a.jpg
4、代码

    #include<AT89X51.H>
    #include<stdio.H>
    #include<stdlib.H>
    sfr WDTRST = 0xA6;  
     
    #define OUTPORT1  P0
    #define OUTPORT2  P2
    #define BELL     P3_5
    #define CLR           P3_4
    #define INPORT    P1
     
    Static unsigned char code  digital[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0xe1,0x91,0x88,0x86,0xa0,0xa1,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x58,0x00}; //字库码"0,1,2,3,4,5,6,7,8,j,y,r,e,a,d,0.,1.,2.,3.,4.,5.,6.,7.,8."
    static unsigned char code select[]={0xff,0xfb,0xf7,0xef,0xdf};     //选位字码
     
    static unsigned char  rycle=0x00; //当前数码管显示位控制
    static unsigned char data num[5]={0x4,0x0e,0x09,0x0A,0x09};//检测结果
    static unsigned char data i,j;
    static unsigned char data  count;//蜂鸣器警报时长
    static unsigned char bdata temp;  //8位取样数据
    static bit state=0x00 ;//复位状态保存
    static unsigned int sum[]={0x00,0x00};   //复位键检测时间/自动复位的时长
    static bit timeCLR=0x00;//自动复位状态
    static bit stateCLR=0x00; //首次状态保留
     
    void delay(char t);
    void ready();
     
     
    void init()
    {
          P0 = 0xff;
          P1 = 0xff;
          P2 = 0xff;
          P3 = 0xFF;
          EX0 = 0x00;
     
          EX1 = 0x00;
          ET1 = 0x00;
          ES = 0x00;
          ET2 = 0x00;
          WDTRST = 0x1E;
          WDTRST = 0xE1;
     
          BELL = 0;
     
          TMOD=0x11;
          EA=0x01;
     
          TR0=0x00;
          ET0=0x00;
          TL0=0x18;      //T0=130ms
          TH0=0x02;
     
          count=0;
     
          TL1=0x24;    //T1=4.5ms
          TH1=0xfa;
          TR1=0x01;
          ET1=0x01;
     
    }
    void belltime() interrupt 1
    {
          TL0+=0x18;
          TH0+=0x02;
          if(!count--)
          {
                  BELL=0x00;
                  ET0=0x00;
                  TR0=0x00;
          }
     
     
    }
     
     
    void display() interrupt 3
    {
          TL1+=0x24;
          TH1+=0xFA;
          if(rycle<=num[0])
          {
                 OUTPORT1 = digital[num[rycle]];
                 OUTPORT2 = select[rycle];
                 ++rycle;
          }else  rycle=0x00;
     
     
     
          if(!CLR)
          {
                 sum[0]++;
               if(sum[0]>666&&stateCLR)
                 {
                        timeCLR=!timeCLR;
                      stateCLR=0;
                        state=!state;   //避免按复位键超时,导致状态重复反转
                 }
                 
          }else
          {
                 sum[0]=0;
                 stateCLR=1;                //复位键退出,将状态设置为可复位状态
          }
     
     
          if(timeCLR&&!state)
          {
                 if(sum[1]++>2333)                    //在有抢答结果的情况下,等待复位
                 {
                        if(temp==0xff)                    //防作弊
                        {
                               ready();
                        }else              
                        {    
                               sum[1]=2167-(int)666*rand();        //延迟0.5-2.5S
                        }
                 }
     
          }else sum[1]=0;
     
     
     
     
    }
    void delay(char t)
    {
          count=t;
          TL0=0x18;
          TH0=0x02;
          ET0=0x01;
          TR0=0x01;
    }
     
    void main()
    {
          init();
         while(1){
                 WDTRST=0x1E;
                 WDTRST=0xE1;
                 temp = INPORT;            //对8个连接器同时采样
                 if(!CLR&&temp==0xff)
                 {
                    ready();
                 }
                 for(i=1,j=0;i<=8&&state;i++)         //8个连接器状态检测
                 {
                        if(!(temp & 0x01))
                        {
                               j++;
                               num[0]=j; //num[0]存放首批按下的连接器个数
                               num[j]=(j>1?i+0x0f:i); //存放按下状态的连接器序列
     
                               
                               BELL=0x01;
                               delay(1);
                        }
                        temp >>= 1;
                 }
     
     
                 if(j>0) state=0; //判断是否抢答成功,成功就禁止再次抢答
          
     
     
          }
    }
     
     
    void ready()
    {
          num[0]=0x04;
          num[4]=0x0b;
          num[3]=0x0c;
          num[2]=0x0e;
          num[1]=0x0a;
     
          state=0x01;
     
          BELL=0x01;
          delay(1);
    }

5、成品效果
3edd751exb1376cc6fa63&690.jpg
3edd751exb137729e5330&690.jpg
3edd751exb13777447693&690.jpg
3edd751exb1377d3a5419.jpg