基于stm32f103的模拟篮球计分器设计

本文详细描述了一款基于STM32F103zet6的模拟篮球计分器的设计过程,包括时间显示、比分控制、暂停功能、加分/减分机制以及温度实时显示,通过C语言编程实现各项功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验要求:

基于stm32f103zet6编写程序,设计一个模拟篮球计分器,可以显示比赛总时间,包括分、秒及十分之一秒;可以显示两队总比分;可以通过按键控制时间暂停,且此时仍能显示总比分;两队的比分均具有加1,加2,加3 的加分方式。

二、设计思路:

首先针对第一个要求显示比赛总时间,我分为两种计时方式,通过按键来控制,分别是正常速率计时以及0.1倍速计时,0.1倍速计时只要让十分之一秒按照每一秒加一的速率运行即可实现,而对于正常速率计时,经过了C语言的学习也不难写出。

对于第二个要求显示两队总比分,只要掌握好LCD_ShowString( ),LCD_ShowxNum( )两个函数的用法即可,注意控制好横纵坐标的位置,合理设计函数内的参数,防止重叠或字符与数字不对齐等问题的产生。

对于通过按键控制时间暂停,我定义了一个参数如t,当不同的按键按下时t会有不同的值,从而实现不同的功能,例如t为0时0.1倍速计时,t为1时暂停,t为2时正常计时,t为3时终止比赛。然后使用if...else...语句,写出t取不同值时对应的代码,t为1时不做操作,而在t取0和1时采用计时,从而实现了按键控制时间暂停。

对于使两队的比分均具有加1,加2,加3 的加分方式,由于战舰开发板上只有四个按键难以实现功能,因此我采用红外遥控器,利用switch...case...语句,不同的键值实现不同的功能。

在上述要求之外,我还设计了减分功能,以防止误触按键时比分出现差错,同加分一样,利用switch...case...语句,不同的键值下写入减分语句。同时,我设计当有球队一次加3分时,红灯亮起。另外,在按下遥控器的9键时,可以切换LCD背景,通过LCD_Clear( )函数来改变颜色。对于上面提到的终止比赛键,按下时可以将计时清零,并比较两队的目前比分,在屏幕上显示胜者。此外,我还利用温度采集,在LCD上实时显示温度,并取整数返回发给上位机,通过串口调试助手可以看到。

三、主要代码:

该代码以正点原子战舰开发板v3提供的例程为根本遵循,故只给出main.c,main.c中代码如下:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "remote.h"
#include "tsensor.h"


int main(void)
{			  
	u16 min=0;u16 s=0;u16 ss=0;
	u8 key,keyy;
	u8 t;
	u8 c=0;u8 a=0;u8 b=0;
	u8 x=0;
	u16 times;
	u16 temp1;u16 adcx;
	
	delay_init();	    	    
	uart_init(115200);	
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	
 	LED_Init();			     
	LCD_Init(); 
	KEY_Init();
	Remote_Init();  
    T_Adc_Init();	
	
    while(1) 
    {	
	 
	key=Remote_Scan();	
	if(key)
		{	 
				  
			switch(key)
			{
				case 0:;break;			   
				case 162:;break;	    
				case 98:;break;	    
				case 2:;break;		 
				case 226:;break;		  
				case 194:;break;	   
				case 34:;break;		  
				case 224:;break;		  
				case 168:;break;		   
				case 144:;break;		    
				case 104:a=a+1;break;		       //1队加1分  
				case 152:a=a+2;break;	           //1队加2分
				case 176:a=a+3;LED0=0;break;	   //1队加3分,红灯亮 
				case 48:b=b+1;break;		       //2队加1分
				case 24:b=b+2;break;		       //2队加2分
				case 122:b=b+3;LED0=0;break;       //2队加3分,红灯亮		  
				case 16:a=a-1;break;			   //1队减1分				
				case 56:b=b-1;break;	           //2队减1分
				case 90:x++;if(x==9)x=0;;break;    //切换背景颜色
				case 66:;break;
				case 82:;break;		 
			}
			
		}
		else delay_ms(700);	 
		
		switch(x)                                  //切换背景颜色
		{
			case 0:LCD_Clear(WHITE);break;
			case 1:LCD_Clear(BLACK);break;
			case 2:LCD_Clear(MAGENTA);break;
			case 3:LCD_Clear(CYAN);break;
			case 4:LCD_Clear(YELLOW);break;
			case 5:LCD_Clear(BRRED);break;
			case 6:LCD_Clear(GRAY);break;
			case 7:LCD_Clear(LGRAY);break;
			case 8:LCD_Clear(BROWN);break;
		}
		POINT_COLOR=RED; 
		LCD_ShowString(10,50,200,16,16,"min:"); 
        LCD_ShowString(10,65,200,16,16,"s:"); 
	    LCD_ShowString(10,80,200,16,16,"ss:"); 
	    LCD_ShowString(30,100,200,16,16,"1  vs  2");		
		
		
		POINT_COLOR=BLUE;
	    LCD_ShowxNum(50,50,min,4,16,0);
        LCD_ShowxNum(50,65,s,4,16,0);
	    LCD_ShowxNum(50,80,ss,4,16,0);
		
		keyy=KEY_Scan(0);
		if(keyy)
		{
			switch(keyy)
			{
				
				case KEY1_PRES:t=1;break;     //暂停键
				case WKUP_PRES:t=0;break;     //0.1倍速计时
				case KEY0_PRES:t=2;break;     //正常计时
				case KEY2_PRES:t=3;break;     //终止比赛
				
			}
		}
		
		if(t==0)
		{
			ss++;
	     if(ss==10)
	    {
		 ss=0;
		 s++;
	    }
	     if(s==60)
	    {
		 s=0;
		 min++;
	    }
	     if(min==48)
	    {
		 min=0;
	    }
		 delay_ms(100);
				
        }
		else if(t==1)
		{ }
		else if(t==2)
		{
			ss=0;
			ss=ss+10;
	        if(ss==10)
	    {
		    ss=0;
		    s++;
	    }
	        if(s==60)
	    {
		    s=0;
		    min++;
	    }
	        if(min==48)
	    {
		    min=0;
	    }
		    delay_ms(100);
		}
		else if(t==3)
		{
			ss=0;s=0;min=0;
			if(a>b) LCD_ShowString(30,180,200,16,16,"1 is the winner");
			else if(a<b) LCD_ShowString(30,180,200,16,16,"2 is the winner");
			else LCD_ShowString(30,180,200,16,16,"1=2");
		}
						
	    POINT_COLOR=GREEN;
	    LCD_ShowxNum(10,120,a,4,16,0);
	    LCD_ShowxNum(60,120,b,4,16,0);
		
		temp1=Get_Temprate();	//得到温度值 
		if(temp1<0)
		{
			temp1=-temp1;
			LCD_ShowString(30+10*8,140,16,16,16,"-");	//显示负号
		}else LCD_ShowString(30+10*8,140,16,16,16," ");	//无符号	
        LCD_ShowString(30,140,200,16,16,"TEMPERATE: 00.00C");	
        adcx=temp1/100;		
		LCD_ShowxNum(30+11*8,140,adcx,2,16,0);		//显示整数部分
		LCD_ShowxNum(30+14*8,140,temp1%100,2,16, 0X80);	//显示小数部分
		
		if(USART_RX_STA&0x8000)
		{					   
			
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("篮球计分器\r\n");
				printf("综合设计\r\n\r\n");
			}
			if(times%10==0) printf("\r\n%f\r\n",(double)(adcx));  
			delay_ms(10);   
		}
}
}

四、实验结果:

 该图为初始页面,时分秒均为零,比分为0:0,同时进行温度采集

该图为给1队加1分,故显示1:0

 

 该图为在1:0基础上给1队加2分,故显示3:0

该图为在3:0基础上给1队加3分,故显示6:0,同时红灯亮起

 

该图为在6:0基础上给2队加1分,故显示6:1

 

该图为在6:1基础上给2队加2分,故显示6:3

 

该图为在6:3基础上给2队加3分,故显示6:6

 

 

以上两张图为切换背景颜色

 

该图为在6:6基础上给1队减1分,故显示5:6

 

该图为在5:6基础上给2队减1分,故显示5:5

 

该图为正常计时模式

该图为0.1倍速计时模式

 

该图为在上图时间下按下暂停键的结果,可以看到温度仍在采集,但时间不改变

 

该图为按下提前终止比赛键,当前比分为5:5,故输出1=2

 

该图为按下提前终止比赛键,当前比分为11:5,故输出1 is the winner

 

该图为按下提前终止比赛键,当前比分为11:26,故输出2 is the winner

 

该图为通过串口调试助手看到的取整后的温度值

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值