本帖最后由 123456ld 于 2019-11-11 15:09 編輯
基于c51的四路搶答器,本實驗通過數(shù)碼管結合矩陣按鍵及獨立按鍵組成四路搶答器。對不同選手的判斷從而在數(shù)碼管上顯示那位選手搶答成功暫停計時,或哪三位選手犯規(guī)觸發(fā)蜂鳴器報警。其中倒計時的開始由獨立按鍵K1實現(xiàn),對搶答或倒計時的恢復由獨立按鍵K3實現(xiàn)。程序源碼為本人自創(chuàng),如有不懂,請留言發(fā)問。篇幅有限僅提供部分代碼。詳情請下載后查閱。
該程序適用stc89c51單片機
單片機源程序如下:
- /****************************************************
- * 實驗內容
- * 四路搶答器
- **************************************************/
- #include <reg52.h>
- typedef unsigned int u16;
- typedef unsigned char u8;
- /***********************************************
- *
- * 變量及引腳定義聲明
- *************************************************/
- sbit AA = P2^2;
- sbit BB = P2^3;
- sbit CC = P2^4;
- sbit k3 = P3^2;
- sbit k4 = P3^3;
- sbit beep = P1^5;
- int i=0; //初始狀態(tài)控制毫秒的兩位數(shù)碼管為0
- int j=10; //初始狀態(tài)控制秒的兩位數(shù)碼管為10
- int jishu=0; //以10ms為一個劑量,精準控制毫秒的99-0
- int cishu=0; //消除最后一秒帶來的影響
- int xuanshou=0; //選手編號
- int biaozhi=1; //控制搶答開始后只有一個人可以被記錄
- int wei1=0 , wei2=0 , wei3=0;
- enum position {zero, one, two, three, four, five, six, seven};
- u16 code duanxuan[16] = { 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71};
- /*****************************************************
- *
- * 子函數(shù)申明
- ******************************************************/
- void delay(u16 i); //延時函數(shù)
- void jvzhen(); //矩陣鍵盤選手確定
- void weixuan( u16 i ); //數(shù)碼管位選
- void timer0(); //定時器初始化
- void xianshi(); //數(shù)碼管倒計時顯示
- void int0(); //中斷0倒計時開始
- void int1(); //中斷1問題結束恢復數(shù)碼管
- void panduan(); //答題選手的判斷
- void qiangda(); //選手搶答時的判斷
-
- /*****************************************************
- * 主函數(shù)
- *******************************************************/
- void main()
- {
- int0();
- int1();
- timer0();
- while(1)
- {
- xianshi();
- jvzhen();
- panduan();
- qiangda();
- }
- }
- void qiangda()
- {
- if( j==10&&xuanshou!=0 )
- {
- wei1 = xuanshou;
- while(1)
- {
- xianshi();
- weixuan(7);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( xuanshou!=wei1 )
- {
- break;
- }
- if( k4==0 )
- {
- break;
- }
- }
- wei2 = xuanshou;
- while(1)
- {
- xianshi();
-
- weixuan(7);
- P0 = duanxuan[wei2];
- delay(1);
- P0 = 0x00;
-
- weixuan(6);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( xuanshou!=wei2 )
- {
- break;
- }
- if( k4==0 )
- {
- break;
- }
- }
- wei3 = xuanshou;
- while(1)
- {
- xianshi();
-
- weixuan(7);
- P0 = duanxuan[wei3];
- delay(1);
- P0 = 0x00;
-
- weixuan(6);
- P0 = duanxuan[wei2];
- delay(1);
- P0 = 0x00;
-
- weixuan(5);
- P0 = duanxuan[wei1];
- delay(1);
- P0 = 0x00;
-
- beep=~beep;
- delay(1);
- jvzhen();
- if( k4==0 )
- {
- break;
- }
- }
- }
- }
- /* 延時 */
- void delay(u16 i)
- {
- u16 a;
- while(i--)
- {
- for(a = 0; a < 100; a++)
- {
- ;
- }
- }
- }
- /* 顯示哪位選手按鍵暫停 */
- void panduan()
- {
- if( i!=0 && xuanshou!=0 )
- {
- switch( xuanshou )
- {
- case 1 : TR0=0; weixuan(7); P0=duanxuan[1]; delay(1); P0 = 0x00; break;
- case 2 : TR0=0; weixuan(7); P0=duanxuan[2]; delay(1); P0 = 0x00; break;
- case 3 : TR0=0; weixuan(7); P0=duanxuan[3]; delay(1); P0 = 0x00; break;
- case 4 : TR0=0; weixuan(7); P0=duanxuan[4]; delay(1); P0 = 0x00; break;
- }
- biaozhi=0;
- }
- }
- /* 矩陣鍵盤選手確定 */
- void jvzhen()
- {
- P1 = 0x0f;
- if( (P1!=0x0f&&biaozhi==1) )
- {
- delay(5);
- if( (P1!=0x0f) )
- {
- switch( P1 )
- {
- case 0x07 : xuanshou = 1; break;
- case 0x0b : xuanshou = 2; break;
- case 0x0d : xuanshou = 3; break;
- case 0x0e : xuanshou = 4; break;
- }
- P1=0xf0;
- switch( P1 )
- {
- case (0x70) : xuanshou = xuanshou; break;
- }
- }
- }
- }
- /* 數(shù)碼管位選*/
- void weixuan( u16 i )
- {
- switch(i)
- {
- case (zero): CC = 0; BB = 0; AA = 0; break; //第零位
- case (one): CC = 0; BB = 0; AA = 1; break; //第一位
- case (two): CC = 0; BB = 1; AA = 0; break; //第二位
- case (three): CC = 0; BB = 1; AA = 1; break; //第三位
- case (four): CC = 1; BB = 0; AA = 0; break; //第四位
- case (five): CC = 1; BB = 0; AA = 1; break; //第五位
- case (six): CC = 1; BB = 1; AA = 0; break; //第六位
- case (seven): CC = 1; BB = 1; AA = 1; break; //第七位
- }
- }
- /* 定時器初始化*/
- void timer0()
- {
- TMOD =0x01;
- TH0 = (65536-1000)/256;
- TL0 = (65536-1000)%256; //1ms
- ET0 = 1;
- EA = 1;
- }
- /* 倒計時顯示 */
- void xianshi()
- {
- weixuan(0);
- P0 = duanxuan[i%10];
- delay(1);
- P0 = 0x00;
-
- weixuan(1);
- P0 = duanxuan[i/10];
- delay(1);
- P0 = 0x00;
- weixuan(2);
- P0 = 0x40;
- delay(1);
- P0 = 0x00;
-
- weixuan(3);
- P0 = duanxuan[j%10];
- delay(1);
- P0 = 0x00;
-
- weixuan(4);
- P0 = duanxuan[j/10];
- delay(1);
- P0 = 0x00;
- }
- /* 倒計時開始 */
- void int0()
- {
- EA=1;
- IT0=1;
- EX0=1;
- }
- /* 數(shù)碼管復位 */
- void int1()
- {
- EX1=1;
- IT1=1;
- EA=1;
- }
復制代碼
所有資料51hei提供下載:
四路搶答器(倒計時).zip
(35.3 KB, 下載次數(shù): 39)
2019-11-10 12:02 上傳
點擊文件名下載附件
|