#include <reg51.h> #define uchar unsigned char uchar code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF}/*1~9、空格和-的字型碼*/ ,display[8]={1,2,4,8,16,32,64,128};//動態顯示數碼管 uchar score[2]={0,0},time[2]={12,0},byte[8]={0},j=0,h=0;//score數組記錄A、B兩隊份數time //數組記錄倒計時分、秒時間,byte //數組記錄八個數碼管的顯示字,j記 //錄按鍵s0按下的次數,h記錄時間 //中斷1的次數; bit start=0; //start為12分倒計時是否開始時的標志位; sbit alrm=P3^0; //alrm為響鈴脈沖輸出端 unsigned int t=0; //響鈴脈沖個數 void delay1(uchar t) //延時程序,最短5ms { unsigned char m,n,k; for(m=t;m>0;m--) for(n=10;n>0;n--) for(k=250;k>0;k--); } void jishi() //倒計時程序 { if(start==1) //如果倒計時標志有效,則開始倒計時 { if(time[1]==0) { if(time[0]==0) //如果分秒位都為0時,開啟時間中斷0,輸出響鈴脈沖 { start=0; ET0=1; TR0=1; } else //如果秒位為0,分位不為0,則秒位跳為59,分位減1 { time[0]--; time[1]=59; } } else time[1]--; //如果分秒位都不為0,則秒位減1 } } void TIMER0() interrupt 1 using 0 //時間中斷0;用于產生響鈴脈沖 { TH0=0xfc; //1ms的計數初始狀態 TL0=0x18; t++; alrm=!alrm; if(t==5000) //如果輸出5000個脈沖,則停止響鈴 { t=0; ET0=0; TR0=0; } } void TIMER1() interrupt 3 using 1 { TH1=0x63; TL1=0xc0; //50ms初始值; if((h++)==20) { // 一秒是否到,如果到,則進行倒計時程序 h=0; jishi(); } } void INT_0() interrupt 0 using 2 //外部中斷0,記錄按鍵按下次數 { ET0=0; delay1(1); //延時消抖 j++; if(j==5) //如果按鍵s0按下五次,則歸零 j=0; ET0=1; } void jiaohuan() //分數交換,AB兩隊換場程序 { uchar temp; temp=score[0]; score[0]=score[1]; score[1]=temp; } void INT_1() interrupt 2 using 3 //外部中斷1 { ET1=0; //延時消抖 delay1(1); if(j==1) //如果s0按下的次數為1次,則score[1]加1 { score[1]++; if(score[1]==100) //分數到100后歸零 score[1]=0; } else if(j==2) { score[0]++; //如果s0按下的次數為2次,則score[0]加1 if(score[0]==100) //分數到100后歸零 score[0]=0; } else if(j==3) //如果s0按下的次數為3次,則兩隊分數交換 jiaohuan(); else if(j==4) //如果s0按下的次數為4次 ,則打開倒計時或關閉倒計時 start=!start; else; ET1=1; } void by(void) { byte[5]=11; //第五個數碼管一直顯示為"-" if(j==4) //如果s0按下的次數為4,則顯示倒計時 { byte[3]=time[0]/10; byte[4]=time[0]%10; byte[6]=time[1]/10; byte[7]=time[1]%10; } else //否則顯示比分 { byte[3]=score[0]/10; byte[4]=score[0]%10; byte[6]=score[1]/10; byte[7]=score[1]%10; } } void blank() { if(j==1) //如果s0按下1次;第7、8個數碼管閃爍跳動 { byte[7]=10,byte[6]=10; } else if(j==2) //如果s0按下2次;第4、5個數碼管閃爍跳動 { byte[3]=10,byte[4]=10; } else if(j==3) //如果s0按下3次;第4、5、7、8個數碼管閃爍跳動 { byte[7]=10,byte[6]=10; byte[4]=10,byte[3]=10; } else; } void bitshow() { if(h<=10) //前半秒正常顯示,后半秒根據s0按下的次數相應的數碼管閃爍 by(); else blank(); } void dis() { uchar i; while(1) // 死循環顯示 { bitshow(); //求每一位的顯示 for(i=3;i<=7;i++) { P0=~display[i]; //P0口控制掃描顯示的數碼管 P1=tab[byte[i]]; //P1口輸出字型碼 delay1(1); //延時5ms,增加顯示亮度 } } } void main(void) { TMOD=0x11; EA=1; EX0=1; EX1=1; ET1=1; IT1=1; IT0=1; TR1=1; //開啟時間中斷1,兩個外部中斷 IP=5; //中斷優先級控制 dis(); //顯示子程序 } |