本設計是以八路搶答為基本理念。考慮到依需設定限時回答的功能,利用STC89C52單片機及外圍接口實現的搶答系統,利用單片機的定時器/計數器定時和記數的原理,將軟、硬件有機地結合起來,使得系統能夠正確地進行計時,同時使數碼管能夠正確地顯示時間。用開關做鍵盤輸出,揚聲器發生提示。同時系統能夠實現:在搶答中,只有開始后搶答才有效,如果在開始搶答前搶答為無效;搶答限定時間為60秒,倒計時為5秒時蜂鳴器報警,選手搶答成功后顯示選手編號以及剩余時間。
設計要求與指標:
11) 八個按鍵分別表示1至8號選手。 22) 有開始鍵,暫停鍵,復位鍵。 3) 當按下開始鍵后,從60秒開始倒計時,當倒計時為5秒時,蜂鳴器報警。 4) 有選手按下搶答按鍵后,液晶屏顯示選手編號和剩余時間。 5) 搶答成功后按復位鍵從新開始。
制作出來的實物圖如下:
IMG_20150308_001433.jpg (2.84 MB, 下載次數: 47)
下載附件
2020-12-13 21:13 上傳
IMG_20150308_001949.jpg (3.15 MB, 下載次數: 34)
下載附件
2020-12-13 21:13 上傳
流程圖.jpg (13.08 KB, 下載次數: 39)
下載附件
2020-12-13 21:15 上傳
使用說明
一、 主要功能:
1、采用4位數碼管設計。
2、下排按鍵一一對應八位選手。
3、上排三個按鍵,從走到右依次為:開始、暫停、復位。
4、操作流程:上電后數碼管顯示“----”當主持人按下“開始”鍵后,倒計時60秒,開始計時,此時,八位選手就可以搶答,如有緊急情況需要停止的話,主持人按“暫停”鍵就可以,如果有選手搶答成功,數碼管顯示“1 25”,1表示是1號選手,25表示剩余還25秒,倒計時小于5秒時,蜂鳴器響,提示時間快要結束,當倒計時為0秒時,此題結束,表示沒有任何選手搶答成功,主持人按“復位”鍵后從新開始。
5、可以設定倒計時時間,在上電后,數碼管顯示“----”,此時按下1號選手對應的按鍵,進入倒計時時間設定狀態,2號選手對應的按鍵為時間加,3號選手對應的按鍵為時間減,設定完成后再按1號選手鍵退出。
6、供電方式,1、電池供電,2、usb供電
電池供電需3節5號電池,請盡量用新電池,已保證足夠的電壓。
Usb供電可以連接手機充電器,筆記本、臺式電腦,如插入其他供電設備,請確保電壓為5V。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (19.5 KB, 下載次數: 44)
下載附件
2020-12-14 04:44 上傳
51hei.png (19.56 KB, 下載次數: 37)
下載附件
2020-12-14 04:45 上傳
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- sbit smg1=P2^4; //定義數碼管第一位
- sbit smg2=P2^6; //定義數碼管第二位
- sbit smg3=P2^7; //定義數碼管第三位
- sbit smg4=P2^5;
- sbit keyks=P2^2; //定義開始按鍵
- sbit keytz=P2^1; //定義停止按鍵
- sbit keyqc=P2^0; //定義清除按鍵
- sbit key1=P1^4; //定義1號搶答選手 sbit
- sbit key2=P1^5; //定義2號搶答選手
- sbit key3=P1^6; //定義3號搶答選手
- sbit key4=P1^7; //定義4號搶答選手
- sbit key5=P3^4; //定義5號搶答選手
- sbit key6=P3^5; //定義6號搶答選手
- sbit key7=P3^6; //定義7號搶答選手
- sbit key8=P3^7; //定義8號搶答選手
- sbit spk=P1^0; //定義蜂鳴器
- int djs=60,js=0; //djs和bt是初始倒計時時間,可修改
- unsigned char flag=0;
- //int table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- int table[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7,0x80};
- void delayms(int x) //延時函數
- {
- char i;
- while(x--)
- {
- for(i=500;i>0;i--);
- }
- }
-
- void Timer0_init() //定時器0初始化
- {
- js=0;
- TMOD=0x01; //T0為定時器方式1
- TH0=60;
- TL0=176;
- //TR0=1;//IT1=1;
- ET0=1;//EX1=1;
- EA=1;
- }
- void timer0() interrupt 1 using 1 //定時器0中斷服務函數
- {
- TF0=0;
- TH0=60;
- TL0=176; //賦初值
- js++;
- if(flag==1)
- {
- if(js<8)
- spk=0;
- else spk=1;
- }
- if(js==20)
- { js=0;
- djs--; //產生1s的倒計時
- }
- }
- void djsxs() //顯示倒計時函數
- { int b1,b2;
- b1=djs/10;
- b2=djs%10; // 將倒計時時間分成高低位
- P0=table[b1];
- smg2=0;
- delayms(3);
- smg2=1; //顯示十位數字
- P0=table[b2];
- smg3=0;
- delayms(3); //顯示個位數字
- smg3=1;
- }
- void djsxs30() //第二位數碼管顯示-
- {
- P0=0x80; //第二位數碼管
- smg4=0;
- delayms(3);
- smg4=1;
- }
- void djsxs22()
- {
- P0=0x80;
- smg1=0;
- delayms(3);
- smg1=1;
- //第一位數碼管顯示-
- P0=0x80; //第二位數碼管
- smg4=0;
- delayms(3);
- smg4=1;
-
- P0=0x80;
- smg2=0;
- delayms(3); //第三位數碼管顯示-
- smg2=1;
- P0=0x80;
- smg3=0;
- delayms(3);
- smg3=1; //第四位數碼管顯示-
- }
- void djsxs1()
- {
- P0=table[1];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示1
- }
- void djsxs2()
- {
- P0=table[2];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示2
- }
- void djsxs3()
- {
- P0=table[3];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示3
- }
- void djsxs4()
- {
- P0=table[4];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示4
- }
- void djsxs5()
- {
- P0=table[5];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示5
- }
- void djsxs6()
- {
- P0=table[6];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示6
- }
- void djsxs7()
- {
- P0=table[7];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示7
- }
- void djsxs8()
- {
- P0=table[8];
- smg1=0;
- delayms(3);
- smg1=1; //第一位數碼管顯示8
- }
- void main()
- {
- int djs1=60;
- Timer0_init(); //初始化定時器中斷
- spk=1; //蜂鳴器不響
- djs=60; //倒計時賦值
- while(1)
- {
- LOOP1: djs=djs1;
- djsxs22(); //LOOP1是標號,顯示 - --
- if(key1==0) //在定時器運行狀態下,key1==0 則說明1號選手按下按鍵
- {
- delayms(3);
- if(key1==0)
- {
- while(!key1); //去除按鍵抖動后,重新在判斷,是否確實按下
- djs=60;
- while(1)
- {
- TR0=0; //定時器停止
- djsxs();
- if(key2==0) //復位按下按下
- {
- delayms(8); //去除抖動
- if(key2==0) //再次判斷是否按下復位按鍵
- {
- do
- {
- while(!key2); //如果按下復位鍵,則回到- --狀態
- delayms(5);
- }
- while(key2!=1);
- djs++;
- djs1=djs;
- }
- }
- if(key3==0) //復位按下按下
- {
- delayms(8); //去除抖動
- if(key3==0) //再次判斷是否按下復位按鍵
- {
- do
- {
- while(!key3); //如果按下復位鍵,則回到- --狀態
- delayms(5);
- }
- while(key3!=1);
- djs--;
- djs1=djs;
- }
- }
- if(key1==0) //復位按下按下
- {
- delayms(3); //去除抖動
- if(key1==0) //再次判斷是否按下復位按鍵
- {
- while(!key1); //如果按下復位鍵,則回到- --狀態
- goto LOOP1; //goto語句,回到loop1表號處
- }
- }
- }
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(3); //去除按鍵抖動
- if(keyks==0)
- {
- while(!keyks); //以上表示按下開始按鍵
- //spk=1; //蜂鳴器不響
- TR0=1; //啟動定時器 開始倒計時
- while(1)
- {
- djsxs();
- if(keytz==0)
- {
- delayms(3); //此處表示出去抖動, 以后不一一標出
- if(keytz==0)
- {
- while(!keytz); //以上表示按下停止按鍵后
- {
- TR0=0; //定時器停止
- flag=0;//
- spk=1;
- }
- }
- }
- if(keyks==0)
- {
- //spk=0;
- delayms(3);
- if(keyks==0)
- {
- while(!keyks); //以上表示按下清楚按鍵后
- //spk=1; //蜂鳴器不響
- TR0=1; //定時器啟動
- }
- }
- /***************************以下是八個選手搶答,key1表示1號選手,依次類推,注釋只寫第一位選手,其他和第一個完全一致,************************************/
- if((key1==0)&&(TR0==1)) //在定時器運行狀態下,key1==0 則說明1號選手按下按鍵
- { spk=0; //蜂鳴器響
- delayms(3);
- if(key1==0)
- {
- while(!key1); //去除按鍵抖動后,重新在判斷,是否確實按下
- {
- spk=1; //蜂鳴器不響
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0; //定時器停止
- djsxs1(); //顯示選手編號
- djsxs30(); //第二位數碼管顯示-
- djsxs(); //顯示剩余倒計時時間
- if(keyqc==0)
- {
- delayms(3); //去除抖動
- if(keyqc==0)
- {
- while(!keyqc); //如果按下清楚鍵,則回到- --狀態
- goto LOOP1; //goto語句,回到loop1表號處
- }
- }
- }
- }
- }
- if((key2==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key2==0)
- {
- while(!key2);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs2();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key3==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key3==0)
- {
- while(!key3);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs3();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key4==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key4==0)
- {
- while(!key4);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs4();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key5==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key5==0)
- {
- while(!key5);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs5();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key6==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key6==0)
- {
- while(!key6);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs6();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- }
- if((key7==0)&&(TR0==1))
- { spk=0;
- delayms(3);
- if(key7==0)
- {
- while(!key7);
- {
- spk=1;
- flag=0;//清0最后五秒響蜂鳴器
- }
- while(1)
- {
- TR0=0;
- djsxs7();
- djsxs30(); //第二位數碼管顯示-
- djsxs();
- if(keyqc==0)
- {
- delayms(3);
- if(keyqc==0)
- {
- while(!keyqc);
- goto LOOP1;
- }
- }
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
基于單片機的八路智能搶答器.7z
(413.61 KB, 下載次數: 57)
2020-12-14 04:45 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|