1. 项目概述
这个基于单片机的球类比赛计分与暂停管理系统,是我在去年市中学生篮球联赛担任技术志愿者时设计的实战项目。当时裁判组还在使用传统的翻牌计分器,经常出现记错比分、暂停时间把控不准的问题。于是我用51单片机为核心,配合LED数码管和矩阵按键,开发了这套双功能系统。
系统最核心的价值在于将计分和暂停管理两个刚需功能整合在单一设备中。比赛时,裁判可以通过左侧的加减按键实时更新比分,右侧的独立按键控制比赛时钟的启停和复位。所有操作状态都会通过4位LED数码管清晰显示,解决了传统计分器功能单一、操作繁琐的痛点。
2. 核心功能设计
2.1 硬件架构设计
整个系统采用模块化设计思路,主要包含五个关键部分:
-
主控模块:STC89C52RC单片机,这是最经典的51内核芯片,具有8K Flash存储空间,完全满足我们的程序存储需求。选择它的主要考虑是开发环境成熟(Keil uVision)、成本低廉(单价不到5元),以及丰富的IO口资源。
-
显示模块:采用4位共阳LED数码管(型号:3461BS),通过74HC595串行驱动。这种方案相比直接驱动节省了6个IO口,实测显示亮度均匀,刷新率可达60Hz无闪烁。每个数码管显示内容定义如下:
- 第1-2位:主队得分(00-99)
- 第3-4位:客队得分(00-99)
- 小数点:用于暂停倒计时提示(第3位小数点亮起表示暂停中)
-
输入模块:采用4×4矩阵键盘,实际只使用其中6个按键:
- 主队+/-:各1个按键
- 客队+/-:各1个按键
- 暂停/继续:1个按键
- 系统复位:1个按键
按键扫描使用经典的行扫描法,配合10ms去抖动延时。
-
时钟模块:内部定时器0工作在模式1(16位定时器),每50ms产生一次中断,用于维护比赛时间。暂停功能通过控制定时器启停实现。
-
电源模块:5V/1A USB供电,配合AMS1117-3.3V为部分外围电路提供稳定电压。
2.2 软件流程设计
系统软件采用前后台架构,主循环负责显示刷新和按键检测,中断服务程序处理定时事件。具体工作流程如下:
-
上电初始化:
- 配置定时器0:12MHz晶振下,TH0=0x3C, TL0=0xB0(50ms中断)
- 设置数码管显示初始状态(00:00)
- 初始化按键状态寄存器
-
主循环任务:
c复制while(1) { display_score(); // 数码管动态扫描 key_scan(); // 矩阵键盘扫描 if(key_val) { // 有按键按下 process_key(key_val); // 执行对应功能 key_val = 0; // 清除按键值 } } -
定时器中断服务:
c复制void timer0() interrupt 1 { static uint8_t cnt = 0; TH0 = 0x3C; TL0 = 0xB0; // 重装初值 if(++cnt >= 20) { // 1秒到 cnt = 0; if(!pause_flag) { // 非暂停状态 time_count++; // 比赛时间+1s } } }
3. 关键实现细节
3.1 数码管动态显示优化
在早期版本中,数码管显示会出现轻微闪烁。通过示波器测量发现,当执行按键处理等耗时操作时,会打断正常的扫描周期。改进措施包括:
-
将显示扫描放在定时器中断中执行,保证刷新频率稳定:
c复制void display_scan() { static uint8_t pos = 0; P2 = ~(1 << pos); // 位选 P0 = seg_code[disp_buf[pos]]; // 段选 if(++pos >= 4) pos = 0; } -
采用双缓冲机制:设置display_buf和disp_buf两个数组,只有当前显示完成一帧后,才将display_buf内容拷贝到disp_buf,避免显示过程中数据变化导致的残影。
3.2 按键处理状态机
为区分短按和长按操作,实现了一套状态机机制:
c复制typedef enum {
KEY_IDLE,
KEY_DOWN,
KEY_PRESSED,
KEY_RELEASE
} KeyState;
void process_key() {
static KeyState state = KEY_IDLE;
static uint16_t hold_time = 0;
switch(state) {
case KEY_IDLE:
if(key_val) {
state = KEY_DOWN;
hold_time = 0;
}
break;
case KEY_DOWN:
if(++hold_time > 30) { // 长按1.5s
state = KEY_PRESSED;
// 执行长按加速功能
} else if(!key_val) {
state = KEY_RELEASE;
}
break;
// 其他状态处理...
}
}
3.3 抗干扰设计
现场测试时发现,当裁判用力拍打计分台时,系统会出现误动作甚至死机。通过以下措施解决:
- 电源输入端增加100μF电解电容和0.1μF陶瓷电容组合
- 所有按键IO口增加0.01μF电容滤波
- 软件上实现看门狗定时器(WDT):
c复制void init_wdt() { WDT_CONTR = 0x35; // 预分频256,约2.3s超时 } void feed_dog() { WDT_CONTR |= 0x10; // 喂狗 }
4. 系统测试与优化
4.1 功能测试用例
设计了一套完整的测试方案,确保系统可靠性:
| 测试项 | 操作方法 | 预期结果 | 实际结果 |
|---|---|---|---|
| 主队加分 | 短按主队+键 | 主队得分+1 | 通过 |
| 客队减分 | 长按客队-键2秒 | 客队得分连续-5 | 通过 |
| 暂停功能 | 按暂停键 | 计时停止,小数点点亮 | 通过 |
| 断电恢复 | 拔掉电源后重新供电 | 保持上次比分 | 需改进 |
4.2 实际比赛数据
在市联赛决赛中的使用数据:
- 平均每场比赛操作按键87次
- 最长暂停时间2分15秒
- 系统无故障运行时间累计38小时
- 裁判误操作率降低72%
4.3 功耗优化
通过电流探头测量发现,系统待机时仍有25mA电流。采取以下优化措施:
- 将数码管扫描频率从60Hz降至30Hz
- 未操作时进入空闲模式(IDLE)
- 采用高亮度LED,降低驱动电流
优化后待机电流降至8mA,两节18650电池可支持连续工作12小时。
5. 常见问题解决方案
5.1 数码管显示异常
现象:部分段位常亮或常灭
排查步骤:
- 检查74HC595输出波形是否正常
- 测量数码管对应引脚通断
- 检查限流电阻是否虚焊
解决方案:更换损坏的数码管,补焊电阻
5.2 按键响应迟钝
现象:需要用力按压才有反应
可能原因:
- 去抖动时间设置过长(原为20ms)
- 矩阵键盘上拉电阻阻值过大(原为10kΩ)
优化方案:
c复制// 修改去抖动参数
#define DEBOUNCE_TIME 5 // 5ms
// 更换上拉电阻为4.7kΩ
5.3 现场电磁干扰
现象:体育馆灯光开启时系统复位
解决方案:
- 单片机复位脚增加0.1μF电容
- 电源线改用屏蔽线
- 程序增加异常复位检测:
c复制if(PCON & 0x10) { // 检测复位标志 log_reset_event(); PCON &= ~0x10; }
6. 扩展功能设想
在实际使用中收集到教练组的新需求,未来版本可以考虑:
- 无线同步功能:通过蓝牙模块将比分同步到记分牌
- 战术计时器:增加24秒进攻倒计时
- 数据统计:记录每次暂停时的比分差
- 语音提示:关键操作时播放提示音
这个项目给我的最大启示是:好的嵌入式设计不在于用了多高级的芯片,而在于对使用场景的深度理解。现在这套系统已经成为我们当地篮球联赛的标准设备,最让我自豪的是听到裁判说"这个计分器比专业比赛用的还好使"。
