一、实验要求:
基于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
该图为通过串口调试助手看到的取整后的温度值