基於51微控制器控制的籃球比賽計時、計分系統設計與模擬(含設計圖和C語言程式原始碼)
1. 設計任務:
本次設計用由AT89C51程式設計控制LED七段數碼管作顯示的球賽計時計分系統。系統應具有賽程定時設定,賽程時間暫停,及時重新整理甲、乙雙方的成績以及賽後成績暫存等功能。
內容包括:顯示、鍵盤、時鐘等內容
2. 設計說明
2.1 需求分析
2.1.1 計分系統:
(1)分為“A隊”和“B隊”的“3分”,“2分”,“1分”各六個按鍵輸入部分,以及兩隊比分的LED顯示部分。在每次增加分數的同時,“24秒”計時恢復為初始值,“12分鐘”計時暫停,等待比賽的繼續進行
2.1.2 計時系統:
(1)比賽開始/繼續:當“比賽開始/繼續”鍵按下後,“24s”和“12分鐘”計時器開始倒計時;
(2)手動24s復位:當“24s復位” 鍵按下後,“24s”倒計時恢復初始值,“12分鐘”倒計時暫停,等待比賽的繼續;
(3)比賽暫停:“比賽暫停”鍵按下後,“24s”倒計時和“12分鐘”倒計時均暫停,等待比賽的繼續進行;
(4)自動增加比賽節數:當“12分鐘”倒計時完成後,判斷當前節數是否為最後一節,若不是,則節數自動增加,並“12分鐘”和“24s”均恢復預設值,等待下一節比賽的進行。
2.2 原理分析
採用微控制器AT89C51作為本設計的核心元件。利用7段共陰LED作為顯示器件。在此設計中共接入了6個7段共陰LED顯示器,其中2個4位LED顯示器用於記錄AB隊的分數,每隊1個4位LED顯示器顯示範圍可達到0~999分,足夠滿足賽程需要;2個兩位LED顯示器用來記錄賽程時間,其中1個用於顯示分鐘,1個用於顯示秒鐘;使用1個2位LED顯示器用於顯示“24s”倒計時,賽程計時均採用倒計時方式。即比賽前將時間設定好,即12分鐘,比賽開始時啟動計時,直至計時到零為止。本設計中設立了10個按鍵,其中6個用於設定兩隊的比分,1個用於比賽開始/比賽繼續,1個用於暫停,1個用於手動增加比賽節數,一個用於恢復“24s”倒計時等功能。
2.3 總體設計
系統主要包括微控制器、LED顯示電路、按鍵控制電路、時鐘電路及復位電路等組成
2.4 軟硬體設計
2.4.1 硬體設計
設計思路:
(1)按鍵模組設計 :
按鍵接至P1口和P3口,按鍵按下時輸入是低電平。鍵的設定如下:“A1”,“A2”,“A3”鍵是A隊加1分、加2分,加3分鍵盤,B隊同理。“比賽開始/比賽繼續”是啟動鍵,“比賽暫停”是暫停鍵。此外,還有兩個按鍵, “24s”復位鍵,“增加比賽節數”鍵。
(2) LED顯示模組設計 :
顯示分為計時和計分顯示兩個部分,均採用共陰極LED數碼管動態掃描顯示,由2個四位一體和4個兩位一體的共陰極數碼管構成。數碼管的7個段控端輸出經過74HC573驅動器進行電流放大驅動接至P0口。採用動態掃描方式,在足夠短的週期內,使各位數碼管逐個輪流受控顯示。
設計截圖:
2.4.2 軟體設計
軟體設計採用C語言模組設計方法,程式由主程式、T0中斷程式、顯示程式、外部中斷0程式、按鍵程式、初始函式、計時函式、延時函式組成。
C語言程式程式碼:
#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit A8=P2^0;
sbit A9=P2^1;
sbit A10=P2^2;
sbit A11=P2^3;
sfr P00=0x80;
uchar code wei_1[]={0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};
uchar code table[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00,0X40};
uchar minute=12; //分
uchar second=0; //秒
uchar key_status=0; //按鍵狀態值
uchar scoreA=0; //A隊得分
uchar scoreB=0; //B隊得分
uchar count1=20; //記錄定時器時間
uchar match=1; //比賽節數
uchar rule_time=24; //記錄24秒規則
uchar rule_flag=0; //記錄24秒規則是否啟用
/*
初始化IO口
*/
void IO_init(){
A8=0;
A9=0;
}
/*
初始化時間
*/
void time_init(){
TMOD = 0x01;
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
EA = 1;
ET0 = 1;
}
/*
延時函式
*/
void delay_ms(uint z){
uint i;
uchar j;
for(i=0;i<z;i++){
for(j=0;j<100;j++);
}
}
/*
計時函式
*/
void T0_Time() interrupt 1 using 1{
if (count1-- == 0)
{
second--;
rule_time--;
count1 = 20;
}
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
}
/*
時間顯示函式
*/
void time_display(uchar w2,uchar d2){
uchar shi1,ge1;
shi1=d2/10;
ge1=d2%10;
P00=wei_1[w2];
A10=1;
A10=0;
P00=table[shi1];;
A8=1;
A8=0;
delay_ms(5);
P00=0;
A10=1;
A10=0;
A8=1;
A8=0;
P00=wei_1[w2+1];
A10=1;
A10=0;
P00=table[ge1];
A8=1;
A8=0;
delay_ms(5);
P00=0;
A10=1;
A10=0;
A8=1;
A8=0;
}
/*
分數顯示函式
*/
void score_dispaly(uchar w2,uchar d2){
uchar qian2,shi2,ge2;
qian2=d2/100;
shi2=d2%100/10;
ge2=d2%100%10;
P00=wei_1[w2];
A9=1;
A9=0;
P00=table[qian2];;
A8=1;
A8=0;
delay_ms(10);
P00=0;
A9=1;
A9=0;
A8=1;
A8=0;
P00=wei_1[w2+1];
A9=1;
A9=0;
P00=table[shi2];
A8=1;
A8=0;
delay_ms(10);
P00=0;
A9=1;
A9=0;
A8=1;
A8=0;
P00=wei_1[w2+2];
A9=1;
A9=0;
P00=table[ge2];
A8=1;
A8=0;
delay_ms(10);
P00=0;
A9=1;
A9=0;
A8=1;
A8=0;
}
/*
鍵盤輸入函式
*/
void key(){
static uchar key_new = 0, key_l,temp;
key_status = 0;
P1 = 0x0f;
if((P1 & 0x0f) != 0x0f)
{
delay_ms(1);
if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
{
key_new = 0;
/*
矩陣鍵盤掃描
*/
key_l = (P1 | 0xf0);
P1 = key_l;
switch(P1)
{
/*
開始計時/比賽繼續
*/
case 0x7e:
TR0=1;
rule_flag=1;
time_display(6,rule_time);
break;
/*
暫停比賽
*/
case 0x7d:
TR0=0;
break;
/*
加分,同時24秒清零和總計時器停止計時
*/
case 0xee:
TR0=0;
scoreA +=3;
rule_time=24;
rule_flag=0;
break;
case 0xed:
TR0=0;
scoreA +=2;
rule_time=24;
rule_flag=0;
break;
case 0xeb:
TR0=0;
scoreA +=1;
rule_time=24;
rule_flag=0;
break;
case 0xde:
TR0=0;
scoreB +=3;
rule_time=24;
rule_flag=0;
break;
case 0xdd:
TR0=0;
scoreB +=2;
rule_time=24;
rule_flag=0;
break;
case 0xdb:
TR0=0;
scoreB +=1;
rule_time=24;
rule_flag=0;
break;
/*
增加比賽節數,同時24秒復位和總計時器復位
*/
case 0xbd:
match++;
minute=12;
second=0;
TR0=0;
rule_time=24;
rule_flag=0;
break;
/*
手動24秒復位
*/
case 0xbe:
if(TR0==1){
rule_time=0;
rule_flag=0;
}else{
rule_flag=0;
}
break;
}
}
}
else
{
key_new = 1;
}
}
void main()
{
IO_init();
time_init();
while(1){
key();
if(second==0){
/*
判斷某節比賽是否結束
*/
if(minute==0){
/*
判斷是否為最後一節比賽
*/
if(match<4){
/*
計時系統恢復為預設值,比賽節數加一
*/
second=60;
minute=11;
match++;
rule_time=24;
rule_flag=0;
}
TR0=0;
}
/*
比賽分鐘數減一
*/
else {
second=60;
minute--;
}
}
/*
24秒結束,計時器暫停和24秒復位
*/
if(rule_time<=0){
TR0=0;
rule_time=24;
}
/*
顯示
*/
time_display(0,minute);
time_display(2,second);
time_display(4,match);
time_display(6,rule_time);
score_dispaly(1,scoreA);
score_dispaly(5,scoreB);
}
}
2.5 方案論證及可行性分析
本設計以微控制器AT89C51為核心的控制電路實現了計時計分、計時的功能,設計中,使用大尺寸數碼管的製造構思巧妙和軟體設計,降低了整個系統的成本,實現了多用途的目的。通過模擬和實物實驗驗證了該系統的正確性和實用性。系統電路製造簡單,顯示清晰,成本低廉。
2.6 測試結果與分析
設計採用C語言程式設計,在Keil C51軟體編譯環境中,經過編譯和連線,生成十六進位制的目的碼檔案.hex。在硬體上,用Proteus軟體繪製出原理圖,經過純電路除錯無誤後,將生成的目的碼檔案載入到Proteus介面的AT89C51中。接著再進行軟硬體聯合除錯,反覆除錯,直至所有顯示及按鍵功能實現,直至模擬成功。\
執行截圖:
2.7 參考文獻:
[1] 胡輝. 微控制器原理與應用[M].北京:中國水利水電出版社,2007.
[2] 戴佳. 51微控制器C語言應用程式設計例項精講[M].北京:電子工業出版社,2006.
3. 設計檔案以及原始碼下載
CSDN下載地址
或者關注博主公眾號,回覆:籃球計時器即可下載,還有更多資源分享哦~