基于51单片机的多路抢答器

基本功能:1.8路抢答器

                  2.抢答成功和抢答失败(别人抢答后再抢答认定为失败)有不同的蜂鸣器提示

                  3.抢答成功对应的指示灯会亮起来,数码管显示对应的抢答人序号

                  4.主持人可以按下按键开始下一轮抢答

基本思路:当选手按下抢答器的时候,对应的单片机端口感受到电平的变化,这时候让灯亮,蜂鸣器响,所以这个时候我们在外面写一个灯函数,蜂鸣器抢答成功失败2个函数。这里我们要注意拿一个变量作为锁资源(当自己抢答后别人再抢答是不能抢答成功的),我这里用了bn_num变量名字。同时为了让蜂鸣器有不同声效,我们可以在自己写一个delay延时函数。注意蜂鸣器是不能通过单片机IO口输出的电流来驱动,所以我们要用一个三极管来放大电流

这里是仿真图:

详细的看一下代码:

#include <REGX52.H>
sbit N_one = P2^0; //1号选手  
sbit N_two = P2^1; //2号选手  
sbit N_three = P2^2; //3号选手  
sbit N_four = P2^3; //4号选手
sbit N_five = P2^4; //5号选手 
sbit N_six = P2^5; //6号选手
sbit N_seven = P2^6; //7号选手
sbit N_eight = P2^7; //7号选手
sbit N_cp = P1^2; //主持人号选手 
sbit led = P1^0;   //灯
sbit beep=P1^1;    //定义蜂鸣器引脚
typedef unsigned int u16;
unsigned char bn_num;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f};//共阴极数码管对应的数组
void delay(){  //延时函数,我自己测试这个循环是我自己想要达到的效果,实际自己可以调整参数等
  int i, j;
  volatile int k;  // 使用volatile关键字,防止编译器优化
  for(i=0; i<100; i++)
    for(j=0; j<100; j++)
      k = j;  // 添加一个看似无用的操作
}
void LED(){ //让灯亮一会再关闭
  led=0; //灯端口置0,开灯的意思
    delay();
    led=1;//灯端口置1,关灯的意思
}
void BEEPs(){  //抢答成功让蜂鸣器响一会再关闭
  beep=0;  
    delay();
    beep=1;
}
void BEEPf(){  //抢答失败让蜂鸣器响3次
    int count=0;
    while(count<=2){
  beep=0;
    delay();
    beep=1;
    delay();
    count++;
    }
}
void main()
{
    
    while(1){
          if(N_one==0){  //如果检测到1号选手按下开关,这个时候端口检测到低电平,这个函数代表选手按下按钮
              if(bn_num==0){  //bn_num我说的锁,如果它等于0,代表没有人抢答过
                    bn_num=1;
                    P0=tab[bn_num]; //数码管为1
                    LED(); //开灯
              BEEPs(); //蜂鸣器响
            }
              else if(bn_num!=0){  //判断是不是已经有人抢答过了,如果是bu_num是不为0
                BEEPf();//蜂鸣器响3下
            }
            while(N_one==0);//检测按键是否松开
        }
            if(N_two==0){  //2号选手
              if(bn_num==0){        
           bn_num=2;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_two==0);
        }
            if(N_three==0){  //3号选手
              if(bn_num==0){
                   bn_num=3;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_three==0);
        }
            if(N_four==0){
              if(bn_num==0){
                   bn_num=4;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
                
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_four==0);
        }
            if(N_five==0){
              if(bn_num==0){
                   bn_num=5;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
                
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_five==0);
        }
            if(N_six==0){
              if(bn_num==0){
                   bn_num=6;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
                
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_six==0);
        }
            if(N_seven==0){
              if(bn_num==0){
                   bn_num=7;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
                
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_seven==0);
        }
            if(N_eight==0){
              if(bn_num==0){
                   bn_num=8;
                    P0=tab[bn_num];
                    LED();
               BEEPs();
                
            }
              else if(bn_num!=0){
                BEEPf();
            }
            while(N_eight==0);
        }
            if(N_cp==0){ //主持人按键,主持人按下,代表这一轮抢答重新开始
              bn_num=0;//归还锁资源
                P0=tab[bn_num];
                while(N_cp==0);
            }
    
    }    
}

特别需要主义的是,因为delay是软件延时,可能在Proteus仿真中会出现问题(delay函数延时太多导致仿真会卡死),所以建议用实物一点一点测试,实物的delay仿真仿真不出来。

同时,我想让三者(灯,蜂鸣器,数码管)达到同一时间响应,我把beeps放在最后,让数码管,灯先工作(他们占用cpu时间比较短),这样就可以差不多达到三者同时工作,如果把beeps函数放在最前面,可以看到按下后一小段时间,数码管才亮。

实物图:

(新人第一次写博客,希望支持!!)

              

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值