@[TOC]51单片机篮球赛计时计分器
设计要求
- 用七段数码管显示甲队和乙队得分及比赛计时,用按键加分及切换显示。
- 七段数码管有两种显示模式:
模式一:分别用3个(或2个)七段数码管显示甲队和乙队比赛得分;
模式二:用同样的数码管显示每节比赛倒计时及24秒计时(具体可参考篮球比赛规则。
两种显示模式用按键1切换。 - 用按键2-4可对甲队或乙队得分+1、+2、+3分。
项目重点
- 七段数码管驱动控制;
- 按键扫描;
- 定时器使用。
说明
- 单片机型号:普中stc89C52RC
- 使用矩阵键盘,k1-k3分别加1-3分,k4加分对象,k5表示加分模式和计时模式切换
代码部分
起始
#include <REGX52.H>
#include "Delay.h"
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40}; //数码管显示部分
unsigned char Sec=24,Min=15,Hour=0; //计时
unsigned char Sec1,Sec2;
unsigned char Min1,Min2;
unsigned char Hour1,Hour2;
unsigned char flag=1; //标志位
unsigned char WorkMode=1; //工作模式,用来承接flag
unsigned char ScoreMode=1; //ScoreMode=1,A加分 ScoreMode=0,B加分
unsigned char ScoreA=0,ScoreB=0;
unsigned char ScoreA1=0; //球员A得分第1位数字
unsigned char ScoreA2=0; //球员A得分第2位数字
unsigned char ScoreB1=0; //球员B得分第1位数字
unsigned char ScoreB2=0; //球员B得分第2位数字
unsigned char KeyNum; //用来承接按键返回值
矩阵键盘函数
unsigned char MatrixKey()//扫描按键状态
{
unsigned char KeyNumber=0;
P1=0xFF;//全部是高电平
P1_3=0;//测试列
//行
if (P1_7==0) { Delay(20);while(P1_7==0);Delay(20); KeyNumber=1;}
if (P1_6==0) { Delay(20);while(P1_6==0);Delay(20); KeyNumber=5;}
if (P1_5==0) { Delay(20);while(P1_5==0);Delay(20); KeyNumber=9;}
if (P1_4==0) { Delay(20);while(P1_4==0);Delay(20); KeyNumber=13;}
P1=0xFF;//全部是高电平
P1_2=0;
if (P1_7==0) { Delay(20);while(P1_7==0);Delay(20); KeyNumber=2;}
if (P1_6==0) { Delay(20);while(P1_6==0);Delay(20); KeyNumber=6;}
if (P1_5==0) { Delay(20);while(P1_5==0);Delay(20); KeyNumber=10;}
if (P1_4==0) { Delay(20);while(P1_4==0);Delay(20); KeyNumber=14;}
P1=0xFF;//全部是高电平
P1_1=0;
if (P1_7==0) { Delay(20);while(P1_7==0);Delay(20); KeyNumber=3;}
if (P1_6==0) { Delay(20);while(P1_6==0);Delay(20); KeyNumber=7;}
if (P1_5==0) { Delay(20);while(P1_5==0);Delay(20); KeyNumber=11;}
if (P1_4==0) { Delay(20);while(P1_4==0);Delay(20); KeyNumber=15;}
P1=0xFF;//全部是高电平
P1_0=0;
if (P1_7==0) { Delay(20);while(P1_7==0);Delay(20); KeyNumber=4;}
if (P1_6==0) { Delay(20);while(P1_6==0);Delay(20); KeyNumber=8;}
if (P1_5==0) { Delay(20);while(P1_5==0);Delay(20); KeyNumber=12;}
if (P1_4==0) { Delay(20);while(P1_4==0);Delay(20); KeyNumber=16;}
return KeyNumber;
}
数码管显示函数
void Nixie(unsigned char Location,Number)
{
switch (Location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;//Y7 111 LED8
case 2:P2_4=1;P2_3=1;P2_2=0;break;//Y6 110 LED7
case 3:P2_4=1;P2_3=0;P2_2=1;break;//Y5 101 LED6
case 4:P2_4=1;P2_3=0;P2_2=0;break;//Y4 100 LED5
case 5:P2_4=0;P2_3=1;P2_2=1;break;//Y3 011 LED4
case 6:P2_4=0;P2_3=1;P2_2=0;break;//Y2 010 LED3
case 7:P2_4=0;P2_3=0;P2_2=1;break;//Y1 001 LED2
case 8:P2_4=0;P2_3=0;P2_2=0;break;//Y0 000 LED1
}
P0=NixieTable[Number];
Delay(1);
P0=0x00;
}
定时器配置函数
void Timer0Init(void) //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式 低四位清零,高四位不变
TMOD |= 0x01; //设置定时器模式 定时器最低位置一
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
主函数
void main()
{
Timer0Init();
while (1)
{
KeyNum=MatrixKey();
//工作模式1 加分模式
if(WorkMode==1)
{
if(WorkMode==0) break; //如果在模式1(加分)过程中按下检测到工作模式0,
ScoreA1=ScoreA/10; //取出得分个位上的数字
ScoreA2=ScoreA%10; //取出得分十位上的数字
ScoreB1=ScoreB/10;
ScoreB2=ScoreB%10;
Nixie(1,ScoreA1);
Nixie(2,ScoreA2);
Nixie(3,10); //显示“-”
Nixie(4,10);
Nixie(5,10);
Nixie(6,10);
Nixie(7,ScoreB1);
Nixie(8,ScoreB2);
KeyNum=MatrixKey();
//模式1情况下 按下k4切换成给B加分模式
if(KeyNum==4)
{
KeyNum=0;
ScoreMode=~ScoreMode;
}
//模式1 A加分
if(ScoreMode==1)
{
if(KeyNum==5) WorkMode=0; //按下k5,切换计时模式
if(KeyNum==1) //按下k1,加1分
ScoreA += 1;
if(KeyNum==2) //按下k2,加2分
ScoreA += 2;
if(KeyNum==3) //按下k3,加3分
ScoreA += 3;
if(ScoreA>99) //高于99分 归零
ScoreA=0;
KeyNum=0;
}
//模式2 B加分
else
{
if(KeyNum==5) WorkMode=0;
if(KeyNum==1) //按下k2
ScoreB+=1;
if(KeyNum==2)
ScoreB+=2;
if(KeyNum==3)
ScoreB+=3;
if(ScoreB>99)
ScoreB=0;
KeyNum=0;
}
}
//工作模式2,计时
if (WorkMode==0)
{
P2_0=0;
Sec1=Sec/10;
Sec2=Sec%10;
Min1=Min/10;
Min2=Min%10;
Hour1=0;
Hour2=0;
Nixie(1,Hour1);
Nixie(2,Hour2);
Nixie(3,10);
Nixie(4,Min1);
Nixie(5,Min2);
Nixie(6,10);
Nixie(7,Sec1);
Nixie(8,Sec2);
if(KeyNum==5) //按下k5,切换加分模式
WorkMode=1;
}
}
}
定时器函数
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count; //静态变量
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
Sec--;
if(Sec==0)
{
Sec=24;
Min--;
}
if(Min==0&&Sec==0)
{
Min=15;
Sec=24;
}
}
}
留言
小编目前本科在读,小白一枚,代码思路可能不够清晰,期待大家评论区交流OvO