【单片机毕业设计】篮球计分系统

简介: 【单片机毕业设计】篮球计分系统

主要功能

  1. 可以在任何时候对每一节的比赛进行倒数,并且可以在任何时候由于攻击方的犯规而中止比赛;
  2. 可以记录比赛双方对比的分数;
  3. 可以在一节后互换场地,对A队和B队的得分进行换位[3];
  4. 具有24秒倒计时功能,可随时按下按钮重置。如果超过24秒篮球在进攻方手里未出手,会发出声音警报,同时停止比赛时间,处理完毕后按下24秒重置按钮,比赛继续。

设计思想

  • 本设计通过运用1个4位LED数码管、2个3位LED数码管和1个2位LED数码管对比赛计时和计分。
  • 本设计还根据最新的比赛规则,增加了24秒倒计时功能,进攻方必须在24秒内有投一次篮,否则视为违规。
  • 该设计能完整实现比赛倒计时、开始、暂停、对篮球比赛中的分数变化进行及时加减记分、24秒倒计时报警和交换场地等功能。

主要代码

#include<reg51.h>
#define LEDData P0
unsigned char code LEDCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int minit,second,count,count1;     //分,秒,计数器
char min=15,sec=0;
sbit add1=P1^0;   //甲对加分,每按一次加1分   /在未开始比赛时为加时间分
sbit dec1=P1^1;   //甲对减分,每按一次减1分  /在未开始比赛时为减时间分
sbit exchange=P1^2; //交换场地
sbit add2=P1^3;   //乙对加分,每按一次加1分  /在未开始比赛时为加时间秒
sbit dec2=P1^4;   //乙对减分,每按一次减1分  /在未开始比赛时为减时间秒
sbit p24_sec=P1^5;
sbit secondpoint=P0^7;    //秒闪动点
//----依次点亮数码管的位------
sbit led1=P2^7;
sbit led2=P2^6;
sbit led3=P2^5;
sbit led4=P2^4;
sbit led5=P2^3;
sbit led6=P2^2;
sbit led7=P2^1;
sbit led8=P2^0;
sbit led9=P3^7;
sbit led10=P3^6;
sbit led11=P3^5;
sbit led12=P3^4;
sbit alam=P1^7;     //报警
bit  playon=0;      //比赛进行标志位,为1时表示比赛开始,计时开启
bit  timeover=0;      //比赛结束标志位,为1时表示时间已经完
bit  AorB=0;      //甲乙对交换位置标志位
bit  halfsecond=0;    //半秒标志位
unsigned int scoreA;    //甲队得分
unsigned int scoreB;    //乙队得分
char sec24=24;    
void Delay5ms(void)
{
  unsigned int i;
  for(i=100;i>0;i--);
}
void display(void)
{
//-----------显示时间分--------------
  LEDData=LEDCode[minit/10];
  led1=0;
  Delay5ms();
  led1=1;
  LEDData=LEDCode[minit%10];
  led2=0;
  Delay5ms();
  led2=1;
//-------------秒点闪动------------
  if(halfsecond==1)
    LEDData=0x7f;
  else
    LEDData=0xff;
  led2=0;
  Delay5ms();
  led2=1;
  secondpoint=0;
//-----------显示时间秒------------
  LEDData=LEDCode[second/10];
  led3=0;
  Delay5ms();
  led3=1;
  LEDData=LEDCode[second%10];
  led4=0;
  Delay5ms();
  led4=1;
//-----------显示1组的分数百位-------
  if(AorB==0)
    LEDData=LEDCode[scoreA/100];
  else
    LEDData=LEDCode[scoreB/100];
  led5=0;
  Delay5ms();
  led5=1;
//---------------显示1组分数的十位-----------
  if(AorB==0)
    LEDData=LEDCode[(scoreA%100)/10];
  else
    LEDData=LEDCode[(scoreB%100)/10];
  led6=0;
  Delay5ms();
  led6=1;
//---------------显示1组分数的个位-----------
  if(AorB==0)
    LEDData=LEDCode[scoreA%10];
  else
    LEDData=LEDCode[scoreB%10];
  led7=0;
  Delay5ms();
  led7=1;
//-----------显示2组分数的百位-------
  if(AorB==1)
    LEDData=LEDCode[scoreA/100];
  else
    LEDData=LEDCode[scoreB/100];
  led8=0;
  Delay5ms();
  led8=1;
//-----------显示2组分数的十位-----------
  if(AorB==1)
    LEDData=LEDCode[(scoreA%100)/10];
  else
    LEDData=LEDCode[(scoreB%100)/10];
  led9=0;
  Delay5ms();
  led9=1;
//-----------显示2组分数的个位-----------
  if(AorB==1)
    LEDData=LEDCode[scoreA%10];
  else
    LEDData=LEDCode[scoreB%10];
  led10=0;
  Delay5ms();
  led10=1;
//-----------显示时间分--------------
  LEDData=LEDCode[sec24/10];
  led11=0;
  Delay5ms();
  led11=1;
  LEDData=LEDCode[sec24%10];
  led12=0;
  Delay5ms();
  led12=1;
}
//==================按键检测程序===================== ====
void keyscan(void)
{
  //如果比赛没开始 
  if(playon==0)
  {
    //按下加分钟的按钮 
    if(add1==0)
    {
      //显示分数和时间 
      display();
      if(add1==0);
      {
        if(minit<99)
          minit++;
        else
          minit=99; 
          min=minit;
      }
      do
        display();  //while等待松开 
      while(add1==0);
    }
    //按下减分钟的按钮 
    if(dec1==0)
    {
      display();
      if(dec1==0);
      {
        if(minit>0)
          minit--;
        else
          minit=0;
          min=minit;
      }
      do
        display();   //while等待松开 
      while(dec1==0);
    }
    //按下加秒数按钮 
    if(add2==0)
    {
      display();
      if(add2==0);
      {
        if(second<59)
          second++;
        else
          second=59; 
          sec=second;
      }
      do
        display();
      while(add2==0);
    }
    //按下减秒数按钮 
    if(dec2==0)
    {
      display();
      if(dec2==0);
      {
        if(second>0)
          second--;
        else
          second=0;  
          sec=second;
      }
      do
        display();
      while(dec2==0);
    }
    //按下场地交换按钮 
    if(exchange==0)
    {
      display();
      if(exchange==0);
      {
        TR1=0;          //关闭T1计数器
        alam=1;         //关报警
          AorB=~AorB;       //开启交换  
        minit=min;        //并将时间预设为15:00
        second=sec;
        sec24=24;
      }
      do
        display();
      while(exchange==0);
    } 
  }
  //如果比赛开始 
  else
  {
    //按下甲队加分按钮 
    if(add1==0)
    {
      display();
      if(add1==0);
      {
        //判断是否交换场地 
        if(AorB==0)
        {
          if(scoreA<999)
            scoreA++;
          else
            scoreA=999;
        }
        else
        {
          if(scoreB<999)
            scoreB++;
          else
            scoreB=999;
        }
      }
      do
        display();
      while(add1==0);
    }
    //按下甲队减分按钮 
    if(dec1==0)
    {
      display();
      if(dec1==0);
      {
        if(AorB==0)
        {
          if(scoreA>0)
            scoreA--;
          else
            scoreA=0;
        }
        else
        {
          if(scoreB>0)
            scoreB--;
          else
            scoreB=0;
        }
      }
      do
        display();
      while(dec1==0);
    }
    //按下乙队加分按钮 
    if(add2==0)
    {
      display();
      if(add2==0);
      {
        if(AorB==1)
        {
          if(scoreA<999)
            scoreA++;
          else
            scoreA=999;
        }
        else
        {
          if(scoreB<999)
            scoreB++;
          else
            scoreB=999;
        }
      }
      do
        display();
      while(add2==0);
    }
    //按下乙队减分按钮 
    if(dec2==0)
    {
      display();
      if(dec2==0);
      {
        if(AorB==1)
        {
          if(scoreA>0)
            scoreA--;
          else
            scoreA=0;
        }
        else
        {
          if(scoreB>0)
            scoreB--;
          else
            scoreB=0;
        }
      }
      do
        display();
      while(dec2==0);
    }
    //一次进攻结束 
    if(p24_sec==0)
    {
      display();
      if(p24_sec==0)
      {
        sec24=24;
        TR0=1;
        alam=1;
        while(p24_sec==0) display();
      }
    }
  }
}
//******************************主函数********************************
void main(void)
{
  TMOD=0x11;
  TL0=0xb0;
  TH0=0x3c;
  TL1=0xb0;
  TH1=0x3c;
  minit=min;        //初始值为15:00
  second=sec;
  EA=1;
  ET0=1;
  ET1=1;
  TR0=0;
  TR1=0;
  EX0=1;
  IT0=1;
  IT1=1;
//  EX1=1;
  PX0=1;
//  PX1=1;
  PT0=0;
  P1=0xFF;
  P3=0xFF;
  alam=1;
  while(1)
  {
    keyscan();
    display();      
    }
}
void PxInt0(void) interrupt 0
{
  Delay5ms();
  EX0=0;
  alam=1;
  TR1=0;
  if(timeover==1)
  {
    timeover=0;
  }
  if(playon==0)
  {
    playon=1;       //开始标志位
    TR0=1;          //开启计时
    if((minit+second)==0)
    {
      sec24=24;
      minit=min;      
      second=sec;
    }
  }
  else
  {
    playon=0;       //开始标志位清零,表示暂停
    TR0=0;          //暂时计时
  } 
  EX0=1;            //开中断 
}
/*
void PxInt1(void) interrupt 2
{
  Delay5ms();
  EX1=0;      //关中断
  if(timeover==1) //比赛结束标志,必须一节结束后才可以交换,中途不能交换场地
  {
    TR1=0;      //关闭T1计数器
    alam=1;     //关报警
      AorB=~AorB; //开启交换  
    minit=15;   //并将时间预设为15:00
    second=0;
  }
  EX1=1;        //开中断
}
*/
//***************************中断服务函数******************************
void  time0_int(void) interrupt 1 
{
  TL0=0xb0;     //设置初值
  TH0=0x3c;
  TR0=1;       //开T0中断
    count++;
  if(count==10)
  {
    halfsecond=0;
  }
    if(count==20)
    {
    count=0;
    halfsecond=1;   //count=0是半秒 
//    if(second>0)
    {
      //second用于整场比赛的时间,15分钟 
      second--;   //秒减一 
      if(second<0)  //一分钟 
      {
        if(minit>0)
        {
          second=59;     //秒赋予59
          minit--;        //分减1
        }
        else    //倒计时结束 
        {
          second=0;        //当秒数为0时
          timeover=1;
          playon=0;      //关闭开关
          TR0=0;         //关闭T0定时器
          TR1=1;         //打开T1定时器  蜂鸣器 
        }
      }
      //sec24用于一次进攻的时间,24秒 
      sec24--;       //对24s倒计时
      if(sec24<=0)       //判断倒计时是否结束
      {
        if((minit+second)!=0)
        {
          alam=0;           //发出警报
          TR0=0;             
        }
        sec24=0;     //24秒倒计时置0
      }
    }
    }
}
//*************************中断服务函数********************************
void  time1_int(void) interrupt 3
{
  TL1=0xb0;
  TH1=0x3c;
  TR1=1;
    count1++;
  if(count1==10)
  {
    alam=0;   //开蜂鸣器 
  }
    if(count1==20)
    {
    count1=0;
    alam=1;
  }
}


相关文章
|
6月前
|
存储
单片机的指令系统
单片机的指令系统
47 1
|
6月前
|
监控
单片机的时钟系统
单片机的时钟系统
72 1
|
6月前
|
传感器 编解码 数据处理
毕业设计|基于STM32单片机的水位浑浊度检测设计
毕业设计|基于STM32单片机的水位浑浊度检测设计
802 0
|
25天前
|
传感器 编解码 人机交互
基于51单片机的温室大棚环境检测系统
基于51单片机的温室大棚环境检测系统
46 0
|
6月前
|
传感器 数据采集 监控
LabVIEW单片机的废气再循环EGR检测系统
LabVIEW单片机的废气再循环EGR检测系统
45 0
|
6月前
|
传感器 存储 安全
基于单片机的定时温控系统的设计_kaic
基于单片机的定时温控系统的设计_kaic
|
6月前
|
传感器
基于51单片机的车辆倒车雷达报警系统
该文描述了一个基于51单片机的超声波倒车雷达系统设计,要求包括:2cm至4m的测量范围,3mm精度,集成DS18B20温度传感器以校准声速,使用LCD1602显示距离和温度,具备按键设置预警距离及蜂鸣器报警功能。系统由AT89C51单片机、HC-SR04超声波模块、DS18B20温度模块、报警电路和LCD显示电路组成。文中还展示了Proteus仿真电路图和部分仿真结果分析,包括LCD显示示例和预警距离设置操作。
【期末不挂科-单片机考前速过系列P5】(第五章:11题速过中断系统和中断系统结构)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P5】(第五章:11题速过中断系统和中断系统结构)经典例题盘点(带图解析)
|
6月前
|
传感器 安全 物联网
单片机在智能家居系统中的应用研究
单片机在智能家居系统中的应用研究
189 1
|
6月前
|
芯片
AT89S52单片机的最小应用系统
AT89S52单片机的最小应用系统
95 0