四位競賽搶答器系統設計
1、設計一個四位競賽搶答單片機系統,可同時供 4 名選手或 4 個代表隊參加比賽,
每隊設置單獨的搶答按鈕,編號為 1、2、3、4;
2、給節目主持人設置一個“搶答開始”控制開關,用來控制搶答開始;
3、給節目主持人設置一個“系統清除”控制開關,用來控制系統清零;
4、搶答器具有編號鎖存、搶答計分、時間顯示和聲響提示等功能。
1)主持人按下“搶答開始”后,系統以減計時方式,顯示搶答剩余時間。
2)如果搶答時間計時結束,卻沒有選手搶答時,本次搶答無效,系統報警提示(顯
示單音,持續 2 秒);
3)搶答時間內,若有選手按動對應的搶答按鈕,此對編號立即鎖存,數碼管上顯
示出隊伍編號和此隊累計分數,同時系統給出音響提示(顯示單音,持續 2 秒)。
4)在主持人啟動“搶答開始”鍵前,選手提前搶答,搶答無效,系統報警提示(顯
示單音,持續 2 秒)。
5、搶答成功后,禁止其他選手搶答,優先搶答選手的編號一直保持到主持人將系
統清零為止;
6、搶答器具有利用旋鈕調整搶答時間功能,時間范圍 20 秒~50 秒。
我們需要硬件操作,仿真圖中的顯示是根據我們用的試驗箱調整的,另外我加了正誤判斷。其中還是有一些小的問題要改的。(懶不想改了)
需要其他功能可以自己看著改。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
5$Y3RYD5GCN~`LBT9WKAXCP.png (39.4 KB, 下載次數: 68)
下載附件
仿真圖
2021-1-5 17:51 上傳
單片機源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define u8 unsigned char
- #define u16 unsigned int
- #define LED_xianshi P0 //數碼管顯示端口
- #define LED_wei P2 //位選
- #define KEY_COL P3 //P3口計時信號輸ru
- sbit start=P1^5; //P1^5 開始搶答
- sbit clear=P1^4; //清零信號
- sbit man1=P1^0; //4人搶答口
- sbit man2=P1^1;
- sbit man3=P1^2;
- sbit man4=P1^3;
- sbit s1=P3^0;//對錯判斷
- sbit s2=P3^1;
- sbit k1=P2^0;//位選
- sbit k2=P2^1;
- sbit k3=P2^2;
- sbit k4=P2^3;
- char dc=0;
- int man=0;
- int score[4]={0,0,0,0}; //分數存儲開始為0
- int cont=0;
- int state=0; //狀態
- int sec0=20; //起始值
- int sec=20; //調節后的值
- char ji=0;
- char si=0;
- sbit warningLED =P1^7; //蜂鳴器聲響控制
- char biaozhi=0;
- //u8 code seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
- u8 code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x11,0xbf};
- unsigned int T0RH,T0RL,T1RH,T1RL;
- u8 duan[]={0x5f,0x5f,0x5f,0x40};
- u8 ad0;
- u8 KEY_up_flag=1;
- u8 KEY_use=0;
- char code dx516[3] _at_ 0x003b;
- u8 flag500ms=0; //設置標志位
- u8 startflag=0;
- u8 warning=0;
- unsigned char GetADCValue(unsigned char chn); //函數申明調用
- extern void I2CStart();
- extern void I2CStop();
- extern unsigned char I2CReadNAK();
- extern bit I2CWrite(unsigned char dat);
- unsigned char KEYscan(); //鍵盤掃描
- void reset_init();
- void KEYexe(u8 val);
- void Duanmove(u8 Movedir);
- void shanshuo();
- int scanduicuo();
- void delay2s()
- {
- TMOD=0x11;
- TH1=0x3c;
- TL1=0xb0;
- ET1=1;
- TR1=1;
- EA=1;
- }
- void delay(u16 t)
- {
- while(t--);
- }
- void chushihua()
- {
- TMOD=0x11;
- TH0=0x3c;
- TL0=0xb0;
- EA=1;
- ET0=1;
- TR0=1;
- }
- void display()
- {
- k4=0;
- LED_xianshi=duan[0];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=duan[1];
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=duan[2];
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=duan[3];
- delay(255);
- k1=1;
- LED_xianshi=0x00;
- }
- void main()
- {
-
- chushihua();
-
- warningLED=0;
-
- while(1)
- {
- k4=0;
- LED_xianshi=duan[0];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=duan[1];
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=duan[2];
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=duan[3];
- delay(255);
- k1=1;
- LED_xianshi=0x00;
-
-
- KEYscan(); //判斷是那個人按下
- if(state==0) //在未開始時能進行的操作
- {
- ad0=GetADCValue(0); //在未開始時可以設置倒計時初值;
- sec0=ad0*30/255+20;
-
- duan[3]=0xbf;
- duan[2]=0xbf;
- duan[1]=seg[sec0/10];
- duan[0]=seg[sec0%10];
-
- delay(255);
-
- if(man!=0)
- {
- man=0;
- warning=1;
- }
-
- if(start==0)
- {
- reset_init();//按下開始后倒計時 state標志位置1
- state=1;
- }
- }
-
- if(state==1) //處于開始的狀態時
- {
-
- if(man!=0)
- {
- dc=0;
- while(!dc)
- {
- scanduicuo();
-
- k4=0;
- LED_xianshi=seg[man];
- delay(255);
- k4=1;
- LED_xianshi=0x00;
-
- k3=0;
- LED_xianshi=0xbf;
- delay(255);
- k3=1;
- LED_xianshi=0x00;
-
- k2=0;
- LED_xianshi=0xbf;
- delay(255);
- k2=1;
- LED_xianshi=0x00;
-
- k1=0;
- LED_xianshi=0xbf;
- delay(255);
- k1=1;
- LED_xianshi=0x00;
-
- if(clear==0)
- {
- state=2;
- break;
- }
- }
- score[man-1]=score[man-1]+cont; //搶到后判斷對錯。對了加一分,錯了不加分
- duan[3]=seg[man];
- duan[2]=seg[17];
- duan[1]=seg[score[man-1]/10%10];
- duan[0]=seg[score[man-1]%10];
-
- display();
-
- state=2;
- warning=1;
- }
- else
- {
- if(flag500ms)
- {
- flag500ms=0;
- sec--;
- duan[3]=0xff;
- duan[2]=0xff;
- duan[1]=seg[sec/10%10];
- duan[0]=seg[sec%10];
- if(sec==0)
- {
- warning=1;
- state=2;
- }
- }
- }
- }
- else if(state==2)
- {
- if(start==1)
- {
- man=0x0000;
- delay(255);
- state=0;
- }
- }
- if(clear==0)
- {
- state=0;
- score[3]=0;
- score[2]=0;
- score[1]=0;
- score[0]=0;
- duan[3] = seg[17];
- duan[2] = seg[17];
- duan[1] = seg[17];
- duan[0] = seg[17];
-
- display();
-
- warningLED=0;
- delay(1000);
- while(!clear) //直到清零狀態結束
- {
- display();
- }
- }
- if(warning)
- {
- warning=0x0000;
- shanshuo();
- }
- }
- }
- unsigned char GetADCValue(unsigned char chn)
- {
- unsigned char val;
- I2CStart();
- if(!I2CWrite(0x48<<1))
- {
- I2CStop();
- return 0;
- }
- I2CWrite(0x40 | chn);
- I2CStart();
- I2CWrite(0x48<<1 | 0x01);
- val = I2CReadNAK();
- I2CStop();
- return val;
- }
- unsigned char KEYscan()
- {
- if(man1==0)
- {
- delay(1000);
- if(man1==0)
- {
- man=1;
- }
- }
- if(man2==0)
- {
- delay(1000);
- if(man2==0)
- {
- man=2;
- }
- }
- if(man3==0)
- {
- delay(1000);
- if(man3==0)
- {
- man=3;
- }
- }
- if(man4==0)
- {
- delay(1000);
- if(man4==0)
- {
- man=4;
- }
- } //掃描誰按下的
- if(start==1)
- {
- state=0;
- }
- if(start==0)
- {
- state==1;
- }
- if(clear==0)
- {
- state==2;
- }
- }
- void reset_init()
- {
- sec=sec0;
- duan[3] = 0;
- duan[2] = 0;
- duan[1] = seg[sec/10%10];
- duan[0] = seg[sec%10];
-
- man=0;
- flag500ms=0;
- TH0=0x3c;
- TL0=0xb0;
- }
- void shanshuo()
- {
- warningLED=1;
- delay2s();
- while(warningLED)
- {
- display();
- }
- if(warningLED==0 || si==0)
- {
- TR1=0;
- ET1=0;
- }
- }
- //定時
- void time() interrupt 1
- {
- TH0=0x3c;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
設計1.1.zip
(165.13 KB, 下載次數: 75)
2021-1-5 17:40 上傳
點擊文件名下載附件
程序和仿真 下載積分: 黑幣 -5
|