|
一、四鍵設計功能1、程序開始當按下開始搶答按鈕后,數碼管顯示搶答倒計時。在該時間內八路搶答按下有效,若超出搶答時間蜂鳴器發出搶答失敗警報預示該次搶答失敗。若有效時間內有人搶答則1位數碼管顯示搶答選手號,二位數碼管顯示答題倒計時。在答題有效時間內答題完成則搶答成功,若超過答題時間,蜂鳴器給出答題超時警報,答題失敗。2、在開始搶答的過程中可按下結束搶答來中斷此次搶答。直接結束搶答后數碼管均顯示0.等待下次搶答開始。3、在開始搶答時,可以不使用開始搶答按鈕而按下隨機抽擊選手答題按鈕來隨機抽取一位選手答題。該按鈕按下后1位數碼管顯示隨機選手號,二位數碼管顯示答題倒計時,若時間超時,蜂鳴器給出警報。若有效時間內答題,則答題成功。4、在隨機抽取選手答題中,可以按下結束隨機抽取選手答題按鈕來結束隨機抽取答題。結束后數碼管均顯示0.等待下次搶答開始。二、兩鍵設計功能1、程序開始當按下開始搶答按鈕后,數碼管顯示搶答倒計時。在該時間內八路搶答按下有效,若超出搶答時間蜂鳴器發出搶答失敗警報預示該次搶答失敗。若有效時間內有人搶答則1位數碼管顯示搶答選手號,二位數碼管顯示答題倒計時。在答題有效時間內答題完成則搶答成功,若超過答題時間,蜂鳴器給出答題超時警報,答題失敗。2、在開始搶答的過程中可按下結束搶答來中斷此次搶答。直接結束搶答后數碼管均顯示0.等待下次搶答開始。
P0^0; //二位數碼管第一位選擇腳sbit DG2 = P0^1; //二位數碼管第二位選擇腳sbit DG3 = P0^3;//P2端口 數碼管段選//P1端口 八位選手搶答sbit start_qd_pin = P3^7;//開始搶答按鈕連接管腳sbit end_qd_pin = P3^5; //結束搶答按鈕連接管腳sbit start_srand_qd_pin = P3^4;//開始隨機抽取選手按鈕連接管腳sbit end_srand_qd_pin = P3^6;//結束隨機抽取選手按鈕連接管腳sbit beep=P3^3;//蜂鳴器連接管腳unsigned char weixuan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//數碼管段碼:0123456789unsigned char qd_num=0; //搶答選手號unsigned char qd_time=0; //搶答倒計時間unsigned char timeout_num=0; //定時器產生中斷次數unsigned char work_status = 0; //工作狀態,下面幾個為工作狀態定義的宏#define START_QD_STATUS 0#define WAIT_QD_STATUS 1#define ACK_QD_STATUS 2#define ACK_SRAND_QD_STATUS 3/*------延時2ms函數------*/void delay2ms(void) //誤差 0us{ unsigned char a,b; for(b=4;b>0;b--) for(a=248;a>0;a--); _nop_(); //if Keil,require use intrins.h}/*------延時50ms函數,參數num為延時多少個50ms------*/void delay50ms(unsigned int num) //誤差 0us{ unsigned char a,b; unsigned char i=0; for(i=0; i<num; i++) { for(b=173;b>0;b--) for(a=143;a>0;a--); }}/*---初始化定時器0---*/void InitTimer0(void)//50ms{ TMOD = 0x01;//定時器工作模式1 TH0 = 0x3C; //定時器裝值高8位 TL0 = 0x0B0;//定時器裝值低8位 EA = 1; //使能總中斷 ET0 = 1; //使能定時器0中斷 TR0 = 1; //啟動定時器}/*------關閉定時器0------*/void end_Timer0(void){ ET0 = 0;//關閉定時器0中斷 TR0 = 0;//停止定時器0}/*----初始化函數-----*/void init(void){ DG1 = 0; DG2 = 0; DG3 = 0; beep = 0;//上電時由于該腳為高,而為高時蜂鳴器會叫,故初始化為低}/*----------等待開始搶答狀態該狀態下一直等待按下開始搶答按鈕或隨機搶答按鈕,再進入相應的工作狀態!這種狀態機的編程方式是當前單片機開發者的主流思想。---------*/void start_qd_status(void){ if(start_qd_pin == 0)//檢測到開始搶答按鈕按下 { work_status = WAIT_QD_STATUS;//工作狀態設置為等待答題狀態 qd_num = 0; //回答選手號為0,等待選手按下 qd_time = 20; //20s搶答時間 timeout_num=0; //中斷次數清0 InitTimer0(); //開啟定時器0 } if(start_srand_qd_pin == 0)//檢測到隨機抽取選手答題按鈕按下 { work_status = ACK_SRAND_QD_STATUS;//工作狀態設置為隨機選手回答狀態 srand(TL0%100); //產生隨機數種子,srand和rand函數有興趣可以百度一下單片機產生隨機數方法! qd_num = (rand()%9);//0-8, 產生隨機數 if(qd_num == 0) //防止產生隨機數0 qd_num = (rand()%9); //再次產生隨機數 qd_time = 30; //30s答題時間 timeout_num=0; //中斷次數清0 InitTimer0(); //開始定時器0 }}/*-------開始按鈕按下后,等待選手搶答狀態函數------*/void wait_qd_status(void){ unsigned char i = 0; if(qd_time == 0)//無人搶答,搶答時間已到 { end_Timer0();//停止定時器0 //蜂鳴器給出無人搶答警報 beep = 1; //蜂鳴器響 delay50ms(40); beep = 0; work_status = START_QD_STATUS;//無人搶答后恢復原始狀態,設置工作狀態為開始搶答狀態 } if(end_qd_pin == 0)//檢測到結束按鍵 { end_Timer0();//停止定時器0 qd_num = 0;//回答選手號為0 qd_time = 0;//搶答時間清0 work_status = START_QD_STATUS;//工作狀態置開始搶答狀態 } switch(P1)//檢測哪位選手按下搶答按鈕 { case 0xfe://1號 qd_num = 1;//回答選手號為1 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xfd://2號 qd_num = 2;//回答選手號為2 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xfb://3號 qd_num = 3;//回答選手號為3 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xf7://4號 qd_num = 4;//回答選手號為4 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xef://5號 qd_num = 5;//回答選手號為5 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xdf://6號 qd_num = 6;//回答選手號為6 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0xbf://7號 qd_num = 7;//回答選手號為7 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; case 0x7f://8號 qd_num = 8;//回答選手號為8 qd_time = 30; timeout_num=0; InitTimer0(); work_status = ACK_QD_STATUS; break; default: break; }}/*------選手回答問題狀態------*/void ack_qd_status(){ unsigned char i = 0; if(qd_time == 0)//答題超時 { end_Timer0();//結束定時器0 qd_num = 0; qd_time = 0; for(i=0;i<3;i++)//選手回答問題超時警報 { beep = 1; delay50ms(5); beep = 0; delay50ms(5); } work_status = START_QD_STATUS;//設置工作狀態為開始搶答狀態 } if(end_qd_pin == 0)//結束按鍵按下 { end_Timer0();//結束定時器0 qd_num = 0; qd_time = 0; work_status = START_QD_STATUS;//設置工作狀態為開始搶答狀態 }}/*-------隨機選手回答狀態-------*/void ack_srand_status(){ unsigned char i = 0; if(qd_time == 0)//答題超時 { end_Timer0();//結束定時器0 qd_num = 0; qd_time = 0; for(i=0;i<3;i++)//隨機選手回答問題超時警報 { beep = 1; delay50ms(5); beep = 0; delay50ms(5); } work_status = START_QD_STATUS; } if(end_srand_qd_pin == 0)//結束按鍵 { end_Timer0();//結束定時器0 qd_num = 0; //選手號清0 qd_time = 0;//時間清0 work_status = START_QD_STATUS;//設置工作
|
|