- #include <REG51.h>
- #include <STRING.H>
- /******************************************************************
- * 自定義Macro
- *******************************************************************/
- //編碼的均為反向編碼
- #define CLEAR 0x7f //定義清空的反碼
- #define LED_BEGIN 0x01 // 定義開始時數碼管的顯示
- #define LED_FOUL 0x38 // 犯規后顯示字母"F",數碼管編碼
- #define LED_C 0x31 // 字母"C"的編碼
- #define LED_L 0x71 // 字母"L"的編碼,兩個用來在主持人取消之后顯示"CL"--cancel
- #define GET 1 // 這個是作為一個函數的參數來混的,就是成功搶答的意思
- #define FOUL 0 // 和上面的參數一起混的,犯規---這兩個的用法在后面體現
- #define READY 0x7e
- //下面是給上位機發送的指令,對應的是cmdID
- #define _STRING_READY_ 9//調整好搶答倒計時,準備開始搶答
- #define _STRING_START_ 8//讀秒結束,搶答開始
- #define _STRING_CANCEL_ 7//取消搶答
- #define _CHANGE_TIME_ 6//每次讀秒
- //發送1--4的指令代表搶答端的序號
- //因為在板子上面采用的是12M的晶振,仿真時候采用的是11.0529M的晶振,為了方便不同時候編譯方便,這里與后面的條件編譯一起使程序修改參數比較方便
- //#define CLOCK_FREQUENCY_12M 1
- /******************************************************************
- * 自定義數據類型
- *******************************************************************/
- typedef unsigned char Byte; // 一個字節
- typedef unsigned int Word; // 一個字,兩個字節
- typedef bit Bool; // 模仿布爾型變量
- //typedef sbit Port; // 本想用自定義一個端口類型的變量,比較方便,但是這句話步知道為何通不過編譯
- /******************************************************************
- * 定義MAX7219寄存器
- *******************************************************************/
- #define REG_NO_OP 0x00 // 定義空操作 register
- #define DIG_1 0x01 // 定義數碼管1 register
- #define DIG_2 0x02 // 定義數碼管2 register
- #define DIG_3 0x03 // 定義數碼管3 register
- #define DIG_4 0x04 // 定義數碼管4 register
- #define DIG_5 0x05 // 定義數碼管5 register
- #define DIG_6 0x06 // 定義數碼管6 register
- #define DIG_7 0x07 // 定義數碼管7 register
- #define DIG_8 0x08 // 定義數碼管8 register
- #define REG_DECODE 0x09 // 定義解碼控制 register
- #define REG_INTENSITY 0x0a // 定義顯示亮度 register
- #define REG_SCAN_LIMIT 0x0b // 定義掃描限制 register
- #define REG_SHUTDOWN 0x0c // 定義"shutdown"模式 register
- #define REG_DISPLAY_TEST 0x0f // 定義"display test"模式 register
- #define INTENSITY_MIN 0x00 // 定義最低顯示亮度
- #define INTENSITY_MAX 0x0f // 定義最高顯示亮度
- /*********************************************************************
- * 定義硬件引腳連接
- **********************************************************************/
- sbit DATA=P2^0; // MAX7219的數據口
- sbit LOAD=P2^1; // MAX7219的鎖存端口
- sbit CLK=P2^2; // MAX7219的時鐘端口
- sbit HOST_START=P0^0; //主持人按鍵,用來重新開始的按鍵 start
- sbit HOST_CANCEL=P0^1; //主持人用來取消搶答的按鍵 clear
- sbit SWITCH1_3=P1^4; // 調節倒計時時間的撥碼開關,下劃線前面的號代表開關的序號,下劃線后面的號代表該開關的數值
- sbit SWITCH2_2=P1^5; // 同上
- sbit SWITCH3_2=P1^6; // 同上
- sbit SWITCH4_1=P1^7; // 同上
- sbit BEEP=P0^7; //定義蜂鳴器端口
- #ifdef USE_SOUND //可以通過define來選擇要不要使用仿真時候的聲音
- sbit LS138_C=P2^4; //定義譯碼器輸入端
- sbit LS138_B=P2^5; //同上
- sbit LS138_A=P2^6; //同上
- sbit LS138_E1=P2^7; //定義譯碼器使能端
- #endif
- /*********************************************************************
- * 定義全局變量
- **********************************************************************/
- Byte data intrCounter; // 計時器中斷次數
- Byte data beginNum; // 開始倒計時的時間
- Byte data counterBack; // 將中斷次數放在里面以備后用
- Byte data showNum; // 數碼管正在顯示的時間
- Bool data isStart; // 是否開始搶答
- Bool data isFoul; // 是否犯規
- Bool data isPressed; // 是否有搶答的鍵按下
- Byte data number_temp; // 用來記錄P1口上次狀態的一個變量
- Bool data needResetTimes;//記錄是否需要重設Timer0的溢出次數
- code unsigned char C51BOX2[3] _at_ 0x43; //使用C51Box時候防止程序跑丟
- /***********************************************************************
- * 共陰極七段數碼管顯示對應段查詢表(數字0-9分別對應code_table[0]-[9])
- ***********************************************************************/
- Byte code code_table_zheng[10]=
- {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};
- Byte code code_table[10]=
- {0x01,0x4f,0x12,0x06,0x4c,0x24,0x20,0x0f,0x00,0x04};
- /***********************************************************************
- * 函數聲明
- ***********************************************************************/
- void MAX7219_SendByte (Byte dataout);
- void MAX7219_Write (Byte reg_number, Byte dataout);
- void MAX7219_DisplayChar(Byte digit, Byte character);
- void MAX7219_Clear (void);
- void MAX7219_SetBrightness (Byte brightness);
- void MAX7219_DisplayTestStart (void);
- void MAX7219_DisplayTestStop (void);
- void MAX7219_ShutdownStart (void);
- void MAX7219_ShutdownStop (void);
- void MAX7219_Init (void);
- void Delay10ms(void);
- Bool GetHostStartKey (void);
- Bool GetHostCancelKey (void);
- void GetCounter(void);
- Byte GetPressed(Byte KeyState);
- Byte GetPressedWireless(Byte KeyState);
- void IT0_Init(void);
- void Timer0_Overflow();
- void PressedHandle(Byte keyPressed);
- void GetOrFoulHandle(Bool state);
- void CancelHandle();
- void SPEAKER_count (void); //聲明倒計時聲音函數
- void SPEAKER_start(void); //聲明開始搶答聲音函數
- void SPEAKER_get(void); //聲明搶到聲音函數
- void SPEAKER_foul(void); // 聲明犯規聲音函數
- void initialSerial();
- void sendNumber(int number);//串口發送數字,這里發送的是CommandID
- void sendString(unsigned char *string);//串口發送字符串
- /***********************************************************************
- * MAX7219_SendByte()
- *
- * 描述: 向MAX7219傳送一個字節的數據
- * Arguments : dataout = data to send
- * Returns : none
- *************************************************************************/
- void MAX7219_SendByte (Byte dataout)
- {
- Byte i;
- for (i=8;i>0;i--)
- {
- Byte mask=1<<(i-1);//mask是個掩碼,取位使用
- CLK=0;//MAX7219的位傳入是在時鐘的上升沿之前,所以在每發一位之前都要變為低電平
- if (dataout&mask)
- DATA=1;
- else
- DATA=0;
- CLK=1;//八個bit都傳遞完成后變為高電平,鎖存
- }
- }
- /***********************************************************************
- * MAX7219_Write()
- *
- * 描述: 向 MAX7219 寫命令
- * Arguments : reg_number = register to write to
- * dataout = data to write to MAX7219
- * Returns : none
- 未完~
- ***************************************************************************/
- void MAX7219_Write (Byte reg_number, Byte dataout)
- {
- LOAD=0;//也是鎖存上升沿之前的,發這兩個字節之前要變為低電平
- MAX7219_SendByte(reg_number);//發送寄存器地址
- MAX7219_SendByte(dataout);//發送數據
- LOAD=1;//變為高電平,鎖存
- }
- /**************************************************************************
- * MAX7219_DisplayChar()
- *
- * 描述: 使某一位顯示一個數字
- * Arguments : digit = digit number (0-7)
- * character = character to display (0-9, A-Z)
- * Returns : none
- **************************************************************************/
- void MAX7219_DisplayChar(Byte digit, Byte character)
- {
- MAX7219_Write(digit, character);
- }
- /**************************************************************************
- * MAX7219_Clear()
- *
- * 描述: 清除所有位的顯示
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_Clear (void)
- {
- Byte i;
- for (i=1; i<=2; i++)
- MAX7219_Write(i, CLEAR);//把八個數碼管全都清零了,已經寫反了^_^
- }
- /**************************************************************************
- * MAX7219_SetBrightness()
- *
- * 描述: 設置數碼管顯示亮度
- * Arguments : brightness (0-15)
- * Returns : none
- ***************************************************************************/
- void MAX7219_SetBrightness (Byte brightness)
- {
- brightness &= 0x0f;
- MAX7219_Write(REG_INTENSITY, brightness);
- }
- /**************************************************************************
- * MAX7219_DisplayTestStart()
- *
- * 描述: 進入 test 模式
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_DisplayTestStart (void)
- {
- MAX7219_Write(REG_DISPLAY_TEST, 1);
- }
- /**************************************************************************
- * MAX7219_DisplayTestStop()
- *
- * 描述: 退出 test 模式
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_DisplayTestStop (void)
- {
- MAX7219_Write(REG_DISPLAY_TEST, 0);
- }
- /**************************************************************************
- * MAX7219_ShutdownStart()
- *
- * 描述: 進入 shutdown 模式
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_ShutdownStart (void)
- {
- MAX7219_Write(REG_SHUTDOWN, 0);
- }
- /**************************************************************************
- * MAX7219_ShutdownStop()
- *
- * 描述: 退出 shutdown 模式
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_ShutdownStop (void)
- {
- MAX7219_Write(REG_SHUTDOWN, 1);
- }
- /**************************************************************************
- * MAX7219_Init()
- *
- * Description: MAX7219初始化模塊; 應該先于其他MAX7219函數而被調用
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void MAX7219_Init (void)
- {
- DATA=1;
- CLK=1;
- LOAD=1;
- MAX7219_Write(REG_SCAN_LIMIT,1);//這里設置的是掃描兩個數碼管
- MAX7219_Write(REG_DECODE, 0x00);
- MAX7219_SetBrightness(INTENSITY_MAX);//設置最大亮度顯示
- MAX7219_DisplayTestStart();
- MAX7219_DisplayTestStop();
- MAX7219_ShutdownStop();
- MAX7219_Clear();
- }
- /**************************************************************************
- * Delay_100us()
- *
- * 描述: 延時100us,主要用在消除開關抖動時
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void Delay10ms(void)
- {
- unsigned char i,j;
- for(i=20;i>0;i--)
- for(j=248;j>0;j--);
- }
- /**************************************************************************
- * GetHostStartKey()
- *
- * Description: 取得主持人開始按鍵的鍵值
- * Arguments : none
- * Returns : 1-->主持人按鍵; 0-->主持人未按鍵
- ***************************************************************************/
- Bool GetHostStartKey (void)
- {
- if (HOST_START ==1)
- return 0;
- else
- Delay10ms ();//如果發現主持人按鍵接通,要先延時100us,防止抖動
- if (HOST_START==1)
- return 0;
- else
- return 1;//延時時候還是接通,則判斷為該鍵確實按下
- }
- /**************************************************************************
- * GetHostCancelKey()
- *
- * Description: 取得主持人取消按鍵的鍵值
- * Arguments : none
- * Returns : 1-->主持人按鍵; 0-->主持人未按鍵
- ***************************************************************************/
- Bool GetHostCancelKey (void)
- {
- if (HOST_CANCEL ==1)
- return 0;
- else
- Delay10ms ();//如果發現主持人按鍵接通,要先延時100us,防止抖動
- if (HOST_CANCEL ==1)
- return 0;
- else
- return 1;//延時時候還是接通,則判斷為該鍵確實按下
- }
- /**************************************************************************
- * GetCounter
- *
- * Description: 取得預先設置的倒計時時間
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void GetCounter(void)
- {
- beginNum=1;//在所有開關都沒有撥動的時候倒計時為1秒,比設置為0秒要好
- intrCounter=20;//每一秒對應的中斷次數為20次
- if (SWITCH1_3==1)
- {
- beginNum+=3;
- }
- if (SWITCH2_2==1)
- {
- beginNum+=2;
- }
- if (SWITCH3_2==1)
- {
- beginNum+=2;
- }
- if (SWITCH4_1==1)
- {
- beginNum+=1;
- }//以上判斷語句為判斷撥碼開關狀態
- intrCounter=20*beginNum;//計算總掃描次數
- }
- /**************************************************************************
- * GetPressed
- *
- * Description: 從P2口連接搶答端的四位來判斷搶答情況
- * Arguments : Byte KeyState-->P2 state
- * Returns : 搶答端的號碼 ; 0-->沒人搶答
- ***************************************************************************/
- Byte GetPressed(Byte KeyState)
- {
- Byte key;//記錄搶答端的號碼
- KeyState&=0xf0;//取P1口的低四位
- switch (KeyState)
- {
- case 0xf0: key=0;break;//全高,無人搶答
- case 0xe0: key=1;break;//只有P1.1,key1搶答
- case 0xd0: key=2;break;//只有P1.2,key2搶答
- case 0xb0: key=3;break;//只有P1.3,key3搶答
- case 0x70: key=4;break;//只有P1.4,key4搶答
- }
- /*
- switch (KeyState)
- {
- case 0x00: key=0;break;//全高,無人搶答
- case 0x01: key=1;break;//只有P1.0,key1搶答
- case 0x02: key=2;break;//只有P1.1,key2搶答
- case 0x04: key=3;break;//只有P1.2,key3搶答
- case 0x08: key=4;break;//只有P1.3,key4搶答
- }
- */
- //上面是在用高電平來判斷搶答狀態時的程序,經證明不知道為何無效
- return key;
- }
- /**************************************************************************
- * GetPressedWireless
- *
- * Description: P2口的高四位于Pt2272接受模塊相連,該方法用來判斷無線搶答序號
- * Arguments : Byte KeyState-->P2 state
- * Returns : 搶答端的號碼 ; 0-->沒人搶答
- ***************************************************************************/
- Byte GetPressedWireless(Byte KeyState)
- {
- Byte key;//記錄搶答端的號碼
- KeyState&=0xf0;//取P2口的高四位
- /*
- switch (KeyState)
- {
- case 0x0f: key=0;break;//全高,無人搶答
- case 0x0e: key=1;break;//只有P1.1,key1搶答
- case 0x0d: key=2;break;//只有P1.2,key2搶答
- case 0x0b: key=3;break;//只有P1.3,key3搶答
- case 0x07: key=4;break;//只有P1.4,key4搶答
- }
- */
- switch (KeyState)
- {
- case 0x00: key=0;break;//全低,無人搶答
- case 0x10: key=1;break;//只有P1.0,key1搶答
- case 0x20: key=2;break;//只有P1.1,key2搶答
- case 0x40: key=3;break;//只有P1.2,key3搶答
- case 0x80: key=4;break;//只有P1.3,key4搶答
- }
- return key;
- }
- /**************************************************************************
- * IT0_Init
- *
- * Description: 初始化計時器T0的狀態
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void IT0_Init(void)
- {
- TMOD=0x21;//設置T0在方式1下工作,同時還要保證T1,也就是波特率所學的定時器的正常工作
- #ifdef CLOCK_FREQUENCY_12M//對使用哪種晶振進行條件編譯
- TH0=0x3C;//12M晶振時的裝入值
- TL0=0xAF;
- #else
- TH0=0x4C;//11.0529M晶振時裝入值
- TL0=0x00;
- #endif
- ET0=1;//使T0中斷可以溢出
- EA=1;//開啟總中斷
- TF0=0;//溢出位清零
- TR0=1;//開啟T0
- }
- /**************************************************************************
- * Timer0_Overflow() interrupt 1
- *
- * Description: 中斷溢出服務程序, 采用的是中斷方式1, 后面最好不加using選擇寄存器組以免與系統用在主程序的寄存器沖突
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void Timer0_Overflow() interrupt 1
- {
- static Byte times=20;//溢出次數,用20次中斷來判斷1秒
- //這里存在重大bug,到由于有相應而停止Timer0后,再次啟用時,這里的second沒有回歸原值
- if (needResetTimes==1)
- {
- times=20;
- needResetTimes=0;//已重設,不需要再次重新設置溢出次數
- }
- #ifdef CLOCK_FREQUENCY_12M//對使用哪種晶振進行條件編譯
- TH0=0x3C;//12M晶振時的裝入值
- TL0=0xAF;//這兩個寄存器存的是計數器的計數開始的值,計算發現這兩個值累加至溢出后正好是50ms
- #else
- TH0=0x4C;//11.0529M晶振時裝入值
- TL0=0x00;//同理,這兩個寄存器存的是計數器的計數開始的值,計算發現這兩個值累加至溢出后正好是50ms
- #endif
- times--;
- intrCounter--;
- /* 原來使用的方法
- if (times==0)//每隔一秒的操作
- {
- MAX7219_DisplayChar(DIG_2,code_table[--showNum]); //要避免用上面的會造成顯示"0"后面一秒鐘,才進入開始
- times=20;//重新賦值每秒計數器
- if (intrCounter==0)
- {
- TR0=0;//關閉T0計數器
- isStart=1;//計時結束,進入正常搶答
- //SPEAKER_start();//開始搶答的聲音
- }
- //待顯示"0"以后就開始搶答
- else
- {
- //SPEAKER_count();//倒計時聲音
- }
- }
- */
- if (times==0)//每隔一秒的操作
- {
- //if (showNum!=1) SPEAKER_count();//倒計時聲音
- //else SPEAKER_start();//開始搶答的聲音
- MAX7219_DisplayChar(DIG_2,code_table[--showNum]);//顯示數字
- sendNumber(_CHANGE_TIME_);//給上位機發送要顯示數字的命令
- times=20;//重新賦值每秒計數器
- }//待顯示"0"以后就開始搶答
- if (intrCounter==0)
- {
- TR0=0;//關閉T0計數器
- isStart=1;//計時結束,進入正常搶答
- }
- }
- /**************************************************************************
- * PressedHandle
- *
- * Description: 按鍵處理
- * Arguments : Byte keyPressed-->按下的按鍵
- * Returns : none
- ***************************************************************************/
- void PressedHandle(Byte keyPressed)
- {
- MAX7219_Clear();//LED clear
- MAX7219_DisplayChar(DIG_2,code_table[keyPressed]);//在右側數碼管顯示搶答選手號碼,此時沒有去判斷是否犯規
- //給上位機發搶答選手的號碼
- sendNumber(keyPressed);
- }
- /**************************************************************************
- * GetOrFoulHandle(Bool state)
- *
- * Description: 正常搶答或是犯規處理
- * Arguments : Bool state-->是GET和FOUL兩個宏的取之之一
- * Returns : none
- ***************************************************************************/
- void GetOrFoulHandle(Bool state)
- {
- if (!state)
- {
- MAX7219_DisplayChar(DIG_1,LED_FOUL);//如果是犯規的話左邊的LED要顯示"F",foul
- }
- }
- /**************************************************************************
- * CancelHandle()
- *
- * Description: 處理主持人取消倒計時
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void CancelHandle()
- {
- MAX7219_DisplayChar(DIG_1,LED_C);
- MAX7219_DisplayChar(DIG_2,LED_L);//主持人取消倒計時之后,兩個數碼管顯示"CL"-->cancel
- }
- /**************************************************************************
- * delayus()
- *
- * Description: 延時程序
- * Arguments : t-->us
- * Returns : time delayed
- ***************************************************************************/
- void delayus(unsigned char t )
- {
- unsigned char j;
- for(;t>0;t--)
- for(j=19;j>0;j--);
- }
- /**************************************************************************
- * SPEAKER_count/start/foul/get()
- *
- * Description: speaker發聲程序->計數/開始/犯規/搶答 四種聲音
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void SPEAKER_count(void)
- {
- unsigned char i;
- for (i=0;i<10;i++)
- {
- BEEP =1; //點亮
- delayus(20);
- BEEP =0; //熄滅
- delayus(20);
- }
- }
- void SPEAKER_start(void)
- {
- unsigned char i;
- for(i=0;i<200;i++)
- {
- BEEP =1; //點亮
- delayus(10);
- BEEP =0; //熄滅
- delayus(10);
- }
- }
- void SPEAKER_foul(void)
- {
- unsigned char i;
- for(i=0;i<250;i++)
- {
- BEEP =1; //點亮
- delayus(15);
- BEEP =0; //熄滅
- delayus(17);
- }
- }
- void SPEAKER_get(void)
- {
- unsigned char i;
- for(i=0;i<250;i++)
- {
- BEEP =1; //點亮
- delayus(10);
- BEEP =0; //熄滅
- delayus(10);
- }
- for(i=0;i<250;i++)
- {
- BEEP =1; //點亮
- delayus(20);
- BEEP =0; //熄滅
- delayus(20);
- }
- }
- /**************************************************************************
- * initialSerial()
- *
- * Description: 初始化串口
- * Arguments : none
- * Returns : none
- ***************************************************************************/
- void initialSerial()
- {
- EA=0;//關閉所有中斷
- TMOD=0x21;//設置T1定時器的工作模式:方式2;同時保證T0的工作模式正常.這兒太重要了
- TH1=0xFA;
- TL1=0xFA;
- PCON=0x80;//設置SMOD=1
- SCON=0x50;//選擇工作方式1,即為UART
- TR1=1;//設置好定時器并打開定時器,定好波特率9600bit/s
- }
- /**************************************************************************
- * sendNumber(int number)
- *
- * Description: 通過串口發送一位數字
- * Arguments : number->要發送的數字
- * Returns : none
- ***************************************************************************/
- void sendNumber(int number)
- {
- TI=0;
- SBUF=number+48;
- while(!TI);
- TI=0;
- }
- /**************************************************************************
- * sendString(unsigned char *string)
- *
- * Description: 通過串口發送字符串
- * Arguments : 要發送的字符串的頭指針
- * Returns : none
- ***************************************************************************/
- void sendString(unsigned char *string)
- {
- do
- {
- SBUF=*string;
- while(!TI);
- TI=0;
- string++;
- }while(*(string-1)!='\0');
- /**************************************************************************
- * 主程序
- ***************************************************************************/
- void main()
- {
- //P1=0xff;
- Byte keyPressed,i;//選手按鍵號碼,沒有的話為0
- Bool hostPressed;//用來記錄主持人按鍵取消,0為沒有動作,1為取消
- Byte buf[10];//設置發送緩沖區
- number_temp=P1&0xf0;//P1口上次的狀態,在調整倒計時時間的時候用到的
- #ifdef USE_SOUND
- LS138_E1=1; //譯碼器初始化
- #endif
- needResetTimes=0;//不需要重新設置溢出次數
- MAX7219_Init();//數碼管初始化
- initialSerial();//初始化串口發送
- GetCounter();//獲取開始時候設置的倒計時時間
- MAX7219_DisplayChar(DIG_1,code_table[beginNum]);
- //顯示開始時設置的倒計時時間,在左位設置
- MAX7219_DisplayChar(DIG_2,READY);//調時間的時候右位的顯示
- while(GetHostStartKey()==0)//當主持人沒有按鍵的時候進入循環
- {
- if (number_temp!=(P1&0xf0))
- //若調整了倒計時時間,則P1口狀態變了,就要重新設置和顯示
- {
- GetCounter();//獲取調整以后的倒計時時間
- MAX7219_DisplayChar(DIG_1,code_table[beginNum]);
- //顯示調整以后的倒計時時間
- number_temp=P1&0xf0;//記錄下來現在P1口的狀態,以備后面的比較
- }
- } //當主持人按鍵以后就結束調整進入搶答倒計時
- sendNumber(beginNum);
- MAX7219_DisplayChar(DIG_1,READY);
- while(GetHostCancelKey()==0);
- sendNumber(_STRING_READY_);//發送調節完畢準備搶答的命令;
- //調整好倒計時時間后,按下start顯示"--",再按下cancel則顯示倒計時時間,此時可以開始倒計時了.
- MAX7219_DisplayChar(DIG_1,READY);//清空右邊一位數碼管
- MAX7219_DisplayChar(DIG_2,code_table[beginNum]);
- for (i=100;i--;i>0)
- Delay10ms();//防止后面出現連讀的情況..
- counterBack=intrCounter; //備份要中斷的總次數
- while(1)//這里要用自己加的循環來把程序束縛在這里運行
- {
- showNum=beginNum;//設置要顯示的時間,當然時從倒計時時間開始
- intrCounter=counterBack;//設置總中斷的次數
- TR0=0;//禁用計時器0
- isPressed=0;//記錄是否有人按鍵
- isStart=0;//沒有開始搶答
- while(GetHostStartKey()==0);
- //給上位機發送開始倒計時的指令
- sendNumber(_STRING_START_);
- needResetTimes=1;//Timer0已經是第二輪開始,需要重新設置溢出次數
- IT0_Init();//初始化計時器0, 啟用.
- MAX7219_DisplayChar(DIG_1,CLEAR);//清空左邊一位數碼管
- while(!isPressed)//如果沒有記錄到有人按鍵就進入
- {
- keyPressed=GetPressed(P2);
- //查詢一下P2口的狀態,即按鍵情況,P2口的后四位作為搶答端輸入,有線時候使用
- //keyPressed=GetPressedWireless(P2);//查詢一下P2口的狀態,即按鍵情況,無線使用
- hostPressed=GetHostCancelKey();
- if (!keyPressed&&!hostPressed)//如果沒有人按鍵,就進入下次循環
- continue;
- else
- {
- TR0=0;//關閉定時器
- isPressed=1;//記錄到有人按鍵,提供條件跳出循環
- }
- }
- if (keyPressed!=0)
- {
- if (isStart)//如果已經開始搶答
- {
- PressedHandle(keyPressed);//處理按鍵,即顯示搶答選手號碼
- GetOrFoulHandle(GET);//處理搶答
- #ifdef USE_SOUND//對是否使用揚聲器進行條件編譯
- LS138_E1=0; //譯碼器準備工作
- switch (keyPressed)
- {
- case 1: LS138_A=0;LS138_B=0;LS138_C=0;break; //1號成功燈亮
- case 2: LS138_A=0;LS138_B=1;LS138_C=0;break; //2號成功燈亮
- case 3: LS138_A=1;LS138_B=0;LS138_C=0;break; //3號成功燈亮
- case 4: LS138_A=1;LS138_B=1;LS138_C=0;break; //4號成功燈亮
- default : break;
- }
- #endif
- }
- else//否則,沒有開始搶答
- {
- PressedHandle(keyPressed);//處理按鍵,即顯示搶答選手號碼
- GetOrFoulHandle(FOUL);//處理犯規,必須要放在后面,因為顯示數字的里面有一個clear
- #ifdef USE_SOUND//對是否使用揚聲器進行條件編譯
- LS138_E1=0; //譯碼器準備工作
- switch (keyPressed)
- {
- case 1: LS138_A=0;LS138_B=0;LS138_C=1;break; //1號犯規燈亮
- case 2: LS138_A=0;LS138_B=1;LS138_C=1;break; //2號犯規燈亮
- case 3: LS138_A=1;LS138_B=0;LS138_C=1;break; //3號犯規燈亮
- case 4: LS138_A=1;LS138_B=1;LS138_C=1;break; //4號犯規燈亮
- default : break;
- }
- #endif
- }
- }
- if (hostPressed==1)
- {
- CancelHandle();
- //向上位機發送主持人取消的指令
- sendNumber(_STRING_CANCEL_);
- for (i=100;i--;i>0)
- Delay10ms();//防止后面出現連讀的情況..
- }
- while(GetHostCancelKey()==0);//如果主持人沒有按鍵再次開始,則停在次死循環處
- #ifdef USE_SOUND//對是否使用揚聲器進行條件編譯
- LS138_E1=1; //關閉譯碼器
- #endif
- MAX7219_DisplayChar(DIG_1,READY);//清空右邊一位數碼管
- MAX7219_DisplayChar(DIG_2,code_table[beginNum]);//左位顯示設置的倒計時時間
- //給上位機發送重新開始倒計時的指令
- sendNumber(_STRING_READY_);
- }
復制代碼
|