該設計的總的原理電路圖如圖1.2所示。當按下不同的按鍵時,顯示器上顯示相應的數據,每一節12分鐘結束喇叭響。可實現所以既定功能。
單片機源程序如下:
- #include<reg51.h>//51單片機頭文件
- typedef unsigned char uchar;
- typedef unsigned int uint;
- sbit K1=P3^2;//比賽倒計時開始/暫停
- sbit K2=P3^3;//24s倒計時重新開始
- sbit K3=P1^3;//乙隊+1按鍵
- sbit K4=P1^2;//乙隊+2按鍵
- sbit K5=P1^1;//甲隊+1按鍵
- sbit K6=P1^0;//甲隊+2按鍵
- sbit K7=P1^4;//甲隊+3按鍵
- sbit K8=P1^5;//乙隊+3按鍵
- sbit K9=P1^6;//預留按鍵
- sbit beep=P2^0;//蜂鳴器接口
- sbit RS=P2^7;
- sbit E=P2^5;
- char miao,fen,num,time,aa;
- uchar bb,cc;
- uchar code table1[]={"H.T 000:000 R.T "};
- uchar code table2[]={"12:00 SEC-1 24"};
- //延時子函數
- void delay(uint z)
- {
- uint x;
- uchar y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- //LCD1602液晶寫指令子函數
- void write_com(uchar com)
- {
- RS=0;
- P0=com;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- //LCD1602液晶寫數據子函數
- void write_date(uchar date)
- {
- RS=1;
- P0=date;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- //LCD1602液晶初始化子函數
- void LCD1602_init()
- {
- uchar i;
- bb=0; //H.T分數初始化
- cc=0; //R.T分數初始化
- time=0;
- TMOD=0x10; //定時器1初始化
- TL1=0x00;
- TH1=0x4c;
- EA=1; //開總中斷
- ET1=1; //開定時器1
- TR1=0; //定時器1不工作
- EX0=1; //開中斷0
- EX1=1; //開中斷1
- IT0=1; //中斷0為邊沿觸發
- IT1=1; //中斷1為邊沿觸發
- E=0;
- beep=0;
- miao=0;
- fen=12;
- num=1;
- aa=24;
- write_com(0x38); //LCD設置初始化
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- write_com(0x80); //LCD顯示初始化
- for(i=0;i<16;i++)
- {
- write_date(table1[i]);
- }
- write_com(0x80+0x40);
- for(i=0;i<16;i++)
- {
- write_date(table2[i]);
- }
- }
- //分數更新子函數
- void point_lcd(uchar add,uchar dat)
- {
- write_com(0x80+add);
- write_date(0x30+dat/100);
- write_date(0x30+(dat%100)/10);
- write_date(0x30+dat%10);
- write_com(0x80+add);
- }
- //按鍵掃描子函數
- void keyscan()
- {
- if(K3==0) //K3按下H.T分數加一
- {
- while(K3==0);
- bb++;
- point_lcd(0x04,bb); //分數顯示更新
- if(K3==0) //松手檢測
- {
- while(K3==0);
- delay(20);
- }
- }
- else if(K4==0) //S4按下H.T分數加二
- {
- while(K4==0);
- bb=bb+2;
- point_lcd(0x04,bb);
- if(K4==0)
- {
- while(K4==0);
- delay(20);
- }
- }
- else if(K7==0) //S4按下H.T分數加二
- {
- while(K7==0);
- bb=bb+3;
- point_lcd(0x04,bb);
- if(K7==0)
- {
- while(K7==0);
- delay(20);
- }
- }
- else if(K5==0) //S5按下R.T分數加一
- {
- while(K5==0);
- cc++;
- point_lcd(0x08,cc);
- if(K5==0)
- {
- while(K5==0);
- delay(20);
- }
- }
- else if(K6==0) //S6按下R.T分數加2
- {
- while(K6==0);
- cc=cc+2;
- point_lcd(0x08,cc);
- if(K6==0)
- {
- while(K6==0);
- delay(20);
- }
- }
- else if(K8==0) //S6按下R.T分數加2
- {
- while(K8==0);
- cc=cc+3;
- point_lcd(0x08,cc);
- if(K8==0)
- {
- while(K8==0);
- delay(20);
- }
- }
- }
- //比賽倒計時/24s倒計時
- void counter_down()
- {
- uchar i;
- if(time>=20) //每1s倒計時做減一操作
- {
- miao--;
- aa--;
- write_com(0x80+0x4e); //24s倒計時顯示
- write_date(0x30+aa/10);
- write_date(0x30+aa%10);
- write_com(0x80+0x4e);
- if(aa==0) //24s結束發出3s連續報警
- {
- beep=1;
- delay(3000);
- beep=0;
- aa=24;
- }
- if((miao==0)&&(fen==0)) //檢測一節比賽是否結束
- {
- TR1=0; //定時器1暫停
- write_com(0x80+0x44);
- write_date(0x30);
- num++;
- aa=24; //24s計時復位
- write_com(0x80+0x4e); //24s倒計時顯示
- write_date(0x30+aa/10);
- write_date(0x30+aa%10);
- write_com(0x80+0x4e);
- if(num<5) //每節結束蜂鳴器發出8s的間斷報警
- {
- for(i=80;i>0;i--)
- {
- beep=1;
- delay(500);
- beep=0;
- delay(500);
- }
- }
- if(num==5) //終場結束,蜂鳴器發出10s的連續警報聲
- {
- beep=1;
- delay(10000);
- num=0;
- }
- beep=0; //蜂鳴器關閉
- write_com(0x80+0x4b); //更新"SEC-?"
- write_date(0x30+num);
- write_com(0x80+0x4b);
- miao=0; //倒計時復位
- fen=12;
- }
- if(miao==-1)
- {
- miao=59;
- fen--;
- }
- write_com(0x80+0x40); //更新倒計時顯示
- write_date(0x30+fen/10);
- write_date(0x30+fen%10);
- write_com(0x80+0x43);
- write_date(0x30+miao/10);
- write_date(0x30+miao%10);
- write_com(0x80+0x43);
- time=0;
- }
- }
- //主函數
- void main()
- {
- LCD1602_init();
- while(1)
- {
- keyscan(); //分數按鍵檢測
- }
- }
- //外部0中斷子函數
- void wb0() interrupt 0 //比賽時間開始/暫停
- {
- TR1=~TR1; //定時器1工作/暫停
- if(TR1==1) //當倒計時工作時,S1按下定時器立即停止工作
- {
- PT1=0;
- }
- else //倒計時不工作時,S1按下倒計時立即工作
- {
- PT1=1;
- }
- if(K1==0) //松手檢測
- {
- while(K1==0);
- counter_down();
- // delay(20);
- }
- }
- //外部1中斷子函數
- void wb1() interrupt 2 //24s倒計時重新開始
- {
- aa=24;
- write_com(0x80+0x4e); //24s倒計時顯示
- write_date(0x30+aa/10);
- write_date(0x30+aa%10);
- write_com(0x80+0x4e);
- if(K2==0) //松手檢測
- {
- while(K2==0)
- {
- counter_down();
- }
- delay(20);
- }
- }
- //定時器1中斷子函數
- void t1() interrupt 3 //定時器1中斷20次為1s
- {
- time++;
- TL1=0x00;
- TH1=0x4c;
- counter_down(); //倒計時
- }
復制代碼
所有資料51hei提供下載:
籃球計分器.zip
(554.66 KB, 下載次數: 263)
2020-2-29 14:41 上傳
點擊文件名下載附件
|