求助,关于抢答器

2019-07-15 15:25发布

程序目的:制作一个抢答器,在前五秒倒计时,若有人按键(矩阵键盘),显示其编号并且蜂鸣器报警按下S3停止报警继续倒计时,五秒后进行秒表计时,若有人按下,显示其编号且秒表停止计数。
现在遇到的问题:无法实现蜂鸣器报警和显示编号,只有倒计时和秒表显示。或有时按下S2不开始倒计时。
#include<reg52.h>
#define uint unsigned int        //宏定义 unsigned int
#define uchar unsigned char   //宏定义 unsigned char
sbit we = P2^7;                     //定义位选           
sbit du = P2^6;                     //定义段选
sbit S2 = P3^0;                      //定义独立键盘S2
sbit S3 = P3^1;                      //定义独立键盘S3
sbit S4 = P3^2;                      //定义独立键盘S4
sbit beep = P2^3;                  //定义蜂鸣器
uint i=1;                                
uint d=1;

uchar counter = 0;         
uint b,e=1;
void delay(uint z)        //定义delay延迟函数
{
        uint x,y;
        for(x = z; x > 0; x--)
                for(y = 120; y > 0 ; y--);
}
void display1(uint a);                      //声明display1函数
unsigned char leddata[]={               //定义数码管显示的字符

                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0xBF,  //0.
                0x86,  //1.
                0xDB,  //2.
                0xCF,  //3.
                0xE6,  //4.
                0xED,  //5.
                0xFD,  //6.
                0x87,  //7.
                0xFF,  //8.
                0xEF,  //9.
                         };

uchar KeyScan()        //带返回值的子函数
{
        uchar cord_l,cord_h;//声明列线和行线的值的储存变量
        P3 = 0xf0;//1111 0000
        if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
        {
                delay(5);//软件消抖
                if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
                {
                          cord_l = P3 & 0xf0;// 储存列线值
                          P3 = cord_l | 0x0f;
                          cord_h = P3 & 0x0f;// 储存行线值
                          while( (P3 & 0x0f) != 0x0f );//松手检测
                          return (cord_l + cord_h);//返回键值码
                }       
        }
               
}

void keypro1()                 //定义按键作用函数1(倒计时时使用)
{
        switch(keyscan())
        {
        case 0xee :P0=leddata[1];break;
        case 0xde :P0=leddata[2];break;
        case 0xbe :P0=leddata[3];break;
        case 0x7e :P0=leddata[4];break;

        case 0xed :P0=leddata[5];break;
        case 0xdd :P0=leddata[6];break;
        case 0xbd :P0=leddata[7];break;       
        case 0x7d :P0=leddata[8];break;
         }
}       

void keypro2()                 //定义按键作用函数2(秒表计时时使用)
{
        switch(keyscan())
        {
        case 0xee :P0=leddata[5];break;
        case 0xde :P0=leddata[5];break;
        case 0xbe :P0=leddata[5];break;
        case 0x7e :P0=leddata[5];break;
       
        case 0xed :P0=leddata[5];break;
        case 0xdd :P0=leddata[5];break;
        case 0xbd :P0=leddata[5];break;
        case 0x7d :P0=leddata[5];break;
         }
}       
                                                                
void display1(uint a)                   //定义倒计时函数
{
uint b;
b = 5-a;
P0 = 0xff;
we = 1;
P0 = 0xef;
we = 0;
du = 1;
P0 = leddata[b];
du = 0;
delay(1);          
}       
       
void display(uint a)               //定义秒表计时函数
{
                uint shi,ge,fen ;
                shi = a/100;                         
                ge = a%100/10+24;
                fen = a%10;
                P0 = 0xff;
                we = 1;
                P0 = 0xdf;
                we = 0;
                du = 1;
                P0 = leddata[shi];
                du = 0;
                delay(1);
                  
                we = 1;
                P0 = 0xbf;
                we = 0;
                du = 1;
                P0 = leddata[ge];
                du = 0;       
                delay(1);

                we = 1;
                P0= 0x7f;
                we = 0;
                du = 1;
                P0 = leddata[fen];
                du = 0;
                delay(1);

                we = 1;
                P0 = 0xef;
                we = 0;
                du = 1;
                P0 = leddata[b];
                delay(1);
}

void Inittimer()          //定义定时器模式
{
    TMOD = 0x01;     //使用计时器0
    TH0 = 0x4c;         //计时50毫秒
    TL0 = 0x00;
}

void main()                  //主函数体
{           uint d=1,e=1;    //定义标识符d,e
          uint time_counter = 0;        //定义记录时间变量
          InitTimer();                       //打开计时器
          while(1)
          {
                      if(time_counter <= 5)   
                           {
                                display1(time_counter);  //开始倒计时
                                if(TF0 == 1)       //溢出处理
                                {                         
                                         
                                         TF0 = 0;
                                         TH0 = 0x4c;
                                         TL0 = 0x00;
                                         counter++;       
                                 }
                                 if(counter == 20)    //满秒+1处理
                                 {       
                                        counter = 0;
                                        time_counter++;
                                 }
                          if(keyscan())          //判断是否按下矩阵键盘
                        {       
                                beep=0;           //蜂鸣器响
                                we = 1;            //位选打开
                                P0 = 0xfe;        //第一位数码管
                                we = 0;            //位选关闭
                                du = 1;            //段选打开
                                P0 = 0x00;        //消除虚影
                                while(d)
                           {                               
                                keypro1();      //抢答按键响应模式1{报警和显示编号}
                                  
                                 if(S3 == 0)       //按下按键S3,继续倒计时
                                 {
                                        delay(1);   //消抖设置
                                        if(S3 == 0)
                                        {       
                                                d=0;
                                               
                                                while(!S3);
                                        }
                                 }
                           }
                                }
                                   if(S2 == 0)             //按下按键S2开始倒计时         
                                 {
                                        delay(1);       //消抖设置
                                        if(S2 == 0)
                                        {       
                                                TR0 = 1;
                                                while(!S2);
                                        }
                                 }
                        }
               
                                                                         
                        if(time_counter >= 5)     //倒计时结束。秒表计时开始
                        {
                                time_counter = 0;   //时间清0
                                InitTimer();
                                TR1=1;
                                while(1)        //秒表计时设置
                                {                               
                                                                                                                                             
                                        if(TF0 == 1)
                                 {         
                                         TF0 = 0;
                                         TH0 = 0x4c;
                                         TL0 = 0x00;
                                         counter++;       
                              }
                                                              
                                if(counter == 2)
                            {       
                                        counter = 0;
                                        time_counter++;
                            }
                       
                                if(time_counter == 600)
                                 {         
                                        time_counter = 0;
                                         b++;
                                 }
                       
                          display(time_counter);
                        if(keyscan())         
                         {        TR0=0,            //计时停止
                                we = 1;           //位选打开
                                P0 = 0xfe;       //第一位数码管亮
                                we = 0;             //位选关闭
                                du = 1;              //打开段选
                                P0 = 0x00;         //消影处理
                                while(e)
                          {
                                keypro2();         //按键响应系统2{显示抢答者编号}
                          
                                 if(S4 == 0)       //退出显示循环
                                 {
                                        delay(1);   //消抖处理
                                        if(S4 == 0)
                                        {       
                                                e=0;                                       
                                                while(!S4);
                                        }
                                 }
                                }                                                                               
                           }
                         }
                        }
                        }                                                           
                   }


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。