尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flipper Zero 1-Wire 温度计示例解析:在 Unleashed 固件中用 DS18B20 构建完整应用

Flipper Zero 1-Wire 温度计示例解析:在 Unleashed 固件中用 DS18B20 构建完整应用 Flipper Zero 1-Wire 温度计示例解析在 Unleashed 固件中用 DS18B20 构建完整应用【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware本篇技术指南以 Unleashed 固件仓库中的 example_thermo 示例应用 为骨架完整讲解如何将 DS18B20 数字温度传感器通过 1-Wire 总线连接到 Flipper Zero 的外部 GPIO并跑通一个集温度采集、屏幕绘制、按键响应、后台线程与本地化显示于一体的示例程序。读完本文你将掌握 1-Wire 主机库的初始化与通信流程、DS18B20 温区寄存器解析方法、通过fbt编译启动 FAP 的完整命令以及如何更换数据引脚并理解外置上拉电阻的硬件前提。示例应用概览与源码入口example_thermo是一个 FlipperAppType.EXTERNAL 类型的示例应用参见 application.fam应用标识为example_thermo入口函数为example_thermo_main需要依赖gui服务栈大小为 1KB属于Examples分类。它的核心作用有两个层面演示 DS18B20 的 1-Wire 驱动用法包括复位、写命令、读暂存器Scratchpad、CRC 校验与温度值换算演示完整应用的四个基本功GUI 绘制ViewPort Canvas、输入事件处理消息队列、线程FuriThread 标志量协作、本地化locale 公制/英制单位切换。主程序源码位于 example_thermo.c执行流程为example_thermo_main→ 分配上下文example_thermo_context_alloc→ 运行主循环example_thermo_run→ 释放资源example_thermo_context_free。这种「分配上下文 → 运行循环 → 释放资源」三段式结构是 Flipper 应用的标准范式。电气连接DS18B20 与 Flipper 外部 GPIO在启动应用之前需要按下表将传感器与 Flipper 的 GPIO 排针相连对应引脚位置见 furi_hal_resources.h 中定义的引脚映射DS18B20Flipper 引脚VDD9GND18DQ17两条重要注意事项NOTE 1GND 也可以使用排针上的 8 号或 11 号引脚三者电气等价NOTE 2默认引脚 17即gpio_ibutton映射到 iButton 端口见 furi_hal_resources.c内部已带有上拉能力一旦改用其他引脚必须在 DQ 与 VDD9 号脚之间外接一个 4.7kΩ 上拉电阻。从源码层面看这一约束与 1-Wire 总线的电气特性直接相关总线空闲时必须被上拉至高电平时序操作依赖主机拉低与释放的组合。在 one_wire_host_start 中引脚被初始化为GpioModeOutputOpenDrain开漏输出开漏结构本身不具备拉高能力因此外部上拉电阻是总线正确工作的物理前提。启动应用fbt 命令行全流程启动该演示应用需要依次完成以下步骤确保 Flipper 中已插入 SD 卡示例以 FAP 形式运行需要 SD 卡存放应用文件用 USB 数据线将 Flipper 连接到电脑在终端中运行编译并启动命令./fbt launch APPSRCexample_thermofbt是 Unleashed 固件的统一构建工具位于仓库根目录脚本入口 fbtlaunch子命令会完成 FAP 的交叉编译、通过 USB 部署到设备并从 CLI 侧启动该应用。若需要先构建而不启动可使用./fbt fap_example_thermo之类目标开发调试的更多用法可参考 fbt.md 与 AppManifests.md。运行后屏幕会显示Thermometer Demo标题与「Connect thermometer to GPIO pin 17」提示温度读数实时刷新按 Back 键退出。更换数据引脚THERMO_GPIO_PIN 宏详解示例允许通过修改宏来更换 1-Wire 数据引脚可选值如下源码注释与 furi_hal_resources.h 中均可查证/* Possible GPIO pin choices: - gpio_ext_pc0 - gpio_ext_pc1 - gpio_ext_pc3 - gpio_ext_pb2 - gpio_ext_pb3 - gpio_ext_pa4 - gpio_ext_pa6 - gpio_ext_pa7 - gpio_ibutton */ #define THERMO_GPIO_PIN (gpio_ibutton)修改要点这些符号均为const GpioPin类型的外部引脚描述符定义于 furi_hal_resources.c例如gpio_ext_pa6对应GPIOA端口的LL_GPIO_PIN_6除gpio_ibutton外其余引脚没有内置上拉电阻更换后必须外接 4.7kΩ 上拉电阻到 9 号脚否则总线无法工作修改后需重新编译并启动应用屏幕上的提示文字会自动更新为对应的引脚号——这是通过furi_hal_resources_get_ext_pin_number(THERMO_GPIO_PIN)动态获取引脚编号实现的见 example_thermo.c。值得注意的是部分可选引脚在系统其他功能中被复用例如gpio_ext_pa6/gpio_ext_pa7同时被调试输出与 PWM 使用参见 furi_hal_os.c 与 furi_hal_pwm.c选择引脚时需避免与已启用的外设冲突。1-Wire 主机库底层实现与关键 API示例依赖的one_wire库位于 lib/one_wire由主机端one_wire_host.h、从机端one_wire_slave与 Maxim CRCmaxim_crc.h组成构建配置见 SConscript。时序参数软件模拟 1-Wire 协议one_wire_host通过 GPIO 位操作软件模拟 1-Wire 时序没有依赖硬件外设。在 one_wire_host.c 中定义了三种时序表基于 Maxim Application Note 126normal标准模式默认写 1 低电平 9µs/高电平 64µs写 0 低电平 64µs复位脉冲 480µs存在检测采样 70µs 后延迟 410µsoverdrive超速模式所有时序缩短到约 1/8复位脉冲仅 70µstm01x面向 TM01x 器件复位脉冲 740µs存在检测 140µs。可通过onewire_host_set_overdrive/onewire_host_set_timings_default/onewire_host_set_timings_tm01x切换。示例使用默认时序即可满足 DS18B20 标准速率通信。常用 API 与调用关系API作用底层实现要点onewire_host_alloc(gpio_pin)按引脚分配主机实例初始化搜索状态校验指针、置默认时序见 one_wire_host.conewire_host_start初始化引脚为开漏输出GpioModeOutputOpenDrain见 one_wire_host.conewire_host_reset总线复位并检测存在脉冲拉低 480µs 后释放采样返回是否有设备应答见 one_wire_host.conewire_host_write写一个字节LSB 先行逐位调用onewire_host_write_bitonewire_host_read_bytes连续读取多个字节逐字节调用onewire_host_readonewire_host_search总线设备 ROM 搜索支持条件搜索模式实现标准三态位搜索算法见 one_wire_host.conewire_host_stop释放引脚恢复为GpioModeAnalog见 one_wire_host.c示例场景只有单个传感器因此在每次事务前调用onewire_host_reset后直接发送 Skip ROM0xCC即可无需执行 ROM 搜索若总线上挂接多个 1-Wire 器件则需改用onewire_host_search获取 8 字节 ROM 地址后再按地址寻址。CRC 校验maxim_crc8DS18B20 暂存器第 9 字节是 Maxim 校验和示例用 maxim_crc8 对前 8 个字节计算并与设备返回的 CRC 比对匹配才采信数据。该实现为逐位多项式多项式0x8C算法初始值为MAXIM_CRC8_INIT0。温度读取协议从命令序列到数值换算读取流程在example_thermo_reader_thread_callback后台线程中以 1000ms 周期循环执行宏UPDATE_PERIOD_MS分两阶段完成。阶段一请求转换requestexample_thermo_request_temperature在临界区FURI_CRITICAL_ENTER/EXIT内完成三条命令onewire_host_reset—— 复位总线若返回 false 说明无设备直接放弃并置has_device false写DS18B20_CMD_SKIP_ROM0xCC—— 跳过 ROM 寻址针对单设备总线写DS18B20_CMD_CONVERT0x44—— 启动温度转换。DS18B20 完成一次转换最长需要约 750ms因此线程随后通过furi_thread_flags_wait(ReaderThreadFlagExit, FuriFlagWaitAny, UPDATE_PERIOD_MS)既等待转换完成又等待退出信号超时FuriFlagErrorTimeout说明 1 秒已到、转换就绪继续读取收到ReaderThreadFlagExit标志则退出线程。阶段二读取暂存器并解析readexample_thermo_read_temperature同样在临界区内执行最多重试 10 次复位总线发送 Skip ROM再发送DS18B20_CMD_READ_SCRATCHPAD0xBE准备读取用onewire_host_read_bytes读取 9 字节暂存器内容结构体DS18B20Scratchpad依次为temp_lsb、temp_msb、高/低报警寄存器、配置寄存器、3 字节保留、CRC用maxim_crc8校验前 8 字节与第 9 字节 CRC不匹配则重试10 次全失败则置has_device false校验通过后按 DS18B20 数据手册示例源码引用了官方数据手册换算温度。温度数值换算详解换算逻辑位于 example_thermo.c核心步骤如下分辨率提取resolution_mode (config 5) 0x03对应 9/10/11/12 位分辨率12 位为默认上电值步进 0.0625°C小数位掩码decimal_mask (0x0F (3 - resolution_mode)) 0x0F用于屏蔽低分辨率时无效的低位整数部分integer_part (temp_msb 4) | (temp_lsb 4)小数部分decimal_part temp_lsb decimal_mask每 1/16 位LSB代表 0.0625°C故temp_abs integer_part decimal_part / 16.f符号判断(temp_msb 0xF0) ! 0表示负温最终赋值为-temp_abs或temp_abs。这段代码将原始寄存器字节还原为带符号浮点摄氏度是整个示例最具教学价值的部分可对照 DS18B20 数据手册第 6 页温度寄存器格式逐行核对。GUI、输入与线程模型屏幕绘制绘制回调example_thermo_draw_callback在每次刷新时全量重绘标题Thermometer Demo、分隔线、提示连接引脚号随后根据has_device状态显示温度读数或-- No data --。温度显示通过snprintf格式化为%.1f保留一位小数并带符号例如Temperature: 23.5C。本地化单位切换示例是 locale-aware 的根据locale_get_measurement_unit()见 locale.h判断单位制LocaleMeasurementUnitsMetric直接显示摄氏温度单位CLocaleMeasurementUnitsImperial调用locale_celsius_to_fahrenheit换算为华氏单位F其他取值触发furi_crash(Illegal measurement units)作为防御性断言。用户可在 Flipper 的Settings → System → Units中切换单位制重进应用即可看到温度显示在 °C/°F 间变化直观验证本地化机制。输入与主循环输入回调example_thermo_input_callback由 GUI 线程触发只做一件事把InputEvent投入容量为 8 的消息队列furi_message_queue_alloc(8, sizeof(InputEvent))。主循环example_thermo_run阻塞在furi_message_queue_get上仅响应InputTypeShort类型的短按当按键为InputKeyBack时置退出标志并跳出循环。退出时依次执行向读取线程置ReaderThreadFlagExit标志 →furi_thread_join等待线程结束 →onewire_host_stop释放总线 →power_enable_otg(power, false)关闭外引脚电源。外部引脚供电example_thermo_run在启动时调用power_enable_otg(context-power, true)为外部 GPIO 排针提供 5V 输出API 声明见 power.h实现位于 power_api.c退出时再关闭。这解释了 DS18B20 的 VDD 可直接接 Flipper 引脚 9 供电的原因若自行接线改用外部电源则需相应调整供电配置。从示例到实战关键注意事项小结上拉电阻是硬前提除默认的gpio_ibutton引脚 17外其余数据引脚都必须外接 4.7kΩ 上拉至 VDD否则复位检测与读写时序均不可靠临界区保护1-Wire 位时序对时序抖动敏感所有总线事务复位、读写都应放在FURI_CRITICAL_ENTER/EXIT临界区内执行防止被其他线程打断导致时序错乱转换延时匹配请求转换后需等待至多 750ms 再读取示例用UPDATE_PERIOD_MS 1000的线程标志等待同时兼顾退出响应是「周期任务 优雅退出」的典型写法CRC 校验不可省1-Wire 在长线上易受干扰读取暂存器后务必校验第 9 字节 CRC失败应重试而不是直接采信引脚复用冲突更换数据引脚前先确认该引脚未被调试输出、PWM、红外等其他外设占用可在 furi_hal_resources.c 与对应外设驱动中核对。在此基础上你可以把示例的读取逻辑抽取为可复用模块接入自己的温度监控、数据记录或 BadUSB 联动的应用场景。【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表