篮球计时计分控制系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学习情境1 篮球计时计分控制系统的设计
之整体模块系统设计
☆点名,复习
1、简述数码管动态显示技术。
2、矩阵键盘的硬件电路设计以及软件程序代码设计
3、简述74HC573的基本功能以及各引脚的作用。
4、简述74HC154的基本功能以及各引脚的作用。
☆新课讲授
前面我们分别设计好了计时模块(24秒计时和单节时间计时)和计分模块,把各个模块综合起来就构成了篮球计时计分控制系统。
因为各个子模块都经过了调试,软件和硬件都没有什么问题,在整合这些子模块时只需做些简单的修改。
1.4 整机硬件电路设计
整机硬件电路具体如下图所示:
1.5 整机软件设计(完整C程序代码)
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
/*--------数码管显示代码--------*/
ucharcodeshuma[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83, 0xC6,0xA1,0x86,0x8E,0xBF,0xFF}; //共阳
//ucharcodeshuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40}; //共阴
uchar Attack_time,Temp,m_count;
uchar part; //定义第几节的变量。
第1,2,3,4节
uchar Key_Num=16, Pro_Key_Num=9;
uint count1,count2,t_count; //时间全局变量,count1,count2用于在中断函数中记录中、
//断次数
sbit attack_begin=P3^0; // 24秒进攻开始按键K1
sbit attack_pause=P3^1; // 24秒进攻暂停按键K2
int Game_time1,Game_time2; //定义每节时间的分钟和秒钟的时间变量
sbit key_start=P3^2; // 比赛开始按键
sbit item_dec=P3^3; // 比赛减分按键
sbit item_add=P3^4; // 设置比赛为第1,2,3,4节,篮球比赛有4节,每节12分钟
bit flag,flag1,first_end; // 定义1秒的标志位,flag,flag1分别用于表示T0和T1定//时
器产生了1秒的时间
bit game_over,OR_ZERO,k1,k2,k3,k4,l,p,h; // 定义一些标志位
uchar Temp_attack_time,dis_time1,dis_time2;
uint attack_sec_shi; // 进攻秒十位
uint attack_sec_ge; // 进攻秒个位
uint game_point1,game_point2; //比赛比分变量
uint Tgame_sec_ge; // 单节比赛时间秒钟个位
uint Tgame_sec_shi; // 单节比赛时间秒钟十位
uint Tgame_min_ge; // 单节比赛时间分钟个位
uint Tgame_min_shi; // 单节比赛时间分钟十位
/*--------子程序声明--------*/
void delay(uint K); //延时子程序
void Display(); // 显示子程序
void Attack_key_event(); //进攻24秒子程序
void Pause_key_event(); // 暂停子程序
void Initialization(); //初始化子程序
void Game_start(); //单节比赛启动子程序,K3按键处理子程序
void Increase_part(); //单节自加子程序,每节结束时,单节变量part自动加1 void Key_Scan() ; // 矩阵键盘扫描子程序
void Add_point(); // 加分按键处理子程序
void Dec_point(); //减分按键处理子程序/
/*--------主程序--------*/
void main(void)
{
Initialization();
//P2=0xff;
while(1)
{
Display(); // 显示子程序
Game_start(); //篮球比赛开始子程序
Attack_key_event(); //24秒进攻开始子程序
Pause_key_event(); // 暂停子程序
Increase_part(); // 比赛每节自加处理子程序
//Key_Scan(); // 矩阵键盘扫描子程序
Add_point(); // 加分按键处理子程序
Dec_point(); //减分按键处理子程序
}
}
/*--------T0中断服务程序--------*/
void T0_int()interrupt 1 // 使用定时器T0,方式1,定时1s
{
TH0 = -50000/256; // 设置定时器初值(定时50ms)TL0 = -50000%256;
count1++;
if(count1==10) // 循环20次
{
count1=0;
flag=1;
}
}
/*--------T1中断服务程序--------*/
void T1_int()interrupt 3 // 使用定时器T1,方式1,定时1s
{
TH1 = -50000/256; // 设置定时器初值(定时50ms)
TL1 = -50000%256;
count2++;
if(count2==10) // 循环20次
{
count2=0;
flag1=1;
}
}
/*--------延时子程序--------*/
void delay(uint K)
{
uint i,j;
for(i=K;i>0;i--)
for(j=120;j>0;j--);
}
/*---------24秒进攻按键(attack_begin,k1按键P3.0口)处理子程序--------*/ void Attack_key_event()
{
if(attack_begin==0) //判断进攻按键是否按下
{delay(15);} //按键消抖
if(attack_begin==0) //再次判断暂停健是否按下。
{
k1=1; //k1为进攻按键按下标志
TR0=1; // 开T0计时
if(k2==0) //没有按下暂停键。
{ Attack_time=24; }
if(k2==1&&Attack_time==0) //有按下暂停键。
{ Attack_time=24; }
}
if(k1==1&&flag==1)
{
flag=0;
Attack_time--;
OR_ZERO=1;
}
if(OR_ZERO==1&&Attack_time==0)
{
OR_ZERO=0;
if(flag==1)
{
flag=0;
Attack_time=24;
}
TR0=0;
}
}
//*----------显示子程序---------*//
void Display()
{
//定义第几节的数码算法。
第1,2,3,4节
int j;
uchar Group1_ge,Group1_shi,Group1_bai,Group2_ge,Group2_shi,Group2_bai;
//uchar KeyNO;
Temp_attack_time=Attack_time;
attack_sec_shi=Temp_attack_time/10;
attack_sec_ge=Temp_attack_time%10;
dis_time1=Game_time1;
dis_time2=Game_time2;
Tgame_sec_shi=dis_time1/10;
Tgame_sec_ge=dis_time1%10;
Tgame_min_ge=dis_time2%10;
Tgame_min_shi=dis_time2/10;
Group1_bai= game_point1/100;
Group1_shi= game_point1%100/10;
Group1_ge = game_point1%100%10;
Group2_bai= game_point2/100;
Group2_shi= game_point2%100/10;
Group2_ge = game_point2%100%10;
for(j=0;j<10;j++)
{
P2=0x0f; //位选,选中百位数对应的那个数码管
P0=shuma[Group1_bai]; // 段选,把百位数的字形码送到上面选通的数码管中delay(1);
P2=0x01; //位选,选中十位数对应的那个数码管
P0=shuma[Group1_shi]; // 段选,把十位数的字形码送到上面选通的数码管中delay(1);
P2=0x02; //位选,选中个位数对应的那个数码管
P0=shuma[Group1_ge]; // 段选,把个位数的字形码送到上面选通的数码管中delay(1);
P2=0x03; //位选,选中百位数对应的那个数码管
P0=shuma[Group2_bai]; // 段选,把百位数的字形码送到上面选通的数码管中
delay(1);
P2=0x04; //位选,选中十位数对应的那个数码管
P0=shuma[Group2_shi]; // 段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x05; //位选,选中个位数对应的那个数码管
P0=shuma[Group2_ge]; // 段选,把个位数的字形码送到上面选通的数码管中
delay(1);
P2=0x0b; //位选,选中个位数对应的那个数码管第6个数码管
P0=shuma[Tgame_min_ge]; //段选,把个位数的字形码送到上面选通的数码管中
delay(1);
P2=0x0a; //位选,选中十位数对应的那个数码管第5个数码管
P0=shuma[Tgame_min_shi]; //段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x09; //位选,选中十位数对应的那个数码管第4个数码管
P0=shuma[16]; //段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x08; //位选,选中十位数对应的那个数码管- 第3个数码管
P0=shuma[16]; //段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x07; //位选,选中个位数对应的那个数码管- 第1个数码管
P0=shuma[Tgame_sec_ge]; //段选把个位数的字形码送到上面选通的数码管中
delay(1);
P2=0x06; //位选,选中十位数对应的那个数码管 1 第2个数码管
P0=shuma[Tgame_sec_shi]; //段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x0c; //位选,选中个位数对应的那个数码管
P0=shuma[attack_sec_ge];// 段选,把个位数的字形码送到上面选通的数码管
中
delay(1);
P2=0x0d; //位选,选中十位数对应的那个数码管
P0=shuma[attack_sec_shi]; //段选,把十位数的字形码送到上面选通的数码管中
delay(1);
P2=0x0e; //位选,
P0=shuma[part]; //段选,
delay(1);
}
}
//*----------暂停子程序---------*//
void Pause_key_event()
{
if(attack_pause==0)
{delay(40);} //按键消抖
if(attack_pause==0) //再次判断暂停健是否按下。
{
k2=1; //k2为暂停按键按下标志位。
TR0=0;
TR1=0;
}
}
/*--------初始化子程序--------*/
void Initialization()
{
TMOD=0x11; // 中断初始化
TH0 = -50000/256; // 设置定时器T0初值(定时50ms)TL0 = -50000%256;
TH1= -50000/256; // 设置定时器T1初值(定时50ms)TL1 = -50000%256;
EA=1; // 开总中断
ET0=1; // T0允许
ET1=1; // T1允许
part=1;
Attack_time=24;
Game_time1=3;
Game_time2=0;
game_point1=106;
game_point2=104;
}
/*--------单节比赛启动子程序,K3按键处理子程序--------*/
void Game_start()
{
if(key_start==0) //判断比赛开始按键K3是否按下?
{delay(40);} // 消抖
if(key_start==0) //再次判断比赛开始按键K3是否按下?
{ k3=1; //设置比赛开始标志位K3
TR1=1;
if(k2==0) //未按下暂停按键。
{
if(flag1==1) return;
{
flag1=0;
Game_time1=2;
Game_time2=59;
}
}
else if(k2==1&&Game_time1==3&&Game_time2==0) {
if(flag1==1) return;
{
Game_time1=2;
Game_time2=59;
}
}
}
if(k3==1&&flag1==1)
{
flag1=0;
p=1;
m_count++; //1秒钟累加器,60秒为1分钟
Game_time2--;
if(Game_time2<0)
{
Game_time2=59;
}
}
if( p==1&&m_count==60)
{
if(Game_time1!=0)
{
Game_time1--;
Game_time2=59;
}
else if(Game_time1==0) //记录每节最后一分钟的秒钟。
{
Game_time1--;
if(Game_time1<0)
{
TR1=0;
first_end=1; //每节结束标志
}
Game_time1=3;
Game_time2=0;
}
p=0;
m_count=0;
}
}
/*-----------------------单节自加子程序,每节结束时,单节变量part自动加1---------------------*/
void Increase_part()
{
if(first_end==1)
{
first_end=0;
if(++part>4)
{part=1;}
}
}
/*-----------------矩阵键盘扫描子程序-------------------------*/
void Key_Scan()
{
uchar key_temp;
P1=0x0f; //高4位置1,放入4行
delay(1);
//按键后00001111将变成0000XXXX,X中有1个为0,其余3个仍能为1.
key_temp=P1^0x0f; //判断按键发生在0~3列中的哪一列。
switch(key_temp)
{
case 1:Key_Num=0;break;
case 2:Key_Num=1;break;
case 4:Key_Num=2;break;
case 8:Key_Num=3;break;
default:Key_Num=16; //说明没有按键按下
}
P1=0xf0; //低四位置零,放入四列
delay(1);
//按键后11110000将变成XXXX0000,X中有1个为0,其余3个仍能为1.
key_temp= P1>>4^0x0f; //将高4位移到低4位,并将其中唯一的0变为1,其余为0
switch(key_temp)
{
case 1:Key_Num+=0;break; //对0~3行分别附加起始值0,4,8,12
case 2:Key_Num+=4;break;
case 4:Key_Num+=8;break;
case 8:Key_Num+=12;
}
}
/*---------------加分按键处理子程序--------------------*/
void Add_point()
{
// bit key;
Key_Scan();
switch(Key_Num)
{
case 12: delay(100);
if (Key_Num==12)
{game_point1++; }
break;
case 13: delay(100);
if (Key_Num==13)
{game_point1=game_point1+2; } break;
case 14: delay(100);
if (Key_Num==14)
{game_point1+=3; }
break;
case 10: delay(100);
if (Key_Num==10)
{game_point2++;}
break;
case 11: delay(100);
if (Key_Num==11)
{game_point2+=2;}
break;
case 15: delay(100);
if (Key_Num==15)
{game_point2+=3;}
break;
}
}
/*---------------减分按键处理子程序--------------------*/ void Dec_point()
{
Key_Scan();
switch (Key_Num)
{
case 8: delay(200);
if (Key_Num==8)
{game_point1--;}
break;
case 9: delay(200);
if (Key_Num==9)
{game_point2--;}
break;
}
}。