1、基于单片机的球类比赛专用计分与暂停管理系统设计
点击链接下载protues仿真设计资料:https://download.csdn.net/download/m0_51061483/91738505
1.1、系统概述
球类比赛(如篮球、排球、手球、羽毛球团体赛等)在比赛过程中通常需要实时记录双方得分,并对暂停次数进行严格管理。尤其在正式比赛环境下,裁判员或记录台需要快速、准确地进行加分、减分以及暂停控制,同时必须避免误操作导致比分错误。传统的人工记录方式存在反应慢、易出错、无法联动显示等缺点,因此设计一套基于单片机的专用计分与暂停管理系统具有较高的实用价值。
本系统以单片机为控制核心,采用LED数码管作为显示终端,结合按键输入实现比分控制与暂停管理。系统能够独立记录主队与客队比分,支持双方分别加分与减分,并实时显示在LED数码管上。同时系统为双方各自设置6次暂停机会,按键触发暂停后自动扣减对应队伍暂停次数并显示剩余次数。在暂停状态下,系统会将加分、减分按键锁定失效,从逻辑上避免在暂停期间误操作导致比分变化,只有在退出暂停后才能恢复计分操作,从而保证比赛记录的严谨性。
系统整体可分为硬件电路设计和软件程序设计两部分。硬件方面包含单片机最小系统、电源模块、按键输入模块、LED数码管显示模块(含驱动)、蜂鸣器或提示模块(可选)、暂停指示模块(LED指示灯,可选)等。软件方面采用模块化结构,包含按键扫描与消抖、比分管理、暂停管理、显示刷新、状态机控制、异常保护(比分下限、暂停次数下限)等功能模块。
该系统适用于学校体育比赛、业余联赛、训练计分、裁判辅助器材等场景,具备成本低、可靠性高、操作简单、可扩展性强的特点。通过本设计可以系统掌握单片机I/O控制、数码管动态扫描、按键消抖、多状态机逻辑设计以及数据结构化管理等综合技术能力。
2、系统功能设计
2.1、双方独立加分、减分与数码管实时显示
系统提供两组独立按键,分别对应主队与客队的加分与减分操作。每次按键动作都将直接影响对应队伍的得分值,系统内部对比分进行运算与边界判断,并将结果实时显示在LED数码管上。
2.1.1、加分功能
- 主队加分键按下:主队得分 +1(或可扩展 +2/+3)
- 客队加分键按下:客队得分 +1(或可扩展 +2/+3)
为了适应不同球类项目需求,本系统默认设计为“每次按下加1分”,因为该方案实现简单且能兼容多种比赛规则。若在篮球比赛中需要加2分或3分,可扩展为多按键或长按模式实现不同分值加分。
2.1.2、减分功能
减分按键主要用于纠错,例如误按加分或裁判判罚更正。系统对减分操作进行保护:
- 当得分大于0时才允许减分
- 当得分为0时减分无效,避免出现负数比分
2.1.3、数码管显示方案
数码管显示可采用如下布局:
- 左侧两位显示主队比分(00~99)
- 右侧两位显示客队比分(00~99)
同时为了显示暂停次数,还需额外显示位: - 主队暂停次数1位显示(0~6)
- 客队暂停次数1位显示(0~6)
因此系统可采用6位或8位数码管设计,例如:
- 6位显示:
主队比分(2位) + 主队暂停(1位) + 客队暂停(1位) + 客队比分(2位)
示例显示: 12 3 2 08可理解为:主队12分、主队剩余暂停3次、客队剩余暂停2次、客队8分
也可以用8位数码管显示更多信息,如比赛时间、节数等(属于扩展功能)。
2.2、双方各6次暂停机会管理与数码管显示
在正式比赛规则中,暂停次数通常有限且由裁判或记录台进行控制。本系统为双方分别设置6次暂停机会,暂停次数独立计数并实时显示。
2.2.1、暂停触发方式
系统设计暂停按键:
- 主队暂停键:进入主队暂停状态,主队暂停次数-1
- 客队暂停键:进入客队暂停状态,客队暂停次数-1
暂停次数减少仅在“未处于暂停状态且剩余次数>0”的条件下生效,避免重复扣减。
2.2.2、暂停次数边界保护
暂停次数最小为0:
- 当暂停次数为0时,再按暂停键无效
- 可通过蜂鸣器发出短促提示音(可选)表示暂停次数已用尽
- 数码管显示0,明确提示剩余次数
2.2.3、暂停显示方式
暂停次数显示需要直观明确,建议放置在比分显示之间或旁边,使记录员一眼能看到:
- 主队暂停剩余
T1 - 客队暂停剩余
T2
显示更新与比分同步刷新,避免出现显示延迟。
2.3、暂停期间加分、减分按键失效防误操作
防误操作是本系统最关键的特色功能之一。比赛暂停期间现场人员可能进行交流、整理记录或调整设备,此时若误触加分/减分键,会导致比分变化并影响比赛公平性。因此系统在进入暂停状态后必须立即锁定计分按键。
2.3.1、按键锁定逻辑
当系统处于暂停状态时:
- 主队加分键无效
- 主队减分键无效
- 客队加分键无效
- 客队减分键无效
仅允许: - 退出暂停键(或再次按暂停键恢复)
- 其他功能键(如复位键、模式键,视设计扩展)
这种逻辑能够从软件层面保证暂停期间比分不会因误触而被改动。
2.3.2、暂停状态提示
为了让操作者明确系统已进入暂停状态,可设计提示方式:
- 数码管某一位显示
P或-闪烁(七段码可用自定义段码模拟) - 暂停指示灯亮起(硬件LED)
- 蜂鸣器提示“滴”一声进入暂停,“滴滴”退出暂停(可选)
提示机制使操作者能快速确认当前状态,避免因不知道已暂停而造成疑惑。
3、电路设计
3.1、硬件总体结构说明
系统电路由以下模块构成:
1)单片机最小系统模块
2)电源模块
3)按键输入模块(双方加分/减分/暂停/退出等)
4)LED数码管显示模块(动态扫描驱动)
5)数码管驱动与限流模块
6)暂停指示模块(可选)
7)蜂鸣器提示模块(可选)
硬件设计的核心目标是:
- 显示稳定、亮度均匀
- 按键输入可靠、无抖动误触
- 单片机IO资源合理分配
- 供电稳定、抗干扰能力强
- 满足比赛现场长时间运行需求
3.2、单片机最小系统模块
单片机作为控制核心,负责:
- 读取按键输入并做消抖处理
- 维护主队/客队比分与暂停次数数据
- 控制数码管动态扫描显示
- 判断暂停状态并锁定计分按键
- 控制蜂鸣器与指示灯(若有)
最小系统包含:
设计要点:
- 晶振布局靠近单片机时钟引脚,走线短
- 复位电路应保证上电时复位时间足够
- 关键IO口尽量不要悬空,未用引脚可配置为上拉输入减少干扰
- 数码管扫描频率要足够高(一般>100Hz),避免肉眼闪烁
3.3、电源模块
系统一般使用5V供电,供电来源可为:
- USB 5V供电
- 9V/12V适配器 + 稳压模块(7805或DC-DC)
电源模块需要保证:
- 数码管驱动电流较大,供电要稳定
- 单片机供电需低噪声
- 按键输入与显示模块共地,避免地线漂移
典型电源设计:
3.4、按键输入模块
按键输入是系统交互核心,本系统按键数量较多,建议采用“独立按键”方式实现高可靠性。
3.4.1、按键功能规划
建议按键包括:
- 主队加分键
H+ - 主队减分键
H- - 主队暂停键
HT - 客队加分键
A+ - 客队减分键
A- - 客队暂停键
AT - 退出暂停/恢复键
RESUME(也可设计为再次按暂停键退出) - 系统复位键
RST(硬件复位或软件复位)
3.4.2、按键硬件连接方式
3.4.3、抗干扰设计
比赛现场可能存在电磁干扰或长线连接导致按键抖动,建议:
- 按键线尽量短
- 增加软件消抖(10ms~20ms稳定判定)
- 关键按键可使用两次确认策略(例如长按1秒进入暂停)以避免误触(可扩展)
3.5、LED数码管显示模块
数码管用于显示比分与暂停次数,是系统最直观的信息输出。
3.5.1、数码管选型
可选择:
- 共阳数码管:段选低电平点亮
- 共阴数码管:段选高电平点亮
推荐使用多位数码管(6位或8位),便于集成显示信息。常见显示布局为6位:
- 位1-位2:主队比分
- 位3:主队暂停次数
- 位4:客队暂停次数
- 位5-位6:客队比分
3.5.2、动态扫描显示原理
由于单片机IO口有限,通常采用动态扫描方式:
- 段选线(a~g, dp)共用
- 位选线逐位轮流使能
- 快速循环刷新,使人眼看到稳定画面
动态扫描优点:
- 节省IO口
- 硬件成本低
- 易于扩展显示位数
扫描频率设计要点:
- 每位点亮时间约1ms~2ms
- 6位扫描周期约6ms~12ms
- 总刷新频率大于80Hz避免闪烁
3.6、数码管驱动与限流模块
数码管段电流与位电流较大,单片机IO口直接驱动可能导致:
- 亮度不足
- IO口过流损坏
- 显示不均匀
因此应加入驱动电路:
典型方案:
- 段选:P0口输出段码,串联限流电阻
- 位选:P2口控制三极管,逐位点亮
这种方式硬件简单且适合教学与快速实现。
3.7、暂停指示模块与蜂鸣器模块(可选)
为了提高系统状态提示能力,可加入:
- 暂停指示LED:暂停时亮
- 蜂鸣器:按键确认音、暂停进入/退出提示音
蜂鸣器驱动建议使用有源蜂鸣器,通过三极管放大控制,避免IO口直接带负载。
暂停LED可直接由IO口驱动并串联限流电阻。
4、程序设计
4.1、软件总体结构与任务调度
软件采用典型嵌入式结构:
- 定时器中断提供系统节拍(1ms)
- 动态扫描显示在中断或主循环高频执行
- 按键扫描每10ms执行一次
- 业务逻辑(计分、暂停)在按键事件触发后执行
- 显示缓存随数据变化实时更新
软件模块划分:
1)系统初始化模块
2)数码管显示驱动模块
3)按键扫描与消抖模块
4)比分管理模块(加分、减分、边界)
5)暂停管理模块(次数扣减、锁定、退出)
6)状态机控制模块(NORMAL/PAUSE)
7)蜂鸣器提示模块(可选)
设计关键点:
- 显示扫描必须稳定,不能被长延时阻塞
- 按键响应必须灵敏且不会误触发
- 暂停状态下必须彻底锁定计分按键
- 数据结构统一管理双方比分与暂停次数,便于维护和扩展
4.2、系统初始化模块
初始化内容包括:
- IO口方向设置
- 定时器初始化(用于数码管扫描与系统节拍)
- 数码管显示缓冲区清空
- 分数与暂停次数初始化(比分=0,暂停=6)
- 默认模式为正常计分模式
初始化完成后开始主循环运行。
4.3、数码管动态扫描显示模块设计
该模块负责将系统数据转为数码管段码并按位刷新。
4.3.1、段码编码
数码管显示数字0~9需要段码表,例如:
- 共阴数码管:1表示点亮
- 共阳数码管:0表示点亮(需要取反)
此外,系统可能需要显示暂停状态提示符,可用如下方式实现:
- 用“-”表示暂停:点亮g段
- 用“P”近似表示暂停:点亮a、b、e、f、g段(近似字母P)
由于七段数码管无法完美显示字母,通常用“-”闪烁更直观。
4.3.2、显示缓冲区设计
建议使用数组保存每位显示的数字或段码:
disp[0]主队十位disp[1]主队个位disp[2]主队暂停disp[3]客队暂停disp[4]客队十位disp[5]客队个位
这样在刷新显示时只需读取缓冲区即可,提高显示效率。
4.4、按键扫描与消抖模块设计
按键扫描策略:
- 每10ms扫描一次按键状态
- 连续检测到按下3次以上认为有效
- 等待松手后再返回按键事件
这种方式可有效避免机械抖动带来的误触发。
按键事件设计为:
KEY_H_ADDKEY_H_SUBKEY_H_TOKEY_A_ADDKEY_A_SUBKEY_A_TOKEY_RESUME
按键模块输出事件码,业务逻辑模块根据事件码执行对应动作,使程序结构清晰。
4.5、比分管理模块设计
比分管理模块主要处理:
- 加分
- 减分
- 边界保护(0~99)
- 暂停状态下拒绝操作
4.5.1、加分逻辑
- 若未暂停:得分+1
- 得分最大可设为99(数码管两位显示限制)
- 若达到最大值则不再增加(可蜂鸣提示可选)
4.5.2、减分逻辑
- 若未暂停:得分-1
- 若得分为0则不再减少
- 防止出现负分
比分管理要保证任何情况下比分不会越界,这是系统可靠性的基本要求。
4.6、暂停管理模块设计
暂停管理模块负责:
- 控制系统进入暂停状态
- 扣减对应队伍暂停次数(最多6次)
- 暂停期间锁定计分按键
- 退出暂停恢复正常模式
4.6.1、暂停进入条件
- 当前处于正常模式
- 对应队伍暂停次数>0
- 按下暂停键
进入暂停后:
pause_flag=1pause_owner=主队/客队- 对应暂停次数-1
- 点亮暂停指示灯或数码管闪烁提示
4.6.2、暂停退出条件
- 按下退出暂停键
- 或再次按下暂停键(复用按键退出)
退出后: pause_flag=0- 恢复计分按键有效
4.6.3、暂停期间按键屏蔽策略
软件层屏蔽的实现方式:
- 在按键事件处理函数中判断
pause_flag - 若为暂停状态且事件为加/减分,则直接丢弃
这种策略简单可靠,同时便于扩展更多“暂停期间禁止操作”的规则。
4.7、状态机控制模块设计
系统至少包含两种状态:
NORMAL:正常计分状态PAUSE:暂停状态
状态机让系统逻辑更清晰:
- 在NORMAL状态才允许计分按键
- 在PAUSE状态只允许退出暂停、复位等按键
状态机还可扩展更多状态,如:
- RESET确认状态
- 设置模式(设置比分或暂停次数)
- 比赛结束状态
这些都可在后续扩展中加入,而不破坏核心结构。
5、核心程序示例(模块化代码)
5.1、全局变量与数据结构
#include <reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
// 数码管段码表(共阴,a~g,dp:dp为bit7)
u8 code SEG_TAB[11] = {
0x3F, //0
0x06, //1
0x5B, //2
0x4F, //3
0x66, //4
0x6D, //5
0x7D, //6
0x07, //7
0x7F, //8
0x6F, //9
0x40 //10: '-' 仅g段
};
// 假设段选接P0,位选接P2(具体依硬件而定)
#define SEG_PORT P0
#define DIG_PORT P2
// 按键(低电平按下)
sbit KEY_H_ADD = P3^0;
sbit KEY_H_SUB = P3^1;
sbit KEY_H_TO = P3^2;
sbit KEY_A_ADD = P3^3;
sbit KEY_A_SUB = P3^4;
sbit KEY_A_TO = P3^5;
sbit KEY_RES = P3^6; // 退出暂停
// 数据:比分与暂停次数
u8 score_h = 0;
u8 score_a = 0;
u8 timeout_h = 6;
u8 timeout_a = 6;
// 状态
bit pause_flag = 0; // 0正常 1暂停
u8 pause_owner = 0; // 0无 1主队 2客队
// 显示缓冲区(6位)
u8 disp_buf[6] = {0};
// 1ms节拍
volatile u16 ms_tick = 0;
volatile bit flag_10ms = 0;
volatile bit flag_500ms = 0;
volatile bit blink = 0;
5.2、定时器初始化与中断(扫描与节拍)
void Timer0_Init_1ms(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = (65536 - 1000) / 256; // 12MHz下近似
TL0 = (65536 - 1000) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void Timer0_ISR(void) interrupt 1
{
static u8 scan_id = 0;
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
ms_tick++;
// 每10ms用于按键扫描
if(ms_tick % 10 == 0) flag_10ms = 1;
// 500ms用于暂停闪烁提示
if(ms_tick % 500 == 0) { flag_500ms = 1; blink = !blink; }
// 数码管动态扫描(1ms扫描一位)
DIG_PORT = 0xFF; // 关闭所有位(假设低电平使能,实际按硬件调整)
SEG_PORT = 0x00;
// 输出段码
SEG_PORT = SEG_TAB[disp_buf[scan_id]];
// 输出位选(示例:scan_id对应位选,需按硬件位选编码表调整)
DIG_PORT = ~(1 << scan_id);
scan_id++;
if(scan_id >= 6) scan_id = 0;
}
5.3、显示缓冲区更新模块
void UpdateDisplayBuffer(void)
{
// 主队比分两位
disp_buf[0] = score_h / 10;
disp_buf[1] = score_h % 10;
// 暂停次数
disp_buf[2] = timeout_h;
disp_buf[3] = timeout_a;
// 客队比分两位
disp_buf[4] = score_a / 10;
disp_buf[5] = score_a % 10;
// 暂停状态闪烁提示:中间两位显示'-'
if(pause_flag && blink)
{
disp_buf[2] = 10;
disp_buf[3] = 10;
}
}
5.4、按键扫描与消抖模块
u8 Key_ReadRaw(void)
{
if(KEY_H_ADD == 0) return 1;
if(KEY_H_SUB == 0) return 2;
if(KEY_H_TO == 0) return 3;
if(KEY_A_ADD == 0) return 4;
if(KEY_A_SUB == 0) return 5;
if(KEY_A_TO == 0) return 6;
if(KEY_RES == 0) return 7;
return 0;
}
u8 Key_Scan(void)
{
static u8 last = 0;
static u8 cnt = 0;
u8 now = Key_ReadRaw();
if(now == last)
{
if(cnt < 3) cnt++;
}
else
{
cnt = 0;
}
last = now;
if(cnt == 3 && now != 0)
{
while(Key_ReadRaw() == now); // 等待松手
return now;
}
return 0;
}
5.5、比分管理模块(加减分与边界)
void Score_Add(u8 team)
{
if(pause_flag) return; // 暂停期间禁止计分
if(team == 1)
{
if(score_h < 99) score_h++;
}
else
{
if(score_a < 99) score_a++;
}
}
void Score_Sub(u8 team)
{
if(pause_flag) return; // 暂停期间禁止计分
if(team == 1)
{
if(score_h > 0) score_h--;
}
else
{
if(score_a > 0) score_a--;
}
}
5.6、暂停管理模块(次数扣减与锁定)
void Pause_Enter(u8 team)
{
if(pause_flag) return; // 已暂停不重复进入
if(team == 1)
{
if(timeout_h == 0) return;
timeout_h--;
pause_owner = 1;
}
else
{
if(timeout_a == 0) return;
timeout_a--;
pause_owner = 2;
}
pause_flag = 1;
}
void Pause_Exit(void)
{
pause_flag = 0;
pause_owner = 0;
}
5.7、按键事件处理模块
void Key_Process(void)
{
u8 k = Key_Scan();
if(k == 0) return;
switch(k)
{
case 1: Score_Add(1); break; // 主队+
case 2: Score_Sub(1); break; // 主队-
case 3: Pause_Enter(1); break; // 主队暂停
case 4: Score_Add(2); break; // 客队+
case 5: Score_Sub(2); break; // 客队-
case 6: Pause_Enter(2); break; // 客队暂停
case 7: Pause_Exit(); break; // 退出暂停
}
}
5.8、主程序框架
void System_Init(void)
{
score_h = 0;
score_a = 0;
timeout_h = 6;
timeout_a = 6;
pause_flag = 0;
pause_owner = 0;
Timer0_Init_1ms();
UpdateDisplayBuffer();
}
void main(void)
{
System_Init();
while(1)
{
if(flag_10ms)
{
flag_10ms = 0;
Key_Process();
UpdateDisplayBuffer();
}
if(flag_500ms)
{
flag_500ms = 0;
UpdateDisplayBuffer();
}
}
}
6、系统可靠性与扩展优化方向
6.1、按键误触防护与操作体验优化
为了进一步降低误操作,可增加:
- 长按进入暂停:必须按住暂停键1秒才进入
- 双击确认退出暂停:避免误触恢复
- 按键提示音:每次有效按键发出短提示音确认成功
这些措施在比赛现场操作紧张时尤其有效。
6.2、比分与暂停次数掉电记忆(扩展)
可以加入EEPROM存储或掉电保存机制:
- 每次比分变化后延时写入EEPROM
- 上电读取恢复比赛数据
适用于临时断电或移动设备场景。
6.3、显示扩展与更多比赛信息管理(扩展)
若采用8位数码管或LCD,可扩展:
- 比赛计时(倒计时或正计时)
- 节数/局数显示
- 犯规次数管理
- 交换场地提示
这些功能可使系统更接近正式比赛计分台设备。
6.4、通信扩展与无线显示(扩展)
7、总结
基于单片机的球类比赛专用计分与暂停管理系统,围绕比赛记录的核心需求,实现了双方独立加分、减分操作并实时显示在LED数码管上,同时对双方各6次暂停机会进行独立管理与显示。在暂停状态下,系统通过软件逻辑对计分按键进行锁定,使加分、减分按键全部失效,从根本上防止暂停期间误操作导致比分变化,显著提升了比赛计分的严谨性和可靠性。
硬件方面,系统由单片机最小系统、电源模块、按键输入模块、数码管显示与驱动模块、可选蜂鸣器与暂停指示模块构成,结构清晰、成本低廉、易于制作。软件方面采用模块化设计与状态机思想,实现了稳定的数码管动态扫描显示、可靠的按键消抖、比分与暂停次数边界保护、暂停锁定机制等关键功能。
该系统不仅能满足学校与业余比赛的计分需求,也具备良好的扩展空间。通过增加比赛计时、犯规统计、无线同步显示等模块,可进一步升级为功能更完整的比赛信息管理终端,为多种球类比赛提供更高效、更可靠的计分与暂停管理支持。
182