標(biāo)題: (原創(chuàng))基于51單片機(jī)的五路數(shù)顯搶答器程序PCB仿真設(shè)計(jì) [打印本頁]

作者: 1979759100Ls    時(shí)間: 2022-5-24 18:24
標(biāo)題: (原創(chuàng))基于51單片機(jī)的五路數(shù)顯搶答器程序PCB仿真設(shè)計(jì)
(原創(chuàng)!)基于51單片機(jī)的五路數(shù)顯搶答器設(shè)計(jì)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)

要求如下:

程序難點(diǎn)分析:
1、搶答的判斷,處于開始搶答環(huán)節(jié)還是不處于搶答環(huán)節(jié),標(biāo)志位要控制好。
2、燈的閃爍問題,需要通過計(jì)數(shù)的形式解決,否則數(shù)碼管和LED一起閃爍。
附件有完整的程序(注釋詳細(xì))+仿真原件+設(shè)計(jì)說明書+PCB+原理圖!在附件!!

Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)

單片機(jī)源程序代碼:
#include<reg51.h>
#include<intrins.h>
sbit smg1=P2^0;                //定義數(shù)碼管第一位
sbit smg2=P2^1;                //定義數(shù)碼管第二位
sbit deng1=P2^3;                //燈1號(hào)
sbit deng2=P2^4;                // 燈2號(hào)
sbit deng3=P2^5;                // 燈3號(hào)
sbit deng4=P2^6;                // 燈4號(hào)
sbit deng5=P2^7;                // 燈5號(hào)


sbit keyksqd=P3^7;        //定義開始按鍵
sbit spk=P3^6;                //定義蜂鳴器
int dingshi;js;            //初始倒計(jì)時(shí)時(shí)間
int keyhao;                        //矩陣鍵值
int buzzbiaozhi=1;        //10S倒計(jì)時(shí)結(jié)束后蜂鳴器響一下的標(biāo)志位
int biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;         //正確搶答唯一
int xxxx=0;   //犯規(guī)搶答標(biāo)志位
int flagD=0; // 控制是否顯示倒計(jì)時(shí)         
int zqqd,fgqd;                   //zqqd正確搶答,fgqd犯規(guī)搶答
int  jishu;                         //用來控制LED閃爍的快慢,防止數(shù)碼管閃爍
int table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0X71};        // 數(shù)碼管段碼0 1 2 3 4 5 6 7 8 9 f

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



void Timer0_init()                        //定時(shí)器0初始化
{
    js=0;
        TMOD=0x01;                                //設(shè)置定時(shí)器0為工作方式1(M1M0為01)
        TH0=(65536-50000)/256;        //裝初值12M晶振定時(shí)50ms數(shù)為50000,1US是1000初始值,所以50ms是5萬
        TL0=(65536-50000)%256;               
        ET0=1;                                                //開定時(shí)器0中斷
        EA=1;                                                //開總中斷
}

void timer0() interrupt 1 using 1        //定時(shí)器0中斷服務(wù)函數(shù)
{
        TH0=(65536-50000)/256;                //裝初值12M晶振定時(shí)50ms數(shù)為50000
        TL0=(65536-50000)%256;        
        js++;                                                //疊加20次
        if(js==20)
        {
          js=0;                                                //清空
          dingshi--;                                        //產(chǎn)生1s的倒計(jì)時(shí)
         }
}

  ///矩陣按鍵//
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;               
}




///倒計(jì)時(shí)函數(shù)////
void djsxs()   //第一位,第二位 顯示倒計(jì)時(shí)函數(shù)
{        
        int b1,b2;
        b1=dingshi/10;
        b2=dingshi%10;                                  //將倒計(jì)時(shí)時(shí)間分成高低位
        P0=table[b1];                          
        smg1=0;                                                 //第1位顯示十位
        delayms(3);
        smg1=1;                                         //顯示十位數(shù)字
        P0=table[b2];
        smg2=0;                                           //第2位顯示各位
        delayms(3);                                 //顯示個(gè)位數(shù)字
        smg2=1;
        
}

//**顯示F犯規(guī)**//

void djsxs10() //高位數(shù)碼管顯示F 表示搶答犯規(guī)
{
         P0=0X71;                        //高位數(shù)碼管顯示F
    smg1=0;
    delayms(3);
    smg1=1;
}

////*****顯示搶答選手號(hào)碼*********///////
void haoma1()  //第二位數(shù)碼管顯示1
{
        P0=table[1];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位數(shù)碼管顯示1
}
void haoma2()  //第二位數(shù)碼管顯示2
{
        P0=table[2];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位數(shù)碼管顯示2
}

void haoma3()  //第二位數(shù)碼管顯示3
{
        P0=table[3];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位數(shù)碼管顯示3
}
void haoma4()  //第二位數(shù)碼管顯示4
{
        P0=table[4];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位數(shù)碼管顯示4
}
void haoma5()  //第二位數(shù)碼管顯示5
{
        P0=table[5];
    smg2=0;
    delayms(3);
    smg2=1;                 //第二位數(shù)碼管顯示5
}

void main()
{
   
         jishu=0;                                 //記錄多少毫秒累加
     dingshi=10;                        //修改倒計(jì)時(shí)初始值
         Timer0_init();             //初始化定時(shí)器中斷
        while(1)
        {
//          smg2=0;                 //上電數(shù)碼管不亮,因?yàn)榉情T取反
//          smg1=0;                 //上電數(shù)碼管不亮,因?yàn)榉情T取反
          keyhao=key_juzhen();
           switch(zqqd)        //顯示搶答的號(hào)碼
          {
                case 1:haoma1(); break;
                case 2:haoma2(); break;
                case 3:haoma3(); break;
                case 4:haoma4(); break;
                case 5:haoma5(); break;           
                default:  ;
       }
           if(xxxx==0)        ///大前提條件是,開始搶答之前有效,否則按下開始搶答數(shù)碼管亂碼。!
           {
           switch(fgqd)        //顯示犯規(guī)的號(hào)碼
          {
                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)) //在定時(shí)器運(yùn)行狀態(tài)下則說明1號(hào)搶答選手按下按鍵
         {        
                 
                        spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
           
            TR0=0;                           //啟動(dòng)定時(shí)器 開始倒計(jì)時(shí)
            flagD=0;                   //顯示倒計(jì)時(shí)函數(shù)
            

        zqqd=1;         
     
         }
                         if((keyhao==2)&&(biaozhi2==1)) //在定時(shí)器運(yùn)行狀態(tài)下,key1==0 則說明2號(hào)搶答選手按下按鍵
         {        
                    spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
         
            TR0=0;                           //啟動(dòng)定時(shí)器 開始倒計(jì)時(shí)
            flagD=0;                   //顯示倒計(jì)時(shí)函數(shù)


        zqqd=2;         
     
         }


                          if((keyhao==3)&&(biaozhi3==1)) //在定時(shí)器運(yùn)行狀態(tài)下 則說明3號(hào)搶答選手按下按鍵
         {        
                         spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
           
            TR0=0;                           //啟動(dòng)定時(shí)器 開始倒計(jì)時(shí)
            flagD=0;                   //顯示倒計(jì)時(shí)函數(shù)


        zqqd=3;         
     
         }
                          if((keyhao==4)&&(biaozhi4==1)) //在定時(shí)器運(yùn)行狀態(tài)下,則說明4號(hào)搶答選手按下按鍵
         {        
                    spk=0;delayms(200);spk=1;
                biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
   
            TR0=0;                           //啟動(dòng)定時(shí)器 開始倒計(jì)時(shí)
            flagD=0;                   //顯示倒計(jì)時(shí)函數(shù)


        zqqd=4;         
      
         }
                                    if((keyhao==5)&&(biaozhi5==1)) //在定時(shí)器運(yùn)行狀態(tài)下,則說明5號(hào)搶答選手按下按鍵
         {        
                         spk=0;delayms(200);spk=1;
                        biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
            
            TR0=0;                           //啟動(dòng)定時(shí)器 開始倒計(jì)時(shí)
            flagD=0;                   //顯示倒計(jì)時(shí)函數(shù)


        zqqd=5;         
      }
                 ////////成功搶答指示燈//////  
    if(zqqd==1)                                                                        ///1號(hào)
          {         
          jishu++;
                    delayms(20);                        
          if(jishu==50)                                   //計(jì)數(shù)到50次燈亮
          {
         deng1=0;        
          }
           
         if(jishu==100)                        //計(jì)數(shù)到100次燈滅
         {
         deng1=1;
            jishu=0;
         
           }
          }
                //*************        //
               if(zqqd==2)                                                          ///2號(hào)
          {         
          jishu++;
                    delayms(20);                //20*50=1秒
          if(jishu==50)
          {
         deng2=0;        
          }
           
         if(jishu==100)                        //計(jì)數(shù)到100次燈滅
         {
         deng2=1;
            jishu=0;
         
           }
          }
           ////*************//
              if(zqqd==3)                                                   //3號(hào)
          {         
          jishu++;
                    delayms(20);               
          if(jishu==50)                                                //計(jì)數(shù)到50次燈亮
          {
         deng3=0;        
          }
           
         if(jishu==100)                        //計(jì)數(shù)到100次燈滅
         {
         deng3=1;
            jishu=0;
         
           }
          }

                 ////****//////
              if(zqqd==4)                                                   //4號(hào)
          {         
          jishu++;
                    delayms(20);        
          if(jishu==50)                                                   //計(jì)數(shù)到50次燈亮
          {
         deng4=0;        
          }
           
         if(jishu==100)                        //計(jì)數(shù)到100次燈滅
         {
         deng4=1;
            jishu=0;
         
           }
          }
                  //////**************////////
              if(zqqd==5)                                                                 //5號(hào)
          {         
          jishu++;
                    delayms(20);        
          if(jishu==50)                                                  //計(jì)數(shù)到50次燈亮
          {
         deng5=0;        
          }
           
         if(jishu==100)                        //計(jì)數(shù)到100次燈滅
         {
         deng5=1;
            jishu=0;
         
           }
          }


         ///////////////// *************犯規(guī)搶答***************************///////////////
                 if((keyhao==1)&&(xxxx==0)) //說明1號(hào)搶答選手按下按鍵犯規(guī)
         {        
                         spk=0;delayms(200);spk=1; delayms(500); spk=0;delayms(200);spk=1;
                        fgqd=1;         
      
         }
                  if((keyhao==2)&&(xxxx==0))//說明2號(hào)搶答選手按下按鍵犯規(guī)
         {                                 
                        spk=0;delayms(200);spk=1; delayms(400); spk=0;delayms(200);spk=1;                 
                      fgqd=2;         
      
         }

                  if((keyhao==3)&&(xxxx==0))//說明3號(hào)搶答選手按下按鍵犯規(guī)
         {                                          
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=3;         
      
         }


                          if((keyhao==4)&&(xxxx==0)) //說明5號(hào)搶答選手按下按鍵犯規(guī)
         {                                   
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=4;         
      
         }

                  if((keyhao==5)&&(xxxx==0)) //說明4號(hào)搶答選手按下按鍵犯規(guī)
         {                                 
                        spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
                      fgqd=5;         
      
         }
                          ////////犯規(guī)搶答指示燈//////  
             if(xxxx==0)        ///大前提條件是,開始搶答之前有效
           {
    if(fgqd==1)                                                                        ///1號(hào)         犯規(guī)閃爍的快
          {         
          jishu++;
                    delayms(20);                 
          if(jishu==10)                                 //計(jì)數(shù)10次燈亮
          {
         deng1=0;        
          }
           
         if(jishu==20)                        //計(jì)數(shù)到20次燈滅
         {
         deng1=1;
            jishu=0;
         
           }
          }
                //*************        //
               if(fgqd==2)                                                          ///2號(hào)
          {         
          jishu++;
                    delayms(20);               
          if(jishu==10)                                 //計(jì)數(shù)10次燈亮
          {
         deng2=0;        
          }
           
         if(jishu==20)                        //計(jì)數(shù)到20次燈滅
         {
         deng2=1;
            jishu=0;
         
           }
//////////******剩余程序請(qǐng)移步附件區(qū)域***/////////////////

搶答器電路-原理圖 PCB.rar

2.51 MB, 下載次數(shù): 19, 下載積分: 黑幣 -5

原理圖+PCB

搶答器-程序 詳細(xì)注釋.rar

38.29 KB, 下載次數(shù): 14, 下載積分: 黑幣 -5

程序

搶答器仿真.rar

240.76 KB, 下載次數(shù): 16, 下載積分: 黑幣 -5

仿真

五路數(shù)顯搶答器設(shè)計(jì)說明書.doc

1.36 MB, 下載次數(shù): 15, 下載積分: 黑幣 -5

說明書


作者: heicad    時(shí)間: 2022-5-26 06:04
好資料,51黑有你更精彩!!!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1