實訓題目:籃球計分牌
1 系統設計
1.1 設計要求
1.1.1 設計任務
(1) 按照題目要求獨立設計系統所需電路,并完成硬件電路的制作及調試。(40分)
(2)結合硬件能夠正常計分(1,2,3)。(10分)
(3)能夠正常顯示分值。(10分)
(4)能夠正常修改工作模式(計分與24秒)。(10分)
(5)能夠24秒的誤差不小于1秒。(15分)
能夠兩隊球員犯規次數計數。
1.2 設計思路及設計框圖
1.2.1設計思路
通過利用STC89C52RC芯片進行設計,7個按鍵實現對應功能:
(1)P1^3通過控制點對應切換1隊和2隊加分。
(2)P1^0、P1^1、P1^2分別對應+1、+2、+3分。
(3)P1^4計分清零
(4)P1^5對應24秒倒計時和計分的轉換。
(5)P1^7外接復位鍵,對應復位功能。
外加復位鍵,按下則數碼管顯示回到比分計分顯示,并清零;24秒倒計時至5秒時led燈依次點亮,倒計時結束時全部點亮。倒數為0時蜂鳴器響,重新倒數時蜂鳴器關閉。切換加分后24s倒計時會自動重新計時。24s倒計時需要用定時器中斷方式0實現,采用工作方式一。并且每秒的時長要有晶振電路控制。
將12MHZ的石英晶體振蕩器和單片機對應的引腳正確連接,將晶振產生的時鐘信號作為定時信號。籃球計分牌分為三個部分:開關控制、數碼管顯示和警示電路。P主要在籃球比賽中用于記錄24秒犯規計時和顯示紅藍兩隊在比賽過程中的比分情況,本計時計分器有兩部分組成:一部分用來實現計時功能,其基本原理和定時鬧鐘相似;另一部分用來實現計分功能,其基本原理和計數器相似,只不過所要記錄和顯示的對象分別是按鍵按下的次數和掃描脈沖次數。
1.2.2總體設計框圖
2 各個模塊程序的設計
2.1 AT89S52芯片模塊
本次實驗所用到的主要芯片,AT89S52是美國ATMEL公司生產的低電壓,高性能CMOS8位單片機,片內含4K bytes的可反復擦寫的只讀程序存儲器(PEROM)和128 bytes的隨機存取數據存儲器(RAM),期間采用ATMEL公司的高密度、非易失性存儲技術生產,兼容標準MCS-51指令系統,片內置通用8位中央處理器(CPU)和Flash存儲單元,功能強大AT89S52單片機可為您提供許多高性價比的應用場合,可靈活應用于各種控制領域。
2.2振蕩電路模塊
晶振模塊給電路提供一定頻率的穩定的震蕩(脈沖)信號。
2.3數碼管顯示模塊
排阻保護電路使數碼管正常輸出相應的數據信息。
2.4 LED電路
通過LED燈來指示隊伍、提示犯規、計時提示等功能。
2.5按鍵模塊
按鍵控制加分、切換、計時控制等。
2.6電源部分
為電路提供電源,使其工作。
2.7復位模塊
作用是將單片機復位,將單片機初始化。
3 調試過程
3.1制作過程
n 設計電路原理圖;
n 上網查閱C51管腳及數碼管管腳資料;
n 把器件安在打好孔的萬用板上,然后焊接;
n 焊接好后,接通5V電源,檢查電路是否顯示正常;
n 根據硬件寫出實現實訓要求的對應程序,并進行調試,直到能全部正確實現要求的功能。
4 功能測試
4.1 測試儀器與設備
n 單片機程序下載線 1條
n 萬用表 1個
n PC機 1臺
4.2 性能指標測試
1、指標測試:以實現兩隊比分的正確顯示,可以進行24S正常倒計時并報警,能記兩隊的1分2分3分。
2、軟件調試還算順利,沒有太大的問題。
3、第一次硬件調試時,發現有一盞LED沒有亮,確定是LED燈壞了便從新焊上一個好的。
4、拆掉所有跳線后,被指出所有的按鍵連接錯誤,這些按鍵內部結構是對腳線相連。于是重連按鍵。刪掉原理圖中不需要的元器件,直接按著原理圖焊接跳線。
4.3 誤差分析
倒計時24s在倒計時方面時和現實的時間存在點小誤差,但是誤差很小可以忽略.感覺軟件方面沒有什么問題,硬件上按鍵不是很靈敏,可能是線路接觸不良。數碼管驗收出現小問題,是管腳虛焊導致的。
5 實訓心得體會
通過這次實訓,讓我學習了很多。這次實訓應該算是目前最難得一次實訓吧。輔導老師給了基本的原理圖,然后經過自己百度和同學幫助下完善了原理圖。然后自己根據原理圖焊了很久,最后焊完時讓同學幫我下載程序,結果程序下載不進去,最后在學霸的幫助下解決了這個下問題。驗收的時候我看其他同學都有好多的功能,感覺自己的功能略少,心里一陣緊張。不過幸運的是基本功能還是能實現的。就是驗收的時候出現了一點小問題,數碼管段選除了一些問題,應該是數碼管管腳虛焊,但是在宿舍前一晚還好,以后要是在做實訓要加強焊接
總的來說過程是最重要的,很開心自己能夠完成這次實訓,在這過程中又讓我學很多知識。每次焊接雖然都要到晚上兩點 ,雖然很累但是發現問題解決問題讓我信心滿滿,這次實訓讓我明白了不要老想著靠別人自己動手操作一根根的去找,按照原理圖一根去接會發現問題出在哪里,以前只想出現問題了去找大神幫忙,但是這次實訓給了我很大的信心,雖然我每次實訓都是一波三折,但是這也代表我不放棄所以以后做實訓一定要自己査好資料,出現問題了先自己解決,在回答問題上我準備的還是不夠充分,本來在前一天晚上看到了兩點,一直再看原理圖,但是關于周期和程序問題還是沒回答上,不過在動手能力上又增強了很多信心!也謝謝兩位老師開題的指導,衷心謝謝老師。
附錄
附錄1:原理圖
附錄2:程序清單
#include<reg52.H> //*****頭文件*****//
#define ucharunsigned char //*定義變量*//
#define uint unsigned int //*定義uint為無符號整形變量*//
unsigned t =0x3cb0;
uchar CZ=24; //*計時初值*//
uchar key=0;
uchar score;
uchar mode=1;//*模式變量*//
uchar score1=0; //*甲隊得分變量*//
ucharscore2=0; //*乙隊得分變量*//
ucharbittime=0,bitdisplay=0; //*定義變量*//
uchar codetab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //*段碼0,1,2,3,4,5,6,7,8,9*//
sbit J0=P1^0; //*獨立按鍵 *//
sbit J1=P1^1;
sbit J2=P1^2;
sbit J3=P1^3;
sbit J4=P1^4;
sbit J5=P1^5;
sbit J6=P1^6;
sbit LED1 = P3^4;
sbit LED2 = P3^5;
sbit LED3 = P3^6;
sbit LED4 = P3^7;
sbit SPK=P1^7;
/********延時函數******/
void delay(ucharz)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/* 服務程序*/
void timer0 (void)interrupt 1 using 0
{
TH0=0x3c; //*50ms*//
TL0=0xb0;
bittime++; //每來一次中斷,中斷次數bittime自加1
while(bittime==20)
{
bittime=0; //每經一秒調用一次顯示程序
bitdisplay=1;
if(bitdisplay)
{
bitdisplay = 0;
CZ--;
if(-1 == CZ) CZ=24;
}
}
}
/* 甲隊分數顯示函數*/
voiddisplay_1(uint z)
{
P2 = 0XFD; /*11111101甲隊個位分數顯示*/
P0 = tab[z%10];
delay(10);
P2 = 0XFE; /*11111110甲隊十位分數顯示*/
P0 = tab[z/10];
delay(10);
}
/* 乙隊分數顯示函數*/
voiddisplay_2(uint z)
{
P2 = 0Xfb; /*11110111乙隊個位分數顯示*/
P0 = tab[z%10];
delay(10);
P2 = 0Xf7; /*11111011乙隊十位分數顯示*/
P0 = tab[z/10];
delay(10);
}
/* 甲分數處理函數*/
int inc1()
{
if(~J3)
{
delay(10);
score1=score1+1;
}while(~J3);
if(~J4)
{
delay(10);
score1= score1+2;
}while(~J4);
if(~J5)
{
delay(10);
score1=score1+3;
}while(~J5);
returnscore1;
}
/* 乙分數處理函數*/
int inc2()
{
if(~J3)
{
delay(10);
score2=score2+1;
}while(~J3);
if(~J4)
{
delay(10);
score2= score2+2;
}while(~J4);
if(~J5)
{
delay(10);
score2=score2+3;
}while(~J5);
returnscore1;
}
/* 甲乙隊切加分換處理函數*/
uchar turn()
{
if(~J2)
{
delay(10);
if(~J2)
{
delay(10);
LED1 = 1;
LED2 = 1;
LED3 = 0;
LED4 = 1;
key = 1;
}while(~J2);
}
if(~J6)
{
delay(10);
if(~J6)
{
delay(10);
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 0;
key = 2;
}while(~J6);
}
return key;
}
/* 加分顯示函數*/
void marks()
{
turn();
if(key== 1)
{
inc1();
if(score1<100)
{
display_1(score1);
display_2(score2);
}
else score1 =score1-100;
}
elseif(key == 2)
{
inc2();
if(score2<100)
{
display_1(score1);
display_2(score2);
}
else score2 = score2-100;
}
}
/*模式選擇函數*/
ucharmode_select()
{
if(~J0)
{
delay(10);
if(~J0)
{
delay(10);
mode = 1;
LED1 = 0;
LED2 = 1;
LED3 = 1;
LED4 = 1;
}while(~J0);
}
if(~J1)
{
delay(10);
if(~J1)
{
delay(10);
mode = 2;
LED1 = 1;
LED2 = 0;
LED3 = 1;
LED4 = 1;
}while(~J1);
}
return mode;
}
/*倒計時處理*/
void time_count()
{
TR0 = 1;
P2 = 0XFD; /*11111010甲乙十位顯示*/
P0 = tab[CZ/10];
delay(10);
P2 = 0XFB; /*11110101甲乙個位顯示*/
P0 = tab[CZ%10];
delay(10);
}
/* 主函數*/
int main()
{
TMOD= 0x01;
TH0=0x3c;
TL0=0xb0;
EA = 1; //cpu允許所有中斷
ET0 =1;//定時器T0中斷允許
TR0 = 0;//關閉定時器T0
P2 = 0XF0;
P0 = 0x3f;
SPK=0;
while(1)
{
mode_select();
if(1 == mode) //加分功能
{
TR0 = 0;//關閉定時器
CZ = 24; //重新賦初值24秒
display_1(score1);
delay(10);
display_2(score2);
marks();
}
if(2== mode) //計時功能
{
if(CZ == 0){TR0 = 0,SPK=1;delay(30);SPK =0;
foul_sever();
}
time_count();}
}
return 0;
}
|