2026寒假练 - 基于RP2350B核心板实现LED与数码管多功能计时器
该项目使用了Thonny软件、MicroPython语言,实现了RP2350B核心板的设计,它的主要功能为:基于RP2350B的LED与数码管多功能计时器。
标签
RP2350B核心板
2026寒假练
LED与数码管多功能计时器
苍白沐
更新2026-03-26
北京理工大学
12

一、所选任务介绍

本次课程设计所选择的任务是开发一个基于RP2350B核心板的LED与数码管多功能计时器。该任务旨在综合运用嵌入式系统开发中的基础知识与核心技术,包括 GPIO 控制、ADC 模拟信号采集、定时器中断管理、动态扫描显示技术、LED 控制方法以及按键识别与状态机设计等内容。通过本项目的实施,需要完成一个具备完整交互逻辑、清晰显示效果和良好运行稳定性的嵌入式应用系统。任务不仅要求实现基础功能,还强调系统整体结构设计能力、软件模块划分能力以及调试与优化能力,具有较强的综合性和实践性。


二、项目介绍

本项目设计并实现了一个支持多种运行模式的双位数字显示系统。系统能够在 0 99 范围内进行数值显示,并通过按键或拨码开关实现模式切换与运行控制。系统包含三种运行模式,分别为递增模式、递减模式和随机模式。在递增模式下,系统每秒自动加一,直到数值达到 99 自动停止;在递减模式下,系统从预设值开始每秒减一,直到减至 0 自动停止;在随机模式下,系统每秒生成一个新的随机数进行显示。双位数码管用于实时显示当前数值,下方 LED 组成的进度条根据数值大小显示比例变化,RGB 灯用于指示当前模式状态,不同模式对应不同颜色。当系统处于暂停状态时,RGB 灯亮度降低以提示当前运行状态。整体系统形成了一个集显示、控制与交互于一体的小型嵌入式应用平台。


三、硬件介绍

本项目的核心控制单元为RP2350B。数码管显示部分采用两位共阴数码管,并通过两个 74HC595 串行移位寄存器进行扩展输出控制。移位寄存器负责将串行数据转换为并行输出,从而控制数码管的段选与位选信号,这种方式有效节省了主控芯片的 IO 资源。系统中使用两颗 WS2812 RGB 灯珠用于模式状态指示,通过单线协议即可实现颜色与亮度控制。进度条部分由 8 个普通 LED 组成,采用查理复用技术,仅使用 4 IO 引脚即可控制 8 LED 的点亮状态,从而提高硬件利用率。按键与拨码开关采用电阻分压方式连接至单个 ADC 引脚,通过不同按键产生不同电压值,实现多按键复用设计。以上硬件共同构成了本系统的完整硬件平台。


四、设计思路

系统整体结构可以分为输入模块、控制模块和输出模块三大部分。输入模块包括 ADC 按键识别与拨码开关检测;控制模块为嵌入式主控芯片内部的软件逻辑与状态机;输出模块包括数码管显示、LED 进度条显示以及 RGB 模式指示灯。系统采用定时器中断加主循环的架构设计,高频显示任务由定时器周期性触发,低频逻辑判断由主循环完成。数码管采用动态扫描方式,每 2ms 刷新一次,通过高速交替点亮两个数码位,实现稳定无闪烁显示。LED 进度条通过查理复用技术轮流点亮对应 LED,利用人眼视觉暂留形成连续亮灯效果。按键识别采用 ADC 电压区间判断方式,并结合软件防抖机制保证识别稳定性。整体设计思路强调模块独立性与功能分离,各模块通过函数接口进行调用,使系统结构清晰、逻辑明确,便于调试与维护。

ADC Control for LED Output-2026-03-19-135154.png


五、关键代码介绍

本项目采用 MicroPython 作为开发语言,Thonny为调试软件。开发过程中通过 USB 串口进行调试,利用串口打印输出系统模式变化、数值变化及运行状态信息,从而辅助判断程序运行情况。软件流程图如下:

mermaid-diagram.png

关键代码部分包括数码管动态扫描函数、ADC 解码函数、按键处理函数以及模式状态机更新函数,这些函数共同构成系统核心逻辑。

1. 数码管动态扫描函数设计与实现

数码管显示模块采用动态扫描方式驱动双位数码管。由于硬件资源有限,本系统通过两个 74HC595 串行移位寄存器扩展输出端口,实现段选与位选信号控制。为了保证显示稳定性与视觉连续性,系统使用定时器周期性中断机制进行扫描刷新。

def _seg_tick(_t):
global _which
if _which == 0:
out16 = _make_out(SEG.get(buf[0], 0), True, False)
else:
out16 = _make_out(SEG.get(buf[1], 0), False, True)
_write16(out16)
_which ^= 1

Timer(-1).init(period=2, mode=Timer.PERIODIC, callback=_seg_tick) # 500Hz

2. ADC 解码函数设计与实现

为节省 IO 资源,本系统将多个按键及拨码开关通过电阻分压网络连接至单一 ADC 引脚。不同按键对应不同电压值,通过 ADC 采样后进行区间匹配判断输入状态。由于 ADC 采样值存在一定波动,系统采用分区判断 + 最小差值匹配 + 容差窗口的算法提高识别精度。

def decode(v):
if v >= NONE_MIN:
return "NONE"

if v < KEY_ZONE_MAX: # KEY优先,只比KEY
best, best_d = None, 10**9
for k in ("KEY1","KEY2","KEY3","KEY4"):
d = abs(v - CODES[k])
if d < best_d: best, best_d = k, d
return best if best_d <= KEY_WIN[best] else "UNKNOWN"

best, best_d = None, 10**9 # SW区,只比SW
for s in ("SW34","SW4","SW3","SW2","SW1"):
d = abs(v - CODES[s])
if d < best_d: best, best_d = s, d
return best if best_d <= TOL_SW else "UNKNOWN"

3. 按键处理函数设计与实现

按键处理采用分层结构设计。第一层由 KeyEngine 类负责完成周期采样、防抖处理以及短按与长按识别;第二层由 handle() 函数根据识别结果执行具体功能逻辑。此种设计将底层信号处理与业务逻辑分离,提高系统可维护性。

class KeyEngine:
def __init__(self):
self.t = time.ticks_ms()
self.stable, self.st_ms = None, 0
self.pressed, self.p_ms, self.long = None, 0, False

def poll(self):
now = time.ticks_ms()
if time.ticks_diff(now, self.t) < SAMPLE_MS: return []
dt = time.ticks_diff(now, self.t); self.t = now

name = decode(read_u16())

if name == self.stable: self.st_ms += dt
else: self.stable, self.st_ms = name, 0

stable = (self.st_ms >= DEBOUNCE_MS)
is_key = stable and (name in ("KEY1","KEY2","KEY3","KEY4"))

ev = []
if is_key:
if self.pressed is None:
self.pressed, self.p_ms, self.long = name, 0, False
if name == self.pressed:
self.p_ms += dt
if (not self.long) and self.p_ms >= LONG_MS:
self.long = True
ev.append(("LONG", name))
else:
if self.pressed is not None and (not self.long):
ev.append(("SHORT", self.pressed))
self.pressed, self.p_ms, self.long = None, 0, False

return ev

4. 模式状态机更新函数设计与实现

系统运行逻辑采用状态机结构设计。状态变量包括当前模式 mode、运行状态 running 以及当前数值 value。主循环通过毫秒计时判断是否达到 1 秒周期,当满足条件时调用 tick_1s() 完成一次状态更新。

def tick_1s():
global value, running
if not running: return
if mode == "UP":
value = value + 1 if value < 99 else 99
if value == 99: running = False
elif mode == "DOWN":
value = value - 1 if value > 0 else 0
if value == 0: running = False
else:
value = random.randint(0, 99)
show()


六、功能展示图及说明

在实物展示过程中,系统上电后默认进入递增模式,RGB 灯显示绿色,数码管显示当前数值。

短按 KEY1 后系统开始运行,数码管数值逐步增加,LED 进度条同步增加,体现数值比例变化。

再次短按 KEY1 可暂停运行,此时 RGB 灯亮度降低。

通过 KEY2 可在递增、递减和随机模式之间循环切换,切换时 RGB 灯颜色相应改变。

在递减模式下数值逐步减小,在随机模式下数值每秒变化。

 

长按 KEY1 可执行系统复位操作。拨动拨码开关可强制进入指定模式,体现硬件优先控制逻辑。

调试过程中通过串口打印信息实时观察模式变化与数值变化,使软件逻辑更加直观清晰。


七、难题及解决方法

在项目开发过程中,首先遇到的问题是数码管显示闪烁现象。经过分析发现刷新频率过低导致视觉闪烁,通过将定时器周期调整为 2ms 提高扫描频率后问题得到解决。其次在按键识别过程中,由于 ADC 数值存在波动,初期出现误判情况。通过设置合理误差范围并增加软件防抖判断逻辑,显著提高了识别准确率。在长按识别逻辑设计中,也曾出现长按释放后误判为短按的问题,最终通过引入长按标志位区分逻辑状态成功解决。此外,在查理复用控制 LED 时出现部分 LED 亮度不均的情况,通过优化刷新周期与点亮顺序,使显示效果更加均匀稳定。这些问题的解决过程不仅提升了系统稳定性,也增强了我对嵌入式调试方法的理解。


八、心得体会

通过本次项目实践,我对嵌入式系统的整体开发流程有了更加深入的理解。从硬件连接到软件架构设计,再到调试与优化,每一个环节都需要严谨思考与反复验证。本项目让我认识到模块化设计的重要性,合理的结构划分可以大幅提升代码可读性和系统稳定性。同时,通过动态扫描和查理复用技术的实践,我更加理解了如何在有限硬件资源下实现更多功能。按键防抖与状态机设计也让我体会到细节处理对系统稳定性的关键影响。整体而言,本项目不仅提升了我的编程能力和问题分析能力,也增强了我对嵌入式系统工程化设计思维的认识,是一次非常有价值的学习与实践经历。

附件下载
test3.py
团队介绍
个人作品
团队成员
苍白沐
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号