系統能實現的功能:
本系統搶答器能實現如下功能:
①、由主持人控制答題開始,通過一個總的控制按鈕,并且蜂鳴器 發聲提示。再次按下時可以對單片機進行復位。
②、同時主持人按鈕控制著30S的搶答倒計時,當時間到仍沒有人搶答時,蜂鳴器發聲報警,同時屏幕顯示無人搶答,等待主持人按鍵復位,進行下一輪搶答 ③、當有一個搶答按鈕被按下后,單片機進行鎖存,屏蔽其他選手號,此時蜂鳴器報警提示,并進入答題倒計時30S,若超時,則蜂鳴器報警,屏幕顯示答題超時,此時等待主持人復位。
六、主要程序
/*======================================================= 主函數
=======================================================*/ void main(void) {
system_init();//系統初始化 // IP = 0x20; while(1) {
seg_change();//轉換顯示的內容 key_handle();//鍵盤處理函數 switch(SPK_Flag) {
case SPK_NO: break;
case SPK_MUSIC: SpkMusic(); break; //播放音樂1 case SPK_ALARM: SpkAlarm(); break; } } }
/*======================================================= 系統初始化函數
=======================================================*/ void system_init(void) {
//定時器0 初始化 定時時間2ms TMOD = 0x01;
TH0 = 0x3c; //50微妙 TL0 = 0xb0;
EA = 1;
ET0 = 1; TR0 = 1;
SEG_RAM[0]=SEG_no; //這位不顯示 有人搶答時,s顯示搶答選手號 或則 無人搶答時 顯示 F
SEG_RAM[1]=SEG_no; SEG_RAM[2]=SEG_no; SEG_RAM[3]=SEG_no;
SEG_RAM[4]=SEG_no;//初始化記分器分數 SEG_RAM[5]=SEG_no; SEG_RAM[6]=SEG_no;
SEG_RAM[7]=SEG_0;//始終顯示0 }
/*======================================================= 鍵盤掃描函數
=======================================================*/ unsigned char key_scan(void) {
unsigned char keyvalue=NO_KEY; if(KEY_PORT != 0xff) {
delay();delay();delay();delay(); delay();delay();delay();delay(); delay();delay();delay();delay(); delay();delay();delay();delay(); switch (KEY_PORT) {
case 0xff: break;//無鍵按下 case 0xfe: keyvalue = PLAYER_1; break; case 0xfd: keyvalue = PLAYER_5; break; case 0xfb: keyvalue = PLAYER_2; break; case 0xf7: keyvalue = RST_KEY; break; case 0xef: keyvalue = PLAYER_3; break; case 0xdf: keyvalue = ADD_KEY; break; case 0xbf: keyvalue = PLAYER_4; break; case 0x7f: keyvalue = UP_KEY; break; }
while(KEY_PORT != 0xff);//松手檢測 }
return (keyvalue);
}
/*======================================================= 鍵盤處理函數
=======================================================*/ void key_handle(void) {
unsigned char keytemp; keytemp = key_scan(); switch(keytemp) {
case NO_KEY: break;
case PLAYER_1: case PLAYER_2: case PLAYER_3: case PLAYER_4: case PLAYER_5:
if(QD_Flag==QD_GO) {
QD_Flag = QD_OK; //切換到搶答成功狀態 SEG_RAM[0] = table_duan[keytemp+1]; //第一個數碼管顯示搶答選手號
QD_show_num = keytemp;
SPK_Flag = SPK_MUSIC; //蜂鳴器 播放音樂 }
break; case RST_KEY:
QD_Flag = QD_GO; SPK_Flag = SPK_NO; QD_timectr=100;
SEG_RAM[0] = SEG_no; break; case ADD_KEY:
JFQ_ctr[QD_show_num]++; //對應選手 記分器 加分 break; case UP_KEY:
QD_show_num++;
if(QD_show_num==5)QD_show_num=0;
SEG_RAM[0] = table_duan[QD_show_num+1];
break; } }
/*======================================================= 定時器0中斷服務程序
=======================================================*/ void Timer0_ISR(void) interrupt 1 {
static unsigned char t0_2ms_counter = 0,tt; //50毫秒計數器 ET2=0;
TL0 = 0x30; //2ms TH0 = 0xf8;
t0_2ms_counter++;
seg_display(); //2毫秒 掃描數碼管 if(t0_2ms_counter==250) //500ms / 2ms = 250 { //0.5s到 if(QD_timectr==0)
{ //搶答時間到,無人搶答,切換到搶答失敗狀態 QD_Flag = QD_NO;
tt++;
if(tt==1)SPK_Flag = SPK_ALARM; //蜂鳴器 播放報警音 else SPK_Flag = SPK_NO; }
if(QD_Flag==QD_GO) QD_timectr-=5; //在搶答倒計時期間 倒計時減0.5
}
ET2=1; }
/*======================================================= 數碼管顯示函數
=======================================================*/ void seg_display(void) {
static unsigned char i=0; LED_WEI = table_wei[i]; LED_DUAN = SEG_RAM[i]; i++;
if(i》7) i=0; }
/*======================================================= 數碼管顯示轉換函數
=======================================================*/ void seg_change(void) {
if (QD_timectr《100) //取值為0~100
SEG_RAM[1]= SEG_no; //最高位為0則不顯示 else
SEG_RAM[1]= SEG_1; //最高位顯示1 SEG_RAM[2] = table_duandot[QD_timectr%100/10]; SEG_RAM[3] = table_duan[QD_timectr%10];
if(QD_Flag==2) SEG_RAM[0] = SEG_F; //顯示‘F’ 無人搶答 if(JFQ_ctr[QD_show_num]》=100) {
SEG_RAM[4]=table_duan[JFQ_ctr[QD_show_num]/100];
SEG_RAM[5]=table_duan[JFQ_ctr[QD_show_num]%100/10]; SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; }
else if (JFQ_ctr[QD_show_num]《100 && JFQ_ctr[QD_show_num]》=10) {
SEG_RAM[4]=SEG_no;//不顯示0
SEG_RAM[5]=table_duan[JFQ_ctr[QD_show_num]%100/10]; SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; }
else if (JFQ_ctr[QD_show_num]《10 && JFQ_ctr[QD_show_num]》0) {
SEG_RAM[4]=SEG_no;//不顯示0 SEG_RAM[5]=SEG_no;//不顯示0
SEG_RAM[6]=table_duan[JFQ_ctr[QD_show_num]%10]; } else {
SEG_RAM[4]=SEG_no;//不顯示0 SEG_RAM[5]=SEG_no;//不顯示0 SEG_RAM[6]=SEG_no;//不顯示0 } }
/*======================================================= 延時函數(延時1毫秒)
=======================================================*/
void delay(void) //延時1MS {
unsigned char a,b; for(b=102;b》0;b--) for(a=3;a》0;a--); }
/*======================================================== 播放音樂 和 報警聲音
=======================================================*/ unsigned int g_ucSoundLongCNT; //
/************************************************* * 函數名稱:void T2Init(void) * 創建日期:2005.6.17
* 功能描述:定時器T2初始化 * 入口參數:uT2Reg:定時器初值 * 返回值: 無 * 修改日志:
*************************************************/ void T2Init(unsigned int uT2Reg) {
CP_RL2=0; //16位自動重載
T2MOD=0x00; //計數增加,外部捕獲禁止 RCLK=0; TCLK=0;
TL2=RCAP2L=uT2Reg&0x00ff; TH2=RCAP2H=uT2Reg》》8;
TR2=1; // 啟動定時器 ET2=1; //t2開中斷 EA=1; }
/************************************************* * 函數名稱:void MusicPlay(uchar ucSL[],uint uST[]) * 創建日期:2005.7.12
* 功能描述:播放某首音樂的函數
* 入口參數:ucSL[]:音節長度的數組;uST[]:音樂頻率的數組 * 返回值: 無 * 修改日志:
*************************************************/
void MusicPlay(unsigned char ucSL[],unsigned int uST[])
{
unsigned char i=0; //float fTmp=“0”;
while((ucSL[i]!=0)||(uST[i]!=0)) {
//fTmp=(float)11059/(float)12000;
T2Init(0xffff-uST[i]*((float)11059/(float)12000)*4); //11。0592M的晶體 //我添加了*5
g_ucSoundLongCNT=((3*ucSL[i]*75000L)/8)/uST[i]; //*1000我改為 75000
while(g_ucSoundLongCNT!=0); //等待計數器為0 TR2=0; //暫時關閉定時器 i++; }
BUZZER = 1; }
/************************************************* * 函數名稱:void T2Init(void) * 創建日期:2005.7.11
* 功能描述:用于音樂的音調半周期定時 * 入口參數:無 * 返回值: 無 * 修改日志:
*************************************************/ void T2ISR(void) interrupt 5 using 1 {
TF2=0; //手動清除溢出標志 if(g_ucSoundLongCNT!=0) {
g_ucSoundLongCNT--; }
BUZZER=~BUZZER; }
評論