專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

單片機(jī)課程設(shè)計(jì)(籃球記分器)

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2012年12月19日   【字體:

 電路圖:


本程序已經(jīng)通過(guò)軟件仿真與硬件制作,
首發(fā)于:www.torrancerestoration.com ,代碼可任意修改,但不可用于商業(yè)目的.
單片機(jī)型號(hào)是:stc89c52,晶振12兆赫.用了3個(gè)4為一體化的數(shù)碼管.
完整代碼下載地址:http://www.torrancerestoration.com/f/lqwwe.rar 
#include <reg51.h>
 #define uchar unsigned char
 #define uint unsigned int
 void delay(uchar x);         //延時(shí)(時(shí)間較短)
 void delay1(uchar x);        //延時(shí)(時(shí)間較長(zhǎng))
 void Js_Jf_Scan(void);       //數(shù)碼管動(dòng)態(tài)掃描顯示函數(shù)
 void Key_if(void);          //A、B兩隊(duì)分值處理函數(shù)
 void Js_50ms(void);        //定時(shí)50ms中斷函數(shù)
 void Key_Y(void);         //預(yù)置時(shí)間函數(shù)
 void Ptime(uchar);         //時(shí)間處理函數(shù)
 void sound(void);          //鳴笛警示函數(shù)
 void jiaohuan(void);    //場(chǎng)地交換
 sbit CL1=P2^0;           //B隊(duì)4位計(jì)分?jǐn)?shù)碼管位控線
 sbit CL2=P2^1;
 sbit CL3=P2^2;
 sbit CL4=P2^3;
 sbit KL1=P2^4;           // A隊(duì)4位計(jì)分?jǐn)?shù)碼管位控線
 sbit KL2=P2^5;
 sbit KL3=P2^6;
 sbit KL4=P2^7;
 sbit S1=P1^3;            //驅(qū)動(dòng)4位計(jì)時(shí)數(shù)碼管位控線
 sbit S2=P1^2;
 sbit S3=P1^1;
 sbit S4=P1^0;
 sbit YK1=P1^6;          //預(yù)置分鐘的十位
 sbit YK2=P1^7;          //預(yù)置分鐘的個(gè)位
 sbit music=P1^4;         //P1.4接喇叭,發(fā)聲,鳴笛
 sbit Key1=P3^0;         //B隊(duì)加分鍵
 sbit Key2=P3^1;         //B隊(duì)減分鍵
 sbit Key3=P3^4;         //A隊(duì)加分鍵
 sbit Key4=P3^5;         //A隊(duì)減分鍵
 sbit JH=P1^5;
 sbit Int_Key=P3^2;                    //鳴笛鍵
 sbit Star=P3^6;                       //開(kāi)始按鈕
 sbit Puse=P3^7;                      //停止按鈕  
 int m=0,ms=0,mg=0;                  //秒鐘的十位、個(gè)位以及秒鐘的變量說(shuō)明
 int fs=0,fg=0,f,fy,num=0;              //分鐘的十位、個(gè)位以及分鐘的變量說(shuō)明
 int g,s,b,q,sum=0;                     //B隊(duì)定義個(gè)十百位
 int g1,s1,b1,q1,sum1=0;               // A隊(duì)定義個(gè)十百位
 int LED_Num[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x00,}; //段碼
 
 void main(void)
 {
  TMOD=0x01;                    //設(shè)置T0為工作方式1,作為16位計(jì)數(shù)器
  TH0=(65535-50000)/256;           //設(shè)置T0的高8位,并且T0的計(jì)數(shù)值為50ms
  TL0=(65535-50000)%256;          //設(shè)置T0的低8位
  music=0;                        //初值喇叭不響
  EA=1;                          //開(kāi)放所有中斷
  ET0=1;                         //允許定時(shí)/計(jì)數(shù)器T0溢出中斷
  EX0=1;                         //允許外部中斷0
  IT0=1;                          //設(shè)置外部中斷0為邊沿觸發(fā)方式(下降沿)
  while(1)                        //無(wú)窮循環(huán),程序一直運(yùn)行
  {
   Key_Y();                    //預(yù)置場(chǎng)次比賽時(shí)間
   if(Star==0&&f!=0&&Puse!=0)  //按下“開(kāi)始鍵”,設(shè)置好比賽時(shí)間,并且未按“停止”鍵時(shí),比賽正式開(kāi)始
   {
    TR0=1;                 //啟動(dòng)定時(shí)器T0,開(kāi)始計(jì)時(shí)
    Key_if();                //開(kāi)始計(jì)分
   }
   else
   {
    TR0=0;               //比賽還未開(kāi)始或比賽結(jié)束時(shí)間到,停止計(jì)時(shí)
   }
   Js_Jf_Scan();                //將相應(yīng)的分?jǐn)?shù)、時(shí)間同步進(jìn)行顯示
  }
 }
 /*******************設(shè)置場(chǎng)次比賽時(shí)間********************/
 void Key_Y(void)
 {
  if(YK1==0)                     //初始狀態(tài),分鐘的十位為0
  {
   delay(1);                    //延時(shí)去抖動(dòng)
   fs=fs+1;                    //分十位加1分
   fy=fs*10+fg;                //求出預(yù)置時(shí)間的分鐘值
   f=fy;
   while(YK1==0);      //中間變量                    
  }
  if(YK2==0)                     //初始狀態(tài),分鐘的個(gè)位為0
  {
   delay(1);                    //延時(shí)去抖動(dòng)
   fg=fg+1;                    //分個(gè)位加1分
   fy=fs*10+fg;                //求出預(yù)置時(shí)間的分鐘值
   f=fy;                       //中間變量
   while(YK1==0);                    
  }
  Js_Jf_Scan();
 }
 /********T0中斷服務(wù)函數(shù),每隔50ms產(chǎn)生一次中斷********/
 void Js_50ms(void)interrupt 1 using 1   //定時(shí)器T0中斷,用工作寄存器組1
 {
  TH0=(65535-50000)/256;         //定時(shí)器T0的高8位
  TL0=(65535-50000)%256;        //定時(shí)器T0的低8位
  num++;                        //每50ms累加一次
  Ptime(num);                    //調(diào)用時(shí)間處理函數(shù)
 }
 /**********************時(shí)間處理函數(shù)********************/
 void  Ptime(uchar time)
 { 
  if(time==20)                   //如果為1s(50ms*20=1s)
  {
   num=0;
   m--;                     //每到1s,計(jì)時(shí)器累加1次
   ms=m/10;                 //秒的十位
   mg=m%10;                //秒的個(gè)位
   if(m<0)                 //如果為1min
   {
    m=59;                  //秒鐘置0
       mg=m%10;            //秒鐘的個(gè)位置0
    ms=m/10;              //秒鐘的十位置0
    f--;                   //分鐘開(kāi)始在預(yù)設(shè)的比賽時(shí)間基礎(chǔ)上倒計(jì)時(shí)
    fs=f/10;               //分鐘的十位
    fg=f%10;              //分鐘的個(gè)位
    if(f==0)               //分鐘數(shù)倒計(jì)時(shí)到0
    {
     TR0=0;            //時(shí)間到,停止計(jì)時(shí)
    }  
   }
  }
 }
 /******************數(shù)碼管動(dòng)態(tài)掃描顯示******************/
 void Js_Jf_Scan(void)
 {
  uchar j;
  for(j=0;j<=5;j++)
  {
   KL4=0;P0=LED_Num[g1];delay(1);KL4=1;  /*將A隊(duì)分?jǐn)?shù)的個(gè)位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   KL3=0;P0=LED_Num[s1];delay(1);KL3=1;  /*將A隊(duì)分?jǐn)?shù)的十位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   KL2=0;P0=LED_Num[b1];delay(1);KL2=1;  /*將A隊(duì)分?jǐn)?shù)的百位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   KL1=0;P0=LED_Num[q1];delay(1);KL1=1;  /*將A隊(duì)分?jǐn)?shù)的千位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   CL4=0;P0=LED_Num[g];delay(1);CL4=1;   /*將B隊(duì)分?jǐn)?shù)的個(gè)位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   CL3=0;P0=LED_Num[s];delay(1);CL3=1;    /*將B隊(duì)分?jǐn)?shù)的十位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   CL2=0;P0=LED_Num[b];delay(1);CL2=1;    /*將B隊(duì)分?jǐn)?shù)的百位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   CL1=0;P0=LED_Num[q];delay(1);CL1=1;   /*將B隊(duì)分?jǐn)?shù)的千位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   S4=0;P0=LED_Num[mg];delay(1);S4=1;   /*將秒鐘的個(gè)位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   S3=0;P0=LED_Num[ms];delay(1);S3=1;  /*將秒鐘的十位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   S2=0;P0=LED_Num[fg];delay(1);S2=1;  /*將分鐘的個(gè)位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
   S1=0;P0=LED_Num[fs];delay(1);S1=1;    /*將分鐘的十位傳遞給譯碼器,通過(guò)按鍵,實(shí)現(xiàn)邊沿跳變,并把結(jié)果譯成相應(yīng)的段碼顯示出來(lái)*/
  }
 }
 /*****************判斷是哪個(gè)隊(duì)加分或者減分*****************/
 void Key_if(void)
 {
  if(Key1==0)                      //當(dāng)按鍵按下時(shí)
  {
   delay(1);                     //延時(shí)去抖動(dòng)
   sum=sum+1;                   //B隊(duì)加1分
  }
  if(Key2==0 && sum>=1)           //減分按鍵按下并且中得分不得少于1分
  {
   delay(1);                     //延時(shí)去抖動(dòng)
   sum=sum-1;                   //B隊(duì)減1分
  }
  if(Key3==0)                      //當(dāng)按鍵按下時(shí)
  {
   delay(1);                     //延時(shí)去抖動(dòng)
   sum1=sum1+1;               //A隊(duì)加1分
  }
     if(Key4==0 && sum1>=1)         //減分按鍵按下并且中得分不得少于1分
  {
   delay(1);                     //延時(shí)去抖動(dòng)
   sum1=sum1-1;               //A隊(duì)減1分
  }
  q=0;                            // A隊(duì)分值的千位默認(rèn)為0
  b=sum/100;                      //求出A隊(duì)分值的百位
  s=sum/10-b*10;                   //求出A隊(duì)分值的十位
  g=sum%10;                      //求出A隊(duì)分值的個(gè)位
  q1=0;                           // B隊(duì)分值的千位默認(rèn)為0
  b1=sum1/100;                    //求出B隊(duì)分值的百位
  s1=sum1/10-b1*10;                //求出B隊(duì)分值的十位
  g1=sum1%10;                    //求出B隊(duì)分值的個(gè)位
 }
 /***********************鳴笛處理***********************/
 void sound(void) interrupt 0 using 0  //外部中斷0(),用工作寄存器組0
 {
  uchar i,j;
  if(Int_Key==0)                    //判斷鳴笛鍵是否按下,有按下就鳴笛
  {
   for(i=0;i<8;i++)               //控制一種發(fā)音的時(shí)間
   {
    for(j=0;j<250;j++)          //控制發(fā)音的頻率,延時(shí)長(zhǎng),頻率低,音低
    {
     music=~music;         //取反
     delay1(1);             //延時(shí)去抖動(dòng)
    }
           Js_Jf_Scan();
   }
   for(i=0;i<16;i++)              //控制另一種發(fā)音的時(shí)間
   {
      for(j=0;j<250;j++)          //控制發(fā)音的頻率,延時(shí)短,頻率高,音高
    { 
     music=~music;         //取反
     delay(1);              //延時(shí)去抖動(dòng)
    }
           Js_Jf_Scan();
 }
 }
  else
   music=0;                     //喇叭不響
 }
  /*******************場(chǎng)地交換函數(shù)*******************/
 void jiaohuan(void)
 {
  int t;
  if(JH==0)
  {
   sum=t;
   t=sum1;
   sum1=t;
  }
 
 }
 
 /*******************延時(shí)1.8ms的子程序*******************/
 void delay1(uchar x)
 {
  uchar k;
  while(x--)
   for(k=0;k<215;k++);     //延時(shí)長(zhǎng)
 }
 /*******************延時(shí)1.0ms的子程序*******************/
 void delay(uchar x)
 {
  uchar k;
  while(x--)
   for(k=0;k<120;k++);     //延時(shí)短
 }

關(guān)閉窗口

相關(guān)文章