找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1303|回复: 1
打印 上一主题 下一主题
收起左侧

(原创)基于51单片机的五路数显抢答器程序PCB仿真设计

[复制链接]
跳转到指定楼层
楼主
(原创!)基于51单片机的五路数显抢答器设计
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

要求如下:

程序难点分析:
1、抢答的判断,处于开始抢答环节还是不处于抢答环节,标志位要控制好。
2、灯的闪烁问题,需要通过计数的形式解决,否则数码管和LED一起闪烁。
附件有完整的程序(注释详细)+仿真原件+设计说明书+PCB+原理图!在附件!!!

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)

单片机源程序代码:
#include<reg51.h>
#include<intrins.h>
sbit smg1=P2^0;                //定义数码管第一位
sbit smg2=P2^1;                //定义数码管第二位
sbit deng1=P2^3;                //灯1号
sbit deng2=P2^4;                // 灯2号
sbit deng3=P2^5;                // 灯3号
sbit deng4=P2^6;                // 灯4号
sbit deng5=P2^7;                // 灯5号


sbit keyksqd=P3^7;        //定义开始按键
sbit spk=P3^6;                //定义蜂鸣器
int dingshi;js;            //初始倒计时时间
int keyhao;                        //矩阵键值
int buzzbiaozhi=1;        //10S倒计时结束后蜂鸣器响一下的标志位
int biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;         //正确抢答唯一
int xxxx=0;   //犯规抢答标志位
int flagD=0; // 控制是否显示倒计时         
int zqqd,fgqd;                   //zqqd正确抢答,fgqd犯规抢答
int  jishu;                         //用来控制LED闪烁的快慢,防止数码管闪烁
int table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0X71};        // 数码管段码0 1 2 3 4 5 6 7 8 9 f

//******延时子程序****//
void delayms(unsigned z)          //定义毫秒
{
        unsigned x,y;
    for(x=z;x>0;x--)
      for(y=110;y>0;y--);   
}



void Timer0_init()                        //定时器0初始化
{
    js=0;
        TMOD=0x01;                                //设置定时器0为工作方式1(M1M0为01)
        TH0=(65536-50000)/256;        //装初值12M晶振定时50ms数为50000,1US是1000初始值,所以50ms是5万
        TL0=(65536-50000)%256;               
        ET0=1;                                                //开定时器0中断
        EA=1;                                                //开总中断
}

void timer0() interrupt 1 using 1        //定时器0中断服务函数
{
        TH0=(65536-50000)/256;                //装初值12M晶振定时50ms数为50000
        TL0=(65536-50000)%256;        
        js++;                                                //叠加20次
        if(js==20)
        {
          js=0;                                                //清空
          dingshi--;                                        //产生1s的倒计时
         }
}

  ///矩阵按键//
unsigned char key_juzhen(void)
{
        unsigned key_value=0;

        P1=0xf7;//给第一列赋值0,其余全为1
        if(P1!=0xf7)//判断第一列按键是否按下
        {
                delayms(10);//消抖
                switch(P1)//保存第一列按键按下后的键值        
                {
                        case 0x77: key_value=1;break;                          //记录键值1
                        case 0xb7: key_value=5;break;                          //记录键值5
                        case 0xd7: key_value=9;break;                           //记录键值9
                        case 0xe7: key_value=13;break;                           //记录键值13
                }
        }
        while(P1!=0xf7);//等待按键松开        
        
        P1=0xfb;//给第二列赋值0,其余全为1            
        if(P1!=0xfb)//判断第二列按键是否按下
        {
                 delayms(10);//消抖
                switch(P1)//保存第二列按键按下后的键值        
                {
                        case 0x7b: key_value=2;break;                    //记录键值13
                        case 0xbb: key_value=6;break;                    //记录键值13
                        case 0xdb: key_value=10;break;                    //记录键值13
                        case 0xeb: key_value=14;break;                    //记录键值13
                }
        }
        while(P1!=0xfb);//等待按键松开        
        
        P1=0xfd;//给第三列赋值0,其余全为1
        if(P1!=0xfd)//判断第三列按键是否按下
        {
                 delayms(10);//消抖
                switch(P1)//保存第三列按键按下后的键值        
                {
                        case 0x7d: key_value=3;break;                   //记录键值3
                        case 0xbd: key_value=7;break;                  //记录键值7
                        case 0xdd: key_value=11;break;                    //记录键值11
                        case 0xed: key_value=15;break;                    //记录键值15
                }
        }
        while(P1!=0xfd);//等待按键松开        
        
        P1=0xfe;//给第四列赋值0,其余全为1
        if(P1!=0xfe)//判断第四列按键是否按下
        {
                 delayms(10);//消抖
                switch(P1)//保存第四列按键按下后的键值        
                {
                        case 0x7e: key_value=4;break;                         //记录键值4
                        case 0xbe: key_value=8;break;                         //记录键值8
                        case 0xde: key_value=12;break;                         //记录键值12
                        case 0xee: key_value=16;break;                          //记录键值16
                }
        }
        while(P1!=0xfe);//等待按键松开
        
        return key_value;               
}




///倒计时函数////
void djsxs()   //第一位,第二位 显示倒计时函数
{        
        int b1,b2;
        b1=dingshi/10;
        b2=dingshi%10;                                  //将倒计时时间分成高低位
        P0=table[b1];                          
        smg1=0;                                                 //第1位显示十位
        delayms(3);
        smg1=1;                                         //显示十位数字
        P0=table[b2];
        smg2=0;                                           //第2位显示各位
        delayms(3);                                 //显示个位数字
        smg2=1;
        
}

//**显示F犯规**//

void djsxs10() //高位数码管显示F 表示抢答犯规
{
         P0=0X71;                        //高位数码管显示F
    smg1=0;
    delayms(3);
    smg1=1;
}

////*****显示抢答选手号码*********///////
void haoma1()  //第二位数码管显示1
{
        P0=table[1];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位数码管显示1
}
void haoma2()  //第二位数码管显示2
{
        P0=table[2];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位数码管显示2
}

void haoma3()  //第二位数码管显示3
{
        P0=table[3];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位数码管显示3
}
void haoma4()  //第二位数码管显示4
{
        P0=table[4];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位数码管显示4
}
void haoma5()  //第二位数码管显示5
{
        P0=table[5];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位数码管显示5
}

void main()
{
   
         jishu=0;                                 //记录多少毫秒累加
     dingshi=10;                        //修改倒计时初始值
         Timer0_init();             //初始化定时器中断
        while(1)
        {
//          smg2=0;                 //上电数码管不亮,因为非门取反
//          smg1=0;                 //上电数码管不亮,因为非门取反
          keyhao=key_juzhen();
           switch(zqqd)        //显示抢答的号码
          {
                case 1:haoma1(); break;
                case 2:haoma2(); break;
                case 3:haoma3(); break;
                case 4:haoma4(); break;
                case 5:haoma5(); break;           
                default:  ;
       }
           if(xxxx==0)        ///大前提条件是,开始抢答之前有效,否则按下开始抢答数码管乱码!!!
           {
           switch(fgqd)        //显示犯规的号码
          {
                case 1:djsxs10();haoma1(); break;
                case 2:djsxs10();haoma2(); break;
                case 3:djsxs10();haoma3(); break;
                case 4:djsxs10();haoma4(); break;
                case 5:djsxs10();haoma5(); break;           
                default:  ;
       }
           }        
                  
                 ///////选手正确抢答****/////////////////////
                 if((keyhao==1)&&(biaozhi1==1)) //在定时器运行状态下则说明1号抢答选手按下按键
         {        
                 
                        spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
           
            TR0=0;                           //启动定时器 开始倒计时
            flagD=0;                   //显示倒计时函数
            

        zqqd=1;         
     
         }
                         if((keyhao==2)&&(biaozhi2==1)) //在定时器运行状态下,key1==0 则说明2号抢答选手按下按键
         {        
                    spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
         
            TR0=0;                           //启动定时器 开始倒计时
            flagD=0;                   //显示倒计时函数


        zqqd=2;         
     
         }


                          if((keyhao==3)&&(biaozhi3==1)) //在定时器运行状态下 则说明3号抢答选手按下按键
         {        
                         spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
           
            TR0=0;                           //启动定时器 开始倒计时
            flagD=0;                   //显示倒计时函数


        zqqd=3;         
     
         }
                          if((keyhao==4)&&(biaozhi4==1)) //在定时器运行状态下,则说明4号抢答选手按下按键
         {        
                    spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
   
            TR0=0;                           //启动定时器 开始倒计时
            flagD=0;                   //显示倒计时函数


        zqqd=4;         
      
         }
                                    if((keyhao==5)&&(biaozhi5==1)) //在定时器运行状态下,则说明5号抢答选手按下按键
         {        
                         spk=0;delayms(200);spk=1;
                        biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
            
            TR0=0;                           //启动定时器 开始倒计时
            flagD=0;                   //显示倒计时函数


        zqqd=5;         
      }
                 ////////成功抢答指示灯//////  
    if(zqqd==1)                                                                        ///1号
          {         
          jishu++;
                    delayms(20);                        
          if(jishu==50)                                   //计数到50次灯亮
          {
         deng1=0;        
          }
           
         if(jishu==100)                        //计数到100次灯灭
         {
         deng1=1;
            jishu=0;
         
           }
          }
                //*************        //
               if(zqqd==2)                                                          ///2号
          {         
          jishu++;
                    delayms(20);                //20*50=1秒
          if(jishu==50)
          {
         deng2=0;        
          }
           
         if(jishu==100)                        //计数到100次灯灭
         {
         deng2=1;
            jishu=0;
         
           }
          }
           ////*************//
              if(zqqd==3)                                                   //3号
          {         
          jishu++;
                    delayms(20);               
          if(jishu==50)                                                //计数到50次灯亮
          {
         deng3=0;        
          }
           
         if(jishu==100)                        //计数到100次灯灭
         {
         deng3=1;
            jishu=0;
         
           }
          }

                 ////****//////
              if(zqqd==4)                                                   //4号
          {         
          jishu++;
                    delayms(20);        
          if(jishu==50)                                                   //计数到50次灯亮
          {
         deng4=0;        
          }
           
         if(jishu==100)                        //计数到100次灯灭
         {
         deng4=1;
            jishu=0;
         
           }
          }
                  //////**************////////
              if(zqqd==5)                                                                 //5号
          {         
          jishu++;
                    delayms(20);        
          if(jishu==50)                                                  //计数到50次灯亮
          {
         deng5=0;        
          }
           
         if(jishu==100)                        //计数到100次灯灭
         {
         deng5=1;
            jishu=0;
         
           }
          }


         ///////////////// *************犯规抢答***************************///////////////
                 if((keyhao==1)&&(xxxx==0)) //说明1号抢答选手按下按键犯规
         {        
                         spk=0;delayms(200);spk=1; delayms(500); spk=0;delayms(200);spk=1;
                        fgqd=1;         
      
         }
                  if((keyhao==2)&&(xxxx==0))//说明2号抢答选手按下按键犯规
         {                                 
                        spk=0;delayms(200);spk=1; delayms(400); spk=0;delayms(200);spk=1;                 
                      fgqd=2;         
      
         }

                  if((keyhao==3)&&(xxxx==0))//说明3号抢答选手按下按键犯规
         {                                          
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=3;         
      
         }


                          if((keyhao==4)&&(xxxx==0)) //说明5号抢答选手按下按键犯规
         {                                   
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=4;         
      
         }

                  if((keyhao==5)&&(xxxx==0)) //说明4号抢答选手按下按键犯规
         {                                 
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=5;         
      
         }
                          ////////犯规抢答指示灯//////  
             if(xxxx==0)        ///大前提条件是,开始抢答之前有效
           {
    if(fgqd==1)                                                                        ///1号         犯规闪烁的快
          {         
          jishu++;
                    delayms(20);                 
          if(jishu==10)                                 //计数10次灯亮
          {
         deng1=0;        
          }
           
         if(jishu==20)                        //计数到20次灯灭
         {
         deng1=1;
            jishu=0;
         
           }
          }
                //*************        //
               if(fgqd==2)                                                          ///2号
          {         
          jishu++;
                    delayms(20);               
          if(jishu==10)                                 //计数10次灯亮
          {
         deng2=0;        
          }
           
         if(jishu==20)                        //计数到20次灯灭
         {
         deng2=1;
            jishu=0;
         
           }
//////////******剩余程序请移步附件区域***/////////////////

抢答器电路-原理图 PCB.rar

2.51 MB, 下载次数: 18, 下载积分: 黑币 -5

原理图+PCB

抢答器-程序 详细注释.rar

38.29 KB, 下载次数: 12, 下载积分: 黑币 -5

程序

抢答器仿真.rar

240.76 KB, 下载次数: 15, 下载积分: 黑币 -5

仿真

五路数显抢答器设计说明书.doc

1.36 MB, 下载次数: 14, 下载积分: 黑币 -5

说明书

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:262 发表于 2022-5-26 06:04 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表