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

主要功能

  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;
	}
}


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为梦而生~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值