2026寒假练-用RP2350B实现OLED数字温度与电压表
该项目使用了CircuitPython 语言,实现了RP2350B核心板的设计,它的主要功能为:基于 RP2350B 与综合训练板的 OLED 数字温度与电压表设计与实现。
标签
2026寒假一起练
OLED 数字温度与电压表
CircuitPython 语言
孟广栋
更新2026-03-24
北京理工大学
36

基于 RP2350B 与综合训练板的 OLED 数字温度与电压表设计与实现

摘要

本项目基于电子森林 RP2350B 核心板与综合训练板,完成“OLED 数字温度与电压表的嵌入式综合功能实现。系统通过外接 ADC 采集训练板电位器电压,并使用 DS18B20 进行温度测量;在 128×32 SPI OLED 上实现温度/电压数值同屏显示与条形图可视化,同时利用按键实现页面切换、温度上限设定与静音控制。当温度超过设定上限时,系统触发蜂鸣器声提示,并通过板载 WS2812 指示告警状态;双位七段数码管用于显示当前页面编号,便于用户快速确认工作界面。软件方面采用 CircuitPython 开发,使用主循环+软定时器的方式对采集、显示与交互进行分时调度,并结合 PIO 实现蜂鸣器非阻塞发声,从而在保证实时性的同时避免界面刷新卡顿。

1 所选任务介绍

本次选题为【搭配综合训练板】OLED 数字温度与电压表。任务要求围绕采集显示交互告警闭环展开,具体包括以下三个方面:

1)电压与温度采集与显示
系统需读取综合训练板上的电位器电压,并采集 DS18B20 温度数据;在 OLED 屏幕上同屏显示温度、电压等数值信息,并以条形图形式直观展示变化趋势,提升可读性与交互体验。

2)温度上限设定与超限告警
通过按键实现温度上限的设置(增/减),当实时温度超过设定阈值时,系统应给出明确告警:蜂鸣器进行提示,同时 LED(或彩灯)指示当前处于告警状态;另外,为满足不同场景需求,加入静音控制,使告警方式更灵活。

3)页面/模式显示
系统需具备多页面显示能力(例如总览页、温度页、电压页、参数设置页等),并通过双位七段数码管显示当前页面编号或工作模式,方便用户在使用过程中快速定位界面状态。

为便于验收与测试,本项目将上述要求进一步工程化为可观察的验收点

·         OLED 能稳定显示温度、电压数值,并同步显示两种条形图;

·         按键切换页面时,数码管显示的页面编号同步变化;

·         温度上限可调,超限时触发蜂鸣器与灯光提示,解除超限后状态可恢复;

·         系统在告警或按键操作时,显示与采样不应明显卡顿。

 

2 项目介绍

本项目旨在利用 RP2350B 平台完成多外设综合应用开发,重点训练从硬件接口理解到软件工程实现的完整流程。系统以 RP2350B 为核心控制器,连接综合训练板上的传感器与显示外设,实现对温度与电压的实时监测,并提供阈值告警与多页面人机交互能力。

项目实现过程中覆盖了典型嵌入式系统的关键环节:

1)多接口外设接入OLED 与外接 ADC 采用 SPI 通信,DS18B20 采用 OneWire 总线,数码管通过 74HC595 串行移位驱动,按键采用 ADC 阶梯电阻方式复用输入,告警输出包含蜂鸣器与 WS2812 彩灯。

2)实时性与并行任务调度:系统采用主循环+软定时器的分时调度策略,将按键扫描、电压采样、温度采样、OLED 刷新、数码管刷新等任务以不同周期运行,避免阻塞式代码导致界面卡顿或采样延迟。

3)非阻塞告警设计:蜂鸣器提示通过 PIO 方式实现“burst”发声,触发后快速返回主循环,不占用 CPU 长时间等待,从而保证告警出现时 OLED 与按键响应仍保持流畅。

4)显示性能优化OLED 刷新采用变化阈值 + dirty 标记机制,当温度/电压变化小于设定阈值时不强制刷新,降低屏幕闪烁并减少总线占用。

总体而言,本项目不仅完成了题目要求的功能,还在工程实现层面注重可维护性与稳定性:通过模块化函数封装、参数常量化与分时调度,保证了系统在多外设并行工作时仍能稳定运行,具备较好的可扩展性(例如后续可加入数据滤波、阈值掉电保存、更多页面显示等功能)。

 

3 简短的所有使用到的硬件介绍

本项目基于电子森林 RP2350B 核心板与综合训练板完成开发,实现温度与电压采集、OLED 同屏显示、按键交互、超限告警以及数码管页面显示等功能。系统所使用的硬件主要分为主控与扩展连接”“采集传感器”“显示与交互”“告警与指示四类,简要说明如下。

1)主控与扩展连接

·     RP2350B 核心板:作为系统主控制器,负责外设通信、数据处理、页面状态机管理以及告警逻辑执行。核心板提供稳定的 3.3V 逻辑电平和丰富 GPIO 资源,并通过扩展接口与综合训练板连接,实现对训练板外设的统一控制。

·     综合训练板:提供项目所需的主要外设器件(如电位器、ADCDS18B20OLED、蜂鸣器等),并与核心板形成完整的采集显示交互告警闭环实验平台。

2)采集传感器与数据来源

·         电位器 RV1:用于产生可调模拟电压,模拟输入电压变化源,便于对电压采集与显示效果进行验证。

·         外接 ADC(训练板 ADC 芯片):用于将电位器输出的模拟电压转换为数字量,主控通过数字接口读取原始采样值,并换算为实际电压值(0~3.3V)。

·         温度传感器 DS18B20:采用 OneWire 总线通讯输出温度数据,主控周期性触发温度转换并读取结果,用于实现温度显示与超限判定。

3)显示与人机交互

·         SPI OLED128×32:作为主要显示终端,用于同屏显示温度、电压、温度上限、告警/静音状态等信息,并通过条形图方式对温度与电压变化进行可视化呈现,提高直观性。

·         双位七段数码管(74HC595 驱动):用于显示当前页面编号或工作模式编号,帮助用户快速确认系统所处界面。通过 74HC595 移位寄存器将串行数据转换为并行段码输出,从而降低 GPIO 占用。

·         按键输入(ADC 键盘方式):系统使用按键实现页面切换、温度上限增减与静音控制等交互功能。按键通过电阻网络复用为单路 ADC 输入,主控通过读取 ADC 数值区间识别不同按键,并结合消抖策略提升判定稳定性。

4)告警与状态指示

·         蜂鸣器(带驱动电路):当温度超过设定上限时触发声提示,用于明确告警。为避免蜂鸣器发声影响主循环实时性,本项目采用非阻塞方式实现提示音输出。

·         WS2812 彩灯/LED 指示:用于显示系统状态(如告警状态、静音状态或提示窗口),使告警更直观、可视化。

综上,硬件体系覆盖了嵌入式系统常见的多种外设接口与功能模块,既满足题目要求,也具备良好的扩展性(例如后续可加入电压滤波、阈值掉电保存、更多页面内容等)。

 

4 方案框图和项目设计思路介绍

本项目的总体方案围绕多源数据采集 + 页面化显示 + 交互设定阈值 + 超限告警输出的闭环目标展开。系统以 RP2350B 为核心控制器,分别完成电压与温度数据采集,并在 OLED 上进行数值与条形图显示;同时通过按键实现页面切换与温度上限设定,在满足实时显示的基础上实现可靠告警与状态提示。为保证多外设并行工作的稳定性与流畅度,软件设计强调分模块调试、非阻塞逻辑、分时调度与刷新优化



图1闭环数据采集与显示系统方案框图

4.1 总体方案思路

·         采集端:电位器输出模拟电压,经训练板 ADC 转换为数字量;温度由 DS18B20 传感器输出。主控周期性读取两类数据,并进行必要的数值换算与阈值判断。

·         处理端:主控内部建立页面状态机与参数管理逻辑(如 page、温度上限 T_limit、静音 mute 等),并根据实时温度与阈值关系判断是否进入告警状态。

·         显示端OLED 同屏显示温度、电压、阈值以及系统状态,并以条形图呈现变化趋势;数码管用于显示当前页面编号,使用户在切换页面时具备明确的视觉反馈。

·         输出端:当温度超限时,蜂鸣器进行提示,灯光/LED 给出状态指示;同时系统保留静音功能,满足不同使用场景需求。

4.2 工程化设计思路与实现步骤

为降低集成复杂度、提高调试效率,本项目采用先跑通、再集成、最后优化的工程路线:

1接口确认与最小功能验证
首先依据原理图确认各外设接口类型与控制信号,完成 OLED 点亮、DS18B20 读数、ADC 读数与数码管显示等最小功能验证,确保硬件连接与引脚定义正确。

2采集模块独立实现与稳定性处理
电压采集部分将 ADC 原始值换算为 0~3.3V 的电压值,并通过变化阈值抑制轻微抖动;温度采集部分考虑 DS18B20 需要一定转换时间,采用异步/非阻塞的方式读取,避免长时间等待造成界面卡顿。

3显示层 UI 与条形图设计
OLED 显示设计采用数值信息 + 条形图的组合形式:数值用于精确读数,条形图用于快速观察变化趋势。在实现上通过对图形对象进行遮罩控制,减少重绘开销并提升刷新稳定性。

4交互逻辑与页面状态机
系统将显示内容组织为多个页面(例如总览、温度、电压、阈值设置等),通过按键完成页面切换与温度上限增减,并将当前页面编号同步显示在数码管上,保证交互一致性与可用性。

5超限告警策略与非阻塞输出
告警逻辑以温度上限为阈值。当实时温度超过阈值时触发告警输出,并给出灯光提示;同时加入静音控制,避免不必要的持续鸣叫。为保证主循环实时性,蜂鸣器提示采用非阻塞方式实现,使告警触发不会影响采样、按键响应与 OLED 刷新。

6整体调度与刷新优化
最终将按键扫描、电压采集、温度采集、OLED 刷新、数码管刷新等任务以不同周期在主循环中分时执行,并结合“dirty 刷新标志机制,仅在数据变化或状态变化时刷新显示,从而提升系统流畅度并降低总线负载。

通过上述设计,本项目能够在多外设并行运行的情况下保持稳定显示、交互响应及时,并在超限场景下给出清晰可靠的告警反馈,满足题目功能要求并具备一定工程完整性。

5 调试软件及使用的编程语言说明、软件流程图及关键代码介绍

5.1 调试软件与使用的编程语言说明

本项目运行于 RP2350B 平台,采用 CircuitPython 作为开发语言与运行环境。CircuitPython 具有上手快、库生态完善、支持 USB 盘快速部署与 REPL 交互调试等特点,适合本项目涉及的多外设综合开发(OLED 显示、ADC 采集、OneWire 温度传感器、WS2812 灯光、74HC595 数码管、蜂鸣器等)。

项目开发与调试主要使用以下方式完成:

1USB 盘部署与在线运行
核心板通过 USB 连接电脑后会以 CIRCUITPY 盘符形式出现,将主程及所需库文件拷贝到该盘符中即可运行。该方式便于快速迭代:修改代码保存自动重启运行,缩短调试周期。

2REPL/串口日志调试
通过串口进入 CircuitPython REPL,可在调试阶段快速验证引脚配置、外设读写是否正常,例如确认 OLED 是否能初始化、DS18B20 是否能扫描到设备、ADC 是否能读到有效数据等。同时,项目在关键状态变化时输出日志(温度、电压、阈值、页面编号、告警/静音状态),用于对照 OLED 显示验证逻辑正确性,定位异常来源。

3)库与模块依赖
本项目主要依赖的库/模块包括:

·         显示与 UIdisplayiofourwireadafruit_displayio_ssd1306adafruit_display_textadafruit_display_shapes

·         采集:analogio(按键 ADC 输入)、adafruit_onewire.busadafruit_ds18x20

·         外设控制:digitalioGPIO)、neopixelWS2812)、rp2pio + adafruit_pioasmPIO 蜂鸣器)

其中,电位器电压读取采用外接 ADC 数字接口读取原始值再换算的方式实现,满足题目对电压测量的功能需求。

5.2 软件流程图

为保证显示流畅、按键响应及时且告警输出不影响主循环,本项目软件采用主循环 + 多节拍软定时器的调度结构。整体流程可概括为初始化循环调度按需刷新三部分。

image.png

2 软件流程图

1)系统初始化阶段

Ø  初始化 GPIO 方向与默认电平(74HC595、蜂鸣器控制、WS2812 等)

Ø  初始化 OLEDSPI 总线、D/CCSRES),创建显示层对象并绘制基础 UI 框架

Ø  初始化 DS18B20OneWire 总线扫描设备),设置温度转换与读取参数

Ø  初始化电压采样接口(外接 ADC 读取时序/引脚),设置采样周期与换算参数

Ø  初始化按键输入(ADC 键盘)并进行 baseline 校准,设置消抖时间

Ø  设置系统默认状态变量:页面 page、温度上限 T_limit、静音 mute、告警状态 over

2)主循环阶段(while True
主循环中根据不同任务周期分时执行以下子任务:

Ø  按键扫描(高频):读取 ADC 键盘值计算与 baseline 的偏差区间判定按键编号消抖确认触发事件(切页/阈值增减/静音)

Ø  电压采样(中频):读取 ADC 原始值提取有效位 3.3V 参考换算为电压值若变化超过阈值则置 dirty_oled

Ø  温度采样(低频,异步两阶段)

n  到达周期时启动 DS18B20 转换(start)并记录时间戳

n  到达转换完成时间后读取温度(read若变化超过阈值则置 dirty_oled

Ø  超限判定与告警输出:若 temp > T_limit 则进入告警状态;当发生未超限超限的边沿时触发蜂鸣器提示,同时控制 WS2812/LED 显示告警(静音状态下不发声/可关闭灯光)

Ø  OLED 刷新(低频,按需):若到达刷新周期且 dirty_oled 置位,则更新文本与条形图显示

Ø  数码管刷新(固定节拍):向 74HC595 移位输出段码,显示当前页面编号或模式编号

通过上述分时调度,系统在多外设并行运行时仍可保持稳定的显示与交互响应,并且告警输出不会阻塞主循环。

5.3 关键代码介绍

本节选取能够体现本项目设计思路与工程实现的关键环节进行说明,包括电压换算、温度异步读取、条形图绘制、按键判定消抖、PIO 蜂鸣器非阻塞输出与软定时器调度等。

1)电压采样与电压换算(电位器电压)

外接 ADC 返回原始数字量后,程序提取有效位(如 12bit)并换算为实际电压值,计算关系如下:

3565c7980b404249677795aa2fd5d85b.png

其中 raw ADC 采样值,3.3V 为系统参考电压。为减少 OLED 上数值抖动与频繁刷新,程序设置电压变化阈值(如 0.02V),当变化小于阈值时不强制刷新屏幕,从而提升显示稳定性与系统效率。

def adc_read_rawB_12():
v16 = adc_read_16bits()
return v16 & 0x0FFF

def raw12_to_v(raw12, vref=3.3):
return (raw12 / 4095.0) * vref

2DS18B20 温度读取(异步两阶段,避免阻塞)

DS18B20 温度转换需要一定时间(典型约 750ms)。若使用阻塞式等待,会导致按键响应变慢、显示刷新卡顿。因此本项目采用启动转换到时读取的异步两阶段方式:

·         周期到达时调用启动温度转换,并记录启动时间

·         当当前时间超过转换所需时间后,再读取温度结果并更新显示数据
该方法使主循环在等待期间仍能执行按键扫描、数码管刷新等任务,有效提升交互流畅度。

if ds_has_async:
if ds_state == "IDLE" and now >= ds_next_start:
try:
ds.start_temperature_read()
ds_ready_time = now + DS_CONV_TIME
ds_state = "WAIT"
except Exception:
ds_state = "IDLE"
ds_next_start = now + DS_PERIOD

elif ds_state == "WAIT" and now >= ds_ready_time:
try:
t = float(ds.read_temperature())
temp_c = t
if (last_temp_shown is None) or (abs(t - last_temp_shown) >= 0.1):
dirty_oled = True
ds_state = "IDLE"
ds_next_start = now + (DS_PERIOD - DS_CONV_TIME)
except Exception:
ds_state = "IDLE"
ds_next_start = now + DS_PERIOD

3OLED 同屏显示与条形图(遮罩法)

OLED 采用数值 + 条形图组合显示:数值用于精确读数,条形图用于直观呈现变化趋势。条形图实现上采用白色底条 + 黑色遮罩的方式:先绘制固定高度的白色矩形条,再通过移动黑色遮罩矩形的 y 坐标控制露出高度,即可实现条形图动态变化。该方法避免频繁创建/销毁图形对象,降低重绘开销,屏幕刷新更稳定。

# 白色底条
bar_temp_fg = Rect(bar_temp_x, 0, BAR_W, HEIGHT, fill=0xFFFFFF, outline=None)
# 黑色遮罩
bar_temp_mask = Rect(bar_temp_x, 0, BAR_W, HEIGHT, fill=0x000000, outline=None)

def set_vbar(mask_rect, ratio):
ratio = clamp01(ratio)
h = int(ratio * HEIGHT)
if h < 0:
h = 0
if h >= HEIGHT:
h = HEIGHT - 1 # 避免 y == -HEIGHT
mask_rect.y = -h

4)按键 ADC 判定与消抖策略

本项目按键采用 ADC 阶梯电阻复用为单路模拟输入。程序首先进行 baseline 校准,在运行时读取当前 ADC 值并与 baseline 做差,得到偏差 delta;然后根据 delta 所落区间判定按下的是哪个按键。为避免抖动与误触,程序加入消抖机制:只有按键状态稳定持续超过设定消抖时间(例如 40ms)才确认一次有效按键事件。该策略能够在硬件噪声或边沿波动时保持稳定识别。

def which_key(delta):
if delta < -22000: return 1
if delta < -11000: return 2
if delta < -5500: return 3
if delta < -DROP_TH: return 4
return None

# 在主循环中
if armed and pressed:
if (now - last_edge) * 1000.0 > DEBOUNCE_MS:
last_edge = now
press_key = which_key(delta)
armed = False

if (not armed) and (abs(delta) < RELEASE_BAND):
if press_key == 1:
page = (page + 1) % 4
dirty_oled = True
# ... 其他按键处理
press_key = None
armed = True

5)蜂鸣器告警(PIO burst 非阻塞输出)

温度超限时需要蜂鸣器提示,但如果采用 sleep 或长时间 PWM 播放会阻塞主循环。本项目将蜂鸣器输出设计为非阻塞方式:使用 PIO 生成指定频率与持续时长的方波 burst,触发后立即返回主循环,CPU 可继续执行显示刷新与按键扫描。该实现保证了告警出现时系统仍具有良好的实时性与交互体验。

class PIOBuzzerBurst:
def __init__(self, pin=board.GP20, sm_freq=1_000_000):
self._sm = rp2pio.StateMachine(
_PIO_BEEP_BURST.assembled,
frequency=sm_freq,
first_set_pin=pin,
set_pin_count=1,
auto_pull=False,
**_PIO_BEEP_BURST.pio_kwargs,
)
self._cmd = array.array("I", [0, 0])

def beep(self, freq_hz=2000, duration_ms=500):
half = int(self._sm.frequency / (2 * freq_hz))
cycles = int(freq_hz * (duration_ms / 1000.0))
self._cmd[0] = half
self._cmd[1] = cycles
self._sm.write(self._cmd)

# 超限边沿触发蜂鸣
def over_edge_beep(now: float, over: bool):
global prev_over, ws_until
if (not prev_over) and over and (not mute):
buzzer.beep(freq_hz=2000, duration_ms=500)
ws_until = now + 0.5
prev_over = over

6)软定时器多任务调度(主循环分时执行)

为了同时兼顾多外设更新频率与系统实时性,本项目为不同任务设置不同周期(例如按键 5ms、数码管 20ms、电压 50msOLED 200ms、温度 1s 等),在主循环中通过时间戳判断任务是否到期执行。这种软定时器方案无需多线程与硬件中断,结构清晰、易维护,并能有效避免某一任务占用过多时间导致其他任务饥饿。

SEG_PERIOD  = 0.020
next_seg = time.monotonic()

KEY_PERIOD = 0.005
next_key = time.monotonic()

ADC_PERIOD = 0.050
next_adc = time.monotonic()

OLED_PERIOD = 0.200
next_oled = time.monotonic()

DS_PERIOD = 1.0
DS_CONV_TIME = 0.75

while True:
now = time.monotonic()

if now >= next_seg:
show_one_digit_page(page)
next_seg = now + SEG_PERIOD

if now >= next_key:
# 按键扫描
next_key = now + KEY_PERIOD

if now >= next_adc:
# 读取电位器
next_adc = now + ADC_PERIOD

if now >= next_oled:
# 刷新OLED
next_oled = now + OLED_PERIOD

# DS18B20 异步状态机已在内部判断
# ...

6 功能展示图及说明(实物展示、软件或工具调试)

本项目的功能展示以屏幕界面效果 + 串口调试信息 + 关键状态对比为主,辅以少量必要的整体连接示意。通过这些可重复、可量化的展示方式,可以更清晰地证明系统已完成题目要求的电压/温度采集、OLED 同屏显示与条形图、按键设阈值、超限告警、数码管页面显示等功能,并体现调试过程的可靠性与可追溯性。

6.1 系统启动与默认页面展示(OLED + 数码管)

image.png

3 上电启动后的默认显示界面(OLED 总览页)

系统上电后自动进入默认页面(总览页)。OLED 同屏显示温度值(Temp)、电压值(Volt)、温度上限(Limit)以及系统状态(如 OK / ALRM / MUTE)。右侧以两根竖向条形图分别表示温度与电压的相对水平,实现数值读数 + 趋势观察的组合显示方式。与此同时,双位七段数码管显示当前页面编号(如 0),用于快速提示当前界面状态,便于页面切换时校验一致性。

说明要点:该展示用于证明OLED初始化正常、显示布局与刷新逻辑可用,数码管驱动与页面状态变量绑定正确。

6.2 多页面切换与显示内容验证

b3ec8d2d87832a3fc23af18e18335240.jpg7a81fed49f68f1b16bcda685374fdb42.jpgf957f58090651eafff37b3c824e272a0.jpg03b9c1177c2d875c8d181d1d3e463cd6.jpg

4 Page0~Page3 页面切换截图组(连续四张)

通过按键触发页面切换,OLED 在多个页面之间循环切换,并且数码管同步显示当前页面编号(0/1/2/3)。各页面定位如下:

·         Page0(总览):同时显示温度、电压、阈值与状态,适合日常监测;

·         Page1(温度页):突出温度显示与温度条形图,同时保留阈值/状态信息;

·         Page2(电压页):突出电压显示与电压条形图,并可显示 ADC 原始值用于调试校验;

·         Page3(设置页):给出阈值设置提示(例如“SET LIMIT / K2+ K3-”),引导用户调整温度上限。

说明要点:该展示用于证明页面状态机 + UI 文本更新 + 数码管显示联动三者一致,满足题目数码管显示当前页面或工作模式的要求。

6.3 电压采集与条形图联动展示

0259a66fb8a1897459c203b6f9828c7f.jpg38479e176c095085c5bf8ac697839337.jpg

81c3360211ddf0a18a0798cbac927bc5.jpgaf760204a6674c46ac893c25290b585d.jpg

5 电压变化过程展示(OLED 电压数值 + 电压条变化)

调整电位器后,OLED 上的电压数值随输入变化实时更新,电压条形图的高度同步变化。为了减少数值抖动与屏幕闪烁,软件对电压更新设置了变化阈值:当变化小于阈值时不强制刷新,从而在保持响应速度的同时提升显示稳定性。

6.4 温度采集、阈值设置与显示更

8ca140d4e6bbf0179001f3ea3f8aa3d7.jpgaa8e0572de48a58e89eac47c96397852.jpg

6 温度显示与温度条变化

系统周期性读取 DS18B20 温度并刷新 OLED 显示。当温度变化时(如环境变化或热源靠近),温度数值与温度条形图会出现对应变化,证明温度采集链路与显示更新逻辑正确。项目采用启动转换到时读取的非阻塞方式获取温度,保证在温度转换等待期间主循环仍能持续响应按键与刷新数码管。

eaf68575835dd67502c1920f9c38069c.jpg3d26c23c414a4f8f012ec44541ce359c.jpg

7 温度上限(Limit)增/减设置展示

在设置页或总览页中,通过按键可对温度上限进行增减调整。每次按键操作后,OLED 上的 Limit 数值会立刻更新,同时页面/模式显示保持一致。该功能验证了按键判定、消抖机制与参数管理逻辑的可靠性,为后续超限告警提供正确阈值输入。

6.5 超限告警与静音功能展示

65dadfb754b28761d137a13f37834936.jpg74a518b4d075b016238fb32b6af3d9a3.jpg

8 超限告警状态展示(ALRM + 蜂鸣器 + 灯光提示)

当实时温度超过设定上限时,系统进入告警状态:OLED 状态字段显示为 ALRM(或同类告警标识),蜂鸣器触发提示音,同时 WS2812/LED 以亮起或闪烁方式提示当前处于超限状态。该展示说明系统已完成阈值比较告警触发状态显示的闭环功能,满足题目超过上限蜂鸣器提示,LED 指示告警状态的要求。
此外,蜂鸣器输出采用非阻塞方式实现,告警触发时 OLED 刷新与按键响应仍保持稳定,无明显卡顿,保证了系统实时性。

按下静音按键后,OLED 状态字段显示为 MUTE,此时蜂鸣器不再触发(或触发被屏蔽),灯光提示可按设计策略关闭或弱化。该功能展示了系统对不同使用场景的适配能力:既保留超限状态提示,又避免不必要的声音干扰,提升人机交互体验。

6.6 软件工具调试展示

为进一步增强可验证性,本项目在调试阶段通过串口输出关键状态信息,形成与 OLED 显示一致的第二证据链

串口打印信息可包含:温度值、温度上限、是否超限(over)、静音状态(mute)、电压值/原始采样值、当前页面编号等。当按键切页、调阈值或发生超限时,串口日志与 OLED 显示状态同步变化,证明数据处理与界面显示逻辑一致,有利于定位问题并验证系统稳定性。

7 项目中遇到的难题及解决方法

本项目涉及温度采集、电压采集、OLED 显示、按键交互、数码管驱动以及蜂鸣器/灯光告警等多个模块,属于典型的多外设综合嵌入式系统。在实现过程中,主要遇到的问题集中在时序与非阻塞”“输入稳定性”“显示刷新效率以及硬件资源与接口调试四个方面。下面按现象原因解决验证的方式总结关键难题与解决方法。

7.1 DS18B20 温度读取导致主循环卡顿

·     问题现象:早期实现中,读取 DS18B20 温度时界面刷新变慢,按键响应变迟钝;在温度读取周期到来时,系统出现短暂卡顿现象。

·     原因分析DS18B20 每次测温需要一定的转换时间(典型约 750ms,视分辨率而定)。若程序采用阻塞式等待(例如等待转换完成后再读取),会导致主循环在等待期间无法执行按键扫描与 OLED 刷新,从而产生明显卡顿。

·     解决方法:采用异步两阶段读取策略:

1.      周期到达时只启动温度转换并记录时间戳;

2.      主循环继续运行其他任务;

3.      到达转换完成时间后再读取温度结果并更新显示。
这样既保证温度读数正确,又避免阻塞主循环。

·     效果验证:改为异步读取后,温度采样发生时 OLED 刷新和按键响应仍保持流畅,页面切换无明显迟滞,串口日志显示温度数据按周期稳定更新。

7.2 OLED 刷新频繁导致闪烁/总线占用高

·         问题现象:当采样频率较高或输入有轻微抖动时,OLED 数值快速跳动并伴随视觉闪烁;同时系统整体忙碌感增强,影响其他任务的实时性。

·         原因分析OLED 属于低速显示外设,若每次循环都全量刷新,SPI 总线占用会显著增大;同时电压/温度传感器存在细小噪声,频繁刷新会把噪声放大为明显闪烁。

·         解决方法:从刷新触发条件显示绘制方式两方面优化:

1.      引入 dirty 标记:只有当数据或状态发生变化时才置位刷新标志,并在到达 OLED 刷新周期后再统一刷新;

2.      设置 变化阈值:电压/温度变化小于阈值时不触发刷新,减少抖动带来的无效更新;

3.      条形图采用遮罩法(移动遮罩矩形而非频繁重建对象),降低重绘开销。

·         效果验证:优化后 OLED 显示更稳定,闪烁明显减轻;在频繁按键或告警触发时仍能保持较平滑的刷新节奏。

7.3 ADC 键盘方式输入不稳定

·         问题现象:按键在某些情况下会出现误判,例如按下一个键却偶尔识别为另一个键,或出现按了一次却触发多次的情况。

·         原因分析:本项目按键采用 ADC 阶梯电阻复用输入,ADC 读数会受电源噪声、手指抖动、采样瞬态等影响产生波动;同时按键机械抖动也会造成短时间内状态反复变化。

·         解决方法

1.      baseline 校准:在空闲状态下取基准值,运行时用 delta = adc - baseline 减小偏置影响;

2.      区间判定:为不同按键设置合理的数值区间,并留出裕量,避免边界附近的抖动造成串键;

3.      消抖策略:设置消抖时间(如 40ms),只有状态连续稳定超过消抖时间才确认一次有效按键事件;

4.      事件触发采用边沿/释放触发思路,避免按住不放时重复触发。

·         效果验证:改进后按键识别稳定,页面切换与阈值增减与实际操作一致,误触发显著减少。

7.4 蜂鸣器提示影响系统实时性

·         问题现象:使用简单延时或阻塞式 PWM 发声时,一旦蜂鸣器响,OLED 刷新会暂停、按键响应变慢,影响整体体验。

·         原因分析:阻塞式蜂鸣器实现通常需要循环输出方波或 sleep 等待持续时间,这会占用 CPU 时间,使主循环无法及时执行其他任务。

·         解决方法:采用 PIO burst 非阻塞发声:触发蜂鸣器时仅向 PIO 状态机写入频率与周期参数,由 PIO 在硬件侧完成方波输出,主循环立即返回继续运行。同时告警触发策略采用超限上升沿触发一次的方式,避免温度持续超限时蜂鸣器频繁打断交互。

·         效果验证:蜂鸣器提示期间 OLED 仍能按节拍刷新,按键仍可及时响应;告警触发准确且不影响系统稳定性。

7.5 多外设并行时序管理困难

·     问题现象:在把所有模块集成到同一程序后,若不控制执行顺序与频率,会出现某些任务执行过于频繁,导致其他任务饿死或刷新不稳定。

·     原因分析:多外设综合项目中,不同模块对实时性的要求不同:按键扫描需要更高频率,OLED 刷新不宜过快,温度采样周期较长,数码管需要固定节拍才能不闪。若缺乏统一调度,很容易出现资源竞争。

·     解决方法:采用主循环 + 多软定时器的调度框架,为不同任务设置不同周期:

1)              按键扫描高频执行;

2)              数码管固定节拍刷新;

3)              电压采样中等频率;

4)              OLED 低频按需刷新;

5)              DS18B20 低频且异步读取。
通过时间戳判断到期执行,并结合 dirty 刷新策略保证系统整体节奏可控。

·     效果验证:调度后系统运行更平稳,页面切换、数值更新、告警触发互不干扰,整体表现符合实时显示 + 及时交互的预期。

7.6 小结

综上,本项目的主要难点并非单一外设的驱动,而在于多外设集成后的系统级问题:如何在资源有限的单片机平台上实现稳定采集、流畅显示与可靠告警。通过异步温度读取、OLED 按需刷新、ADC 键盘消抖判定、PIO 非阻塞蜂鸣器以及软定时器调度等方法,最终实现了稳定可用的系统效果,并为后续扩展(例如增加滤波、阈值掉电保存、更多页面与更丰富指示方式)打下了良好基础。

 

附件下载
p48_composite8.py
主程序
lib.rar
引用的库
团队介绍
北京理工大学-孟广栋
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号