Browse Source

add:提交各型号最新版本的代码及说明

wangpenglin 1 month ago
parent
commit
7290ea16cb

+ 65 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/main.lua

@@ -0,0 +1,65 @@
+--[[
+@module  main
+@summary OneWire综合演示项目主文件(单传感器 + 多传感器)
+@version 001.000.000
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本演示项目整合单DS18B20和多DS18B20传感器功能:
+1. 单传感器模式:GPIO2默认OneWire功能、硬件通道0模式、CRC校验、3秒间隔连续监测
+2. 多传感器模式:引脚54/23切换、PWR_KEY按键控制、电源管理、2秒间隔双路监测
+3. 完整的OneWire API接口演示、错误处理、设备检测、温度报警
+]]
+
+-- 项目信息
+PROJECT = "onewire_demo"
+VERSION = "001.000.000"
+
+
+
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
+
+--添加硬狗防止程序卡死
+if wdt then
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
+
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
+
+-- 在加载以下两个功能的时候建议分别打开,避免同时初始化OneWire总线,导致资源冲突
+-- 单设备模式:使用GPIO2默认OneWire功能
+-- 双设备模式:GPIO2默认 + 引脚54复用
+
+-- 加载单传感器应用模块
+-- require("onewire_single_app")
+
+-- 加载多传感器应用模块
+require("onewire_multi_app")
+
+
+-- 启动系统主循环
+sys.run()

+ 0 - 9
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/onewire_multi_18b20_swich_read/main.lua

@@ -1,9 +0,0 @@
-PROJECT = "DS18B20_GPIO_SWITCH_READ_temperature"
-VERSION = "1.0.0"
-sys = require("sys")
-log.style(1)
-
-
-require"switch_read"
-
-sys.run()

+ 0 - 125
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/onewire_multi_18b20_swich_read/switch_read.lua

@@ -1,125 +0,0 @@
-
-pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) -- 所有GPIO高电平输出3.3V(方便使用VDD_EXT给18B20供电)
-gpio.setup(2, 1) --GPIO2控制780EPM开发板V1.3版本camera电源打开和关闭
-gpio.setup(31, 1) -- GPIO31控制780EPM开发板V1.4版本camera电源打开和关闭
-
-local onewire_pin = 54 --18B20接的pin 54脚
-
-
-pins.setup(onewire_pin, "ONEWIRE") -- PAD54脚既是GPIO3也是cam_mclk 
-
---读取当前pin脚上的18B20温度
-local function read_ds18b20(id)
-log.info("读取温度",id)
-    local tbuff = zbuff.create(10)
-    local succ, crc8c, range, t
-    local rbuff = zbuff.create(9)
-    tbuff:write(0x55)
-    tbuff:copy(nil, id)
-    tbuff:write(0xb8)
-  
-    tbuff[tbuff:used() - 1] = 0x44
-    succ = onewire.tx(0, tbuff, false, true, true)
-    if not succ then
-        return
-    end
-
-    succ = onewire.reset(0, true)
-    if not succ then
-        return
-    end
-    if onewire.bit(0) > 0 then
-        log.info("温度转换完成")
-    end
-    tbuff[tbuff:used() - 1] = 0xbe
-    succ = onewire.tx(0, tbuff, false, true, true)
-    if not succ then
-        return
-    end
-    succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
-    crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
-    if crc8c == rbuff[8] then
-        range = (rbuff[4] >> 5) & 0x03
-        -- rbuff[0] = 0xF8
-        -- rbuff[1] = 0xFF
-        t = rbuff:query(0, 2, false, true)
-        t = t * (5000 >> range)
-        t = t / 10000
-        log.info("当前温度", t,"原始值为",mcu.x32(rbuff[8]))
-    else
-        log.info("RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
-        return
-    end
-
-end
-
---初始化当前pin脚上的18B20,并读取18B20的唯一识别ID
-local function test_ds18b20()
-    local succ, rx_data
-    local id = zbuff.create(8)
-    local crc8c
-    onewire.init(0) -- 初始化单总线
-    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
-    id:set() -- 清空id
-    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
-    if succ then
-        if id[0] == 0x28 then
-            crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
-            if crc8c == id[7] then
-                log.info("探测到DS18B20", "18B20对应唯一ID为", id:query(0, 7):toHex())
-                read_ds18b20(id)
-                -- log.info("DS18B20离线,重新探测")
-            else
-                log.info("ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
-            end
-        else
-            log.info("ROM ID不正确", mcu.x32(id[0]))
-        end
-    else
-        log.info("没有检测到DS18B20")
-    end
-end
-
-local switchover_pin = gpio.PWR_KEY --选择powerkey作为切换18B20读数的信号脚
-
-gpio.debounce(switchover_pin, 100) --设置防抖
-
-
---设置powerkey按下和抬起的功能(18B20温度的取值再54pin和56pin之间切换)
---如果客户需要其他pin(22/54/56/78)则改动switchover_pin为用户需要的即可
---注意,由于powerkey不能做单边沿触发,所以一次按下和抬起的动作,会触发两次切换pin
---看效果的话,可以先一直按住powerkey几秒,再松开
-gpio.setup(switchover_pin, function()
-    log.info("Touch_pin", switchover_pin, "被触发")
-    log.info("当前单总线pad", onewire_pin)
-    if onewire_pin == 54 then
-        log.info("给PAD" .. onewire_pin .. "配置到GPIO3上去", pins.setup(onewire_pin, "GPIO3"))
-        log.info("给GPIO3设置为高电平输出模式",gpio.setup(3,1))--一定要执行gpio.setup,至于是哪种模式,用户根据自身需求
-        onewire_pin = 56
-    else
-        log.info("给PAD" .. onewire_pin .. "配置到GPIO7上去", pins.setup(onewire_pin, "GPIO7"))
-        log.info("给GPIO7设置为高电平输出模式",gpio.setup(7,1))
-
-        onewire_pin = 54
-    end
-    log.info("设置后单总线pad", onewire_pin)
-
-    onewire.deinit(0) -- 切换的时候一定要先关闭单总线,在读取的时候重新初始化
-
-    log.info("给" .. onewire_pin .. "配置到onewire上去", pins.setup(onewire_pin, "ONEWIRE"))
-    sys.publish("powerkey被按下")
-end, gpio.PULLUP, gpio.RISING)
-
-sys.taskInit(function()
-    while 1 do
-        -- sys.waitUntil("powerkey被按下")
-        log.info("1S后读取"..onewire_pin.."脚上的18B20")
-        sys.wait(1000)
-        log.info("开始读取18B20")
-        test_ds18b20()
-    end
-end)
-
-
-
-

+ 367 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/onewire_multi_app.lua

@@ -0,0 +1,367 @@
+--[[
+@module  onewire_multi_app
+@summary OneWire多DS18B20温度传感器应用演示模块(54和23切换版本)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示多DS18B20温度传感器的完整功能:
+1. 双传感器切换控制(引脚54和23)
+2. 电源管理(GPIO控制)
+3. 按键切换传感器
+4. 双路温度同时监测
+5. 使用引脚复用功能(pins.setup)
+]]
+
+log.info("onewire_multi_app", "多传感器模块版本: 1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- 和GPIO31控制传感器电源使能,确保DS18B20供电正常
+gpio.setup(31, 1)
+
+-- 硬件配置(双设备模式:支持引脚54和23切换)
+local onewire_pin = 54
+local switchover_pin = gpio.PWR_KEY
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_READ_ROM = 0x33
+
+-- 全局状态变量
+local pwr_key_pressed = false
+
+-- PWR_KEY按键中断处理函数
+-- 功能:处理引脚切换按键事件,设置标志位供主循环查询
+local function handle_pwr_key_interrupt()
+    pwr_key_pressed = true
+    log.info("onewire_multi_app", "切换按键被按下")
+end
+
+-- 初始化硬件配置
+local function init_hardware()
+    log.info("onewire_multi_app", "初始化硬件配置...")
+    
+    -- 配置PWR_KEY按键,使用上升沿触发并添加防抖
+    gpio.debounce(switchover_pin, 100)
+    gpio.setup(switchover_pin, handle_pwr_key_interrupt, gpio.PULLUP, gpio.RISING)
+    
+    -- 初始配置当前引脚为ONEWIRE功能
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    log.info("onewire_multi_app", "硬件初始化完成")
+    log.info("onewire_multi_app", "初始引脚: 引脚" .. onewire_pin .. " (ONEWIRE功能)")
+    log.info("onewire_multi_app", "切换按键: PWR_KEY")
+    log.info("onewire_multi_app", "支持引脚: 54 和 23 循环切换")
+    log.info("onewire_multi_app", "电源控制: GPIO31/GPIO2 (已设置为高电平)")
+    
+    return true
+end
+
+
+-- 时序要求:DS18B20上电后需要稳定时间,100ms延时确保电源稳定
+-- 技术背景:DS18B20在电源切换后需要tREC(恢复时间)完成内部初始化
+-- 实际测试:无延时可能导致设备检测失败或温度读取异常
+-- 建议值:最小50ms,推荐100ms以确保可靠性
+local function power_stabilization_delay()
+    log.info("onewire_multi_app", "电源稳定延时(确保DS18B20内部电路就绪)")
+    sys.wait(100)  -- DS18B20 tREC恢复时间,最小50ms,推荐100ms
+end
+
+-- 单总线分时使用引脚切换(同一条总线,分时复用)
+-- 核心逻辑:使用GPIO54和GPIO23两个引脚连接同一条OneWire总线,实现分时复用
+-- 应用场景:当需要在同一总线上分时访问不同设备时使用
+-- 技术原理:通过切换总线连接引脚,实现同一条物理总线的分时使用
+-- 切换效果:
+-- - GPIO54:当前时间段连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
+-- - GPIO23:切换到时间段连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
+-- 注意:这不是多总线并行,而是单总线的分时复用策略
+local function switch_onewire_pin()
+    log.info("onewire_multi_app", "切换OneWire引脚...")
+    
+    -- 关闭当前OneWire总线
+    onewire.deinit(0)
+    
+    
+    -- 分时复用切换逻辑
+    -- 技术原理:将当前不使用的引脚配置为GPIO功能并输出高电平
+    -- 目的:确保非活动设备处于高阻态,避免干扰当前连接的设备
+    -- 电气特性:GPIO设置为开漏输出模式,高电平由上拉电阻提供
+    if onewire_pin == 54 then
+        -- 从54切换到23
+        -- 将PIN54配置为GPIO3功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN54配置为GPIO3", pins.setup(54, "GPIO3"))
+        -- 设置GPIO3为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO3设置为高电平输出(OneWire总线空闲状态)", gpio.setup(3, 1))
+        onewire_pin = 23
+        log.info("onewire_multi_app", "切换到引脚23")
+    else
+        -- 从23切换到54
+        -- 将PIN23配置为GPIO2功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN23配置为GPIO2", pins.setup(23, "GPIO2"))
+        -- 设置GPIO2为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO2设置为高电平输出(OneWire总线空闲状态)", gpio.setup(2, 1))
+        onewire_pin = 54
+        log.info("onewire_multi_app", "切换到引脚54")
+    end
+    
+    log.info("onewire_multi_app", "当前使用引脚:", onewire_pin)
+    
+    -- 配置新引脚为ONEWIRE功能
+    -- 分时复用原理:将选中的引脚配置为OneWire功能,连接到对应设备
+    -- 连接过程:先断开之前的设备连接,再连接新的设备
+    -- 电气特性:确保当前连接的设备具有完整的OneWire通信能力
+    log.info("onewire_multi_app", "将引脚" .. onewire_pin .. "配置为ONEWIRE功能", pins.setup(onewire_pin, "ONEWIRE"))
+    
+    log.info("onewire_multi_app", "引脚切换完成,当前使用: 引脚" .. onewire_pin)
+end
+
+-- 初始化OneWire总线
+local function init_onewire_bus()
+    log.info("onewire_multi_app", "初始化OneWire总线,通道: 0")
+    
+    -- 配置当前引脚
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    -- 初始化OneWire总线
+    onewire.init(0)
+    
+    -- 配置DS18B20标准时序参数
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    
+    log.info("onewire_multi_app", "OneWire总线初始化完成,通道: 0,引脚:" .. onewire_pin)
+    
+    return true
+end
+
+-- 检测DS18B20设备是否存在(分时复用场景)
+-- 分时逻辑:在当前连接的引脚上发送复位脉冲,检测该设备响应
+-- 单总线场景:只有当前连接的引脚上的设备会响应复位脉冲
+-- 返回值:true表示当前引脚连接的设备响应,false表示无设备响应
+local function detect_ds18b20_device()
+    log.info("onewire_multi_app", "检测DS18B20设备,引脚: " .. onewire_pin)
+    
+    -- 发送复位脉冲并检测设备
+    local present = onewire.reset(0, true)
+    
+    if present then
+        log.info("onewire_multi_app", "检测到DS18B20设备响应")
+        return true
+    else
+        log.warn("onewire_multi_app", "未检测到DS18B20设备响应")
+        return false
+    end
+end
+
+-- 读取DS18B20温度(单总线分时复用)
+-- 核心流程:读ROM ID → 选设备 → 温度转换 → 读数据 → CRC校验
+local function read_ds18b20_temperature()
+    log.info("onewire_multi_app", "开始读取DS18B20温度,引脚: " .. onewire_pin)
+    
+    local tbuff = zbuff.create(10)
+    local succ, crc8c, range, t
+    local rbuff = zbuff.create(9)
+    
+    -- 读取设备ROM ID(每个设备唯一)
+    log.info("onewire_multi_app", "读取设备ROM ID(64位唯一标识)")
+    
+    local id = zbuff.create(8)
+    id:set()
+    
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "读取ROM ID失败")
+        return nil
+    end
+    
+    -- 检查设备类型码(DS18B20应为0x28)
+    if id[0] ~= 0x28 then
+        log.warn("onewire_multi_app", "非DS18B20设备,类型码:", mcu.x32(id[0]))
+        return nil
+    end
+    
+    -- CRC校验设备ID
+    crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
+    if crc8c ~= id[7] then
+        log.warn("onewire_multi_app", "ROM ID CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(id[7]))
+        log.info("onewire_multi_app", "完整ROM ID:", id:query(0, 7):toHex())
+        return nil
+    end
+    
+    log.info("onewire_multi_app", "ROM ID校验成功:", id:query(0, 7):toHex())
+    
+    -- 通过MATCH ROM选择设备(确保只选中目标设备)
+    log.info("onewire_multi_app", "开始温度转换(通过ROM匹配选择设备)")
+    
+    -- 构建命令缓冲区:MATCH ROM(0x55) + 目标设备ROM ID + 温度转换命令(0x44)
+    -- 0x55是MATCH ROM命令,后面必须跟64位目标设备的ROM ID
+    tbuff:write(0x55)     -- MATCH ROM命令
+    tbuff:copy(nil, id)  -- 复制64位ROM ID(确保选择正确的设备)
+    tbuff:write(0xb8)
+    tbuff[tbuff:used() - 1] = 0x44  -- CONVERT T温度转换命令
+    
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送温度转换命令失败")
+        return nil
+    end
+
+    -- 第三步:等待转换完成
+    log.info("onewire_multi_app", "等待温度转换完成")
+    
+    -- 等待一段时间让转换完成
+    sys.wait(750)
+    
+    -- 发送复位脉冲检查设备
+    succ = onewire.reset(0, true)
+    if not succ then
+        log.warn("onewire_multi_app", "等待转换完成时设备未响应")
+        return nil
+    end
+    
+    -- 检查转换是否完成
+    if onewire.bit(0) > 0 then
+        log.info("onewire_multi_app", "温度转换完成")
+    end
+    
+    -- 第四步:读取温度数据
+    log.info("onewire_multi_app", "读取温度数据")
+    
+    -- 构建读取命令:匹配ROM(0x55) + ROM ID + 读取暂存器命令(0xBE)
+    tbuff[tbuff:used() - 1] = 0xbe
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送读取命令失败")
+        return nil
+    end
+    
+    -- 接收9字节温度数据
+    succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+    if not succ then
+        log.warn("onewire_multi_app", "温度数据接收失败")
+        return nil
+    end
+    
+    -- 第五步:CRC校验和温度计算
+    log.info("onewire_multi_app", "CRC校验和温度计算")
+    
+    -- CRC校验
+    crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
+    if crc8c == rbuff[8] then
+        -- 计算温度值
+        range = (rbuff[4] >> 5) & 0x03
+        t = rbuff:query(0, 2, false, true)
+        t = t * (5000 >> range)
+        t = t / 10000
+        
+        -- 范围检查
+        if t >= -55.0 and t <= 125.0 then
+            log.info("onewire_multi_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_multi_app", "温度值超出有效范围:", t)
+            return nil
+        end
+    else
+        log.warn("onewire_multi_app", "温度数据CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(rbuff[8]))
+        return nil
+    end
+end
+
+-- 简化版温度读取(用于快速测试)
+local function quick_read_ds18b20()
+    log.info("onewire_multi_app", "快速读取温度,引脚: " .. onewire_pin)
+    
+    -- 首先检测设备是否存在
+    if not detect_ds18b20_device() then
+        return nil
+    end
+    
+    -- 使用完整读取函数
+    return read_ds18b20_temperature()
+end
+
+-- 单总线分时复用主函数(同一条总线,分时访问不同设备)
+local function multi_sensor_app_main()
+    log.info("onewire_multi_app", "启动双传感器应用(引脚54和23)")
+    
+    -- 初始化硬件
+    if not init_hardware() then
+        log.error("onewire_multi_app", "硬件初始化失败,任务无法启动")
+        return
+    end
+    
+    -- 初始化OneWire总线
+    init_onewire_bus()
+    
+    -- 电源稳定延时:确保DS18B20内部电路就绪
+    power_stabilization_delay()
+    
+    -- 检测设备
+    local device_present = detect_ds18b20_device()
+    
+    if not device_present then
+        log.error("onewire_multi_app", "未检测到设备响应")
+        log.warn("onewire_multi_app", "硬件连接提示:")
+        log.warn("onewire_multi_app", "1. 传感器连接引脚54或23")
+        log.warn("onewire_multi_app", "2. 确保GPIO31/GPIO2已设置为高电平供电")
+        log.warn("onewire_multi_app", "3. 确保4.7kΩ上拉电阻正确安装")
+        log.warn("onewire_multi_app", "4. 检查传感器VDD、GND、DQ连接")
+        -- 关闭OneWire总线
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_multi_app", "开始双传感器连续监测...")
+    log.info("onewire_multi_app", "按PWR_KEY按键可切换引脚(54和23)")
+    
+  -- 主循环:按键切换设备,分时读取温度
+    local read_count = 0
+    local success_count = 0
+    
+    while true do
+        read_count = read_count + 1
+        
+        -- 检查按键状态
+        if pwr_key_pressed then
+            pwr_key_pressed = false
+            switch_onewire_pin()
+            
+            -- 重新初始化OneWire总线
+            init_onewire_bus()
+        end
+        
+        log.info("onewire_multi_app", "第" .. read_count .. "次读取,引脚:" .. onewire_pin)
+        
+        -- 尝试读取温度
+        local temperature = read_ds18b20_temperature()
+        
+        if temperature then
+            success_count = success_count + 1
+            log.info("onewire_multi_app", "引脚" .. onewire_pin .. "温度:", 
+                    string.format("%.2f°C", temperature), 
+                    "成功率:", string.format("%.1f%%", success_count/read_count*100))
+            
+            -- 简单的温度报警逻辑
+            if temperature > 30 then
+                log.warn("onewire_multi_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_multi_app", "温度偏低:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_multi_app", "本次读取失败")
+            log.info("onewire_multi_app", "成功率:", string.format("%.1f%%", success_count/read_count*100))
+        end
+        
+        -- 等待下一次读取
+        sys.wait(2000)
+    end
+end
+log.info("onewire_multi_app", "双传感器应用模块加载完成(54和23切换)")
+-- 启动多传感器应用任务
+sys.taskInit(multi_sensor_app_main)
+

+ 0 - 108
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/onewire_single_18b20/main.lua

@@ -1,108 +0,0 @@
-PROJECT = "onewiredemo"
-VERSION = "1.0.0"
-sys = require("sys")
-log.style(1)
-
---[[
-接线说明:
-   DS18B20    Air780EPM
-1. GND    -> GND
-2. VDD    -> 3.3V
-3. DATA    -> GPIO2
-
-注意:
-1. 3.3v在老版本的开发板上没有引脚, 所以需要外接, 一定要确保共地
-2. ONEWIRE功能支持在4个引脚使用, 但硬件通道只有一个, 默认是GPIO2
-3. 如需切换到其他脚, 参考如下切换逻辑, 选其中一种
-
-]]
-
-local function read_ds18b20(id)
-    local tbuff = zbuff.create(10)
-    local succ,crc8c,range,t
-    local rbuff = zbuff.create(9)
-    --如果有多个DS18B20,需要带上ID
-    tbuff:write(0x55)
-    tbuff:copy(nil, id)
-    tbuff:write(0xb8)
-    --如果只有1个DS18B20,就用无ID方式
-    --tbuff:write(0xcc,0xb8)
-    while true do
-        tbuff[tbuff:used() - 1] = 0x44
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        while true do
-            succ = onewire.reset(0, true)
-            if not succ then
-                return
-            end
-            if onewire.bit(0) > 0 then
-                log.info("温度转换完成")
-                break
-            end
-            sys.wait(10)
-        end
-        tbuff[tbuff:used() - 1] = 0xbe
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        succ,rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
-        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
-        if crc8c == rbuff[8] then
-            range = (rbuff[4] >> 5) & 0x03
-            -- rbuff[0] = 0xF8
-            -- rbuff[1] = 0xFF
-            t = rbuff:query(0,2,false,true)
-            t = t * (5000 >> range)
-            t = t / 10000
-            log.info(t)
-        else
-            log.info("RAM DATA CRC校验不对",  mcu.x32(crc8c), mcu.x32(rbuff[8]))
-            return
-        end
-        sys.wait(500)
-    end
-end
-
-local function test_ds18b20()
-    local succ,rx_data
-    local id = zbuff.create(8)
-
-    local crc8c
-    onewire.init(0)
-    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
-    while true do
-        id:set() --清空id
-        succ,rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
-        if succ then
-            if id[0] == 0x28 then
-                crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
-                if crc8c == id[7] then
-                    log.info("探测到DS18B20", id:query(0, 7):toHex())
-                    read_ds18b20(id)
-                    log.info("DS18B20离线,重新探测")
-                else
-                    log.info("ROM ID CRC校验不对",  mcu.x32(crc8c), mcu.x32(id[7]))
-                end
-            else
-                log.info("ROM ID不正确", mcu.x32(id[0]))
-            end
-        end
-        log.info("没有检测到DS18B20, 5秒后重试")
-        sys.wait(5000)
-
-    end
-    
-
-end
-
-if onewire then
-    sys.taskInit(test_ds18b20)
-else
-    log.info("no onewire")
-end
-
-sys.run()

+ 203 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/onewire_single_app.lua

@@ -0,0 +1,203 @@
+--[[
+@module  onewire_single_app
+@summary OneWire单DS18B20温度传感器应用演示模块(GPIO2默认模式)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示单DS18B20温度传感器的完整功能:
+1. 使用GPIO2默认OneWire功能
+2. 硬件通道0模式,无需引脚复用
+3. 优化的时序参数和错误处理
+4. 连续温度监测
+5. 完整的OneWire API接口演示
+]]
+
+
+log.info("onewire_single_app", "单传感器模块版本:1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_SKIP_ROM = 0xCC
+local CMD_READ_ROM = 0x33
+
+-- 单传感器应用主函数
+local function single_sensor_app_main()
+    log.info("onewire_single_app", "启动单传感器应用")
+    
+    -- 初始化OneWire总线(使用硬件通道0模式)
+    log.info("onewire_single_app", "初始化OneWire总线...")
+    onewire.init(0)
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    log.info("onewire_single_app", "OneWire总线初始化完成,使用GPIO2默认引脚")
+    
+    
+    
+    -- 检测DS18B20设备
+    log.info("onewire_single_app", "检测DS18B20设备...")
+    
+    local succ, rx_data
+    local id = zbuff.create(8)
+    local crc8c
+    
+    -- 清空ID缓冲区
+    id:set()
+    
+    -- 读取设备ROM ID(使用手动配置的引脚)
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    
+    local detected = false
+    local device_id = nil
+    
+    if succ then
+        -- 检查家族码(DS18B20为0x28)
+        if id[0] == 0x28 then
+            -- CRC校验
+            crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
+            if crc8c == id[7] then
+                log.info("onewire_single_app", "探测到DS18B20", id:query(0, 7):toHex())
+                detected = true
+                device_id = id
+            else
+                log.warn("onewire_single_app", "ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
+            end
+        else
+            log.warn("onewire_single_app", "ROM ID不正确", mcu.x32(id[0]))
+        end
+    else
+        log.warn("onewire_single_app", "未检测到DS18B20设备,请检查硬件连接")
+        log.info("onewire_single_app", "硬件连接提示:")
+        log.info("onewire_single_app", "1. DS18B20 DATA引脚 -> GPIO2 (默认OneWire功能)")
+        log.info("onewire_single_app", "2. 确保上拉电阻4.7kΩ连接DATA到3.3V")
+        log.info("onewire_single_app", "3. 使用硬件通道0模式,无需引脚复用配置")
+    end
+    
+    if not detected then
+        log.warn("onewire_single_app", "设备检测失败,任务无法启动")
+        log.info("onewire_single_app", "单传感器应用启动完成")
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_single_app", "开始连续温度监测...")
+    
+    -- 读取DS18B20温度数据(单总线单设备模式)
+    -- 与多传感器模式的对比:
+    -- - 单传感器:使用SKIP ROM(0xCC)直接通信,无需ROM ID
+    -- - 多传感器:使用MATCH ROM(0x55)选择设备,需要目标ROM ID
+    -- 
+    -- 单设备读取流程:
+    -- 1. SKIP ROM:发送0xCC命令,跳过ROM ID识别
+    -- 2. 温度转换:发送CONVERT T(0x44)启动温度转换
+    -- 3. 读取数据:发送READ SCRATCHPAD(0xBE)读取温度数据
+    -- 4. CRC校验:验证数据完整性
+    -- 
+    -- 优势:通信简单高效,无需设备寻址
+    -- 限制:只能用于总线上只有一个设备的场景
+    local function read_temperature(dev_id)
+        local tbuff = zbuff.create(10)
+        local rbuff = zbuff.create(9)
+        local succ, crc8c, range, t
+        
+        -- 发送SKIP ROM命令(0xCC) - 跳过ROM识别,直接与设备通信
+        -- 工作原理:所有设备都会响应SKIP ROM命令,无需发送64位ROM ID
+        -- 适用场景:总线上只有一个设备,无需设备寻址和选择
+        -- 优势:通信效率高,无需传输ROM ID,简化通信流程
+        -- 风险:如果总线上有多个设备,所有设备会同时响应,造成冲突
+        tbuff:write(0xcc)
+        
+        -- 发送温度转换命令
+        tbuff[tbuff:used() - 1] = 0x44
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送温度转换命令失败")
+            return nil
+        end
+        
+        -- 等待转换完成(使用位检测)
+        local conversion_complete = false
+        local max_wait = 100
+        local wait_count = 0
+        
+        while wait_count < max_wait do
+            succ = onewire.reset(0, true)
+            if not succ then
+                log.warn("onewire_single_app", "等待转换完成时设备未响应")
+                return nil
+            end
+            if onewire.bit(0) > 0 then
+                log.info("onewire_single_app", "温度转换完成")
+                conversion_complete = true
+                break
+            end
+            sys.wait(10)
+            wait_count = wait_count + 1
+        end
+        
+        if not conversion_complete then
+            log.warn("onewire_single_app", "温度转换超时")
+            return nil
+        end
+        
+        -- 读取温度数据
+        tbuff[tbuff:used() - 1] = 0xBE
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送读取命令失败")
+            return nil
+        end
+        
+        succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+        if not succ or rbuff:used() ~= 9 then
+            log.warn("onewire_single_app", "温度数据读取失败")
+            return nil
+        end
+        
+        -- CRC校验
+        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
+        if crc8c == rbuff[8] then
+            range = (rbuff[4] >> 5) & 0x03
+            t = rbuff:query(0,2,false,true)
+            t = t * (5000 >> range)
+            t = t / 10000
+            log.info("onewire_single_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_single_app", "RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
+            return nil
+        end
+    end
+    
+    -- 主循环 - 连续温度监测
+    while true do
+        local temperature = read_temperature(device_id)
+        
+        if temperature then
+            -- 简单的温度报警逻辑(示例)
+            if temperature > 30 then
+                log.warn("onewire_single_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_single_app", "温度偏低:", string.format("%.2f°C", temperature))
+            else
+                log.info("onewire_single_app", "温度正常:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_single_app", "本次读取失败,继续下一次")
+        end
+        
+        -- 等待下一次读取
+        sys.wait(3000)
+    end
+    
+    log.info("onewire_single_app", "单传感器连续读取任务结束")
+    log.info("onewire_single_app", "单传感器应用启动完成")
+end
+
+log.info("onewire_single_app", "单传感器应用模块加载完成")
+
+-- 启动单传感器应用任务
+sys.taskInit(single_sensor_app_main)

+ 212 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/onewire/readme.md

@@ -0,0 +1,212 @@
+> 王棚嶙
+
+# OneWire综合演示项目
+
+## 功能模块介绍
+
+本demo演示了完整的DS18B20温度传感器OneWire单总线协议实现。项目采用模块化架构,分别实现单传感器和多传感器应用场景。
+
+1、main.lua:主程序入口 <br> 
+2、onewire_single_app.lua:演示单传感器功能模块(GPIO2默认OneWire功能,硬件通道0模式,3秒间隔连续监测)<br> 
+3、onewire_multi_app.lua:演示多传感器功能模块(引脚54/23切换,PWR_KEY按键控制,2秒间隔双路监测)<br> 
+
+## 演示功能概述
+
+###  主程序入口模块 (main.lua)
+
+- 初始化项目信息和版本号
+- 初始化看门狗,并定时喂狗
+- 启动一个循环定时器,每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
+- 加载onewire_single_app模块(通过require "onewire_single_app")
+- 加载onewire_multi_app模块(通过require "onewire_multi_app")
+
+### 单传感器模式 (onewire_single_app.lua)
+- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
+- 完整的CRC8数据校验机制,确保数据可靠性
+- 设备自动识别和ROM验证,支持设备类型检测
+- 3秒间隔连续温度监测,实时温度报警功能
+- zbuff缓冲区优化,提高数据传输效率
+
+
+### 多传感器模式 (onewire_multi_app.lua - 单总线多设备演示)
+
+
+**单总线多设备挂载原理**:
+1. **物理连接**:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
+2. **设备识别**:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
+3. **总线扫描**:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
+4. **设备选择**:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
+5. **分时操作**:每次只与一个设备通信,避免总线冲突
+
+**分时复用测试逻辑**(按键切换设备):
+- **引脚54**:连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
+- **引脚23**:连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
+- **PWR_KEY按键**:按一次切换一个设备,实现同一条总线的分时使用
+
+**核心测试流程**:
+1. 初始化当前引脚的OneWire总线
+2. 发送SEARCH ROM命令扫描总线上的设备
+3. 读取并验证设备的64位ROM ID(家族码+序列号+CRC)
+4. 使用MATCH ROM(0x55)命令选择目标设备
+5. 发送温度转换命令(0x44)并等待完成
+6. 读取温度数据并进行CRC校验
+7. 输出设备ROM ID、温度值、读取成功率
+
+
+
+## 演示硬件环境
+1、Air780EPM核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、ds18b20传感器两个
+
+4、Air780EPM核心板和数据线的硬件接线方式为
+
+- Air780EPM核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
+
+- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
+
+5、Air780EPM核心板和ds18b20传感器接线方式
+
+### 单传感器连接
+
+|   Air780EPM核心板     |    DS18B20传感器    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    23/GPIO2     |         DQ         |
+|    GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air780epm/luatos/app/driver/onewire/image/ce9d3b2c9b3a36c22388d710913668a7.jpg)
+
+### 多传感器连接
+
+
+|   Air780EPM核心板     |    DS18B20传感器1    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    23/GPIO2     |         DQ         |
+|    任意GND          |         GND        |
+
+|   Air780EPM核心板     |    DS18B20传感器2    |
+| --------------- | -------------------|
+|    32/GPIO31         |         VCC        |
+|    54/CAM_MCLK     |         DQ         |
+|    任意GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air780epm/luatos/app/driver/onewire/image/1957f5eb447654ec31894efb589e809b.jpg)
+
+## 演示软件环境
+
+1、Luatools下载调试工具: https://docs.openluat.com/air780epm/common/Luatools/
+
+2、内核固件版本:
+Air780EPM:https://docs.openluat.com/air780epm/luatos/firmware/version/
+
+## 演示核心步骤
+1、搭建好硬件环境
+
+2、通过Luatools将demo与固件烧录到核心板或开发板中
+
+3、烧录好后,板子开机将会在Luatools上看到如下打印:
+
+```lua
+(1)单传感器演示
+[2025-11-24 23:46:59.904][000000000.251] I/user.main onewire_demo 1.0.0
+[2025-11-24 23:46:59.932][000000000.258] I/user.onewire_single_app 单传感器模块版本: 002.002.000
+[2025-11-24 23:46:59.970][000000000.258] I/user.onewire_single_app 单传感器应用模块加载完成
+[2025-11-24 23:47:00.002][000000000.259] I/user.onewire_single_app 启动单传感器应用
+[2025-11-24 23:47:00.032][000000000.259] I/user.onewire_single_app 初始化OneWire总线...
+[2025-11-24 23:47:00.064][000000000.259] I/user.onewire_single_app OneWire总线初始化完成,使用GPIO2默认引脚
+[2025-11-24 23:47:00.096][000000000.259] I/user.onewire_single_app 检测DS18B20设备...
+[2025-11-24 23:47:00.124][000000000.267] I/user.onewire_single_app 探测到DS18B20 2859F253000000 14
+[2025-11-24 23:47:00.159][000000000.267] I/user.onewire_single_app 开始连续温度监测...
+[2025-11-24 23:47:00.186][000000000.276] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:00.216][000000000.289] I/user.onewire_single_app 温度读取成功: 85.00°C
+[2025-11-24 23:47:00.246][000000000.290] W/user.onewire_single_app 温度偏高: 85.00°C
+[2025-11-24 23:47:00.409][000000003.299] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:00.436][000000003.312] I/user.onewire_single_app 温度读取成功: 28.25°C
+[2025-11-24 23:47:00.465][000000003.313] I/user.onewire_single_app 温度正常: 28.25°C
+[2025-11-24 23:47:03.404][000000006.322] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:03.437][000000006.335] I/user.onewire_single_app 温度读取成功: 28.25°C
+[2025-11-24 23:47:03.469][000000006.335] I/user.onewire_single_app 温度正常: 28.25°C
+
+(2)双传感器演示
+[2025-11-24 23:49:45.699][000000000.260] I/user.onewire_multi_app 双传感器应用模块加载完成(54和23切换)
+[2025-11-24 23:49:45.732][000000000.261] I/user.onewire_multi_app 启动双传感器应用(引脚54和23)
+[2025-11-24 23:49:45.761][000000000.261] I/user.onewire_multi_app 初始化硬件配置...
+[2025-11-24 23:49:45.789][000000000.261] I/user.onewire_multi_app 硬件初始化完成
+[2025-11-24 23:49:45.822][000000000.262] I/user.onewire_multi_app 初始引脚: 引脚54 (ONEWIRE功能)
+[2025-11-24 23:49:45.859][000000000.262] I/user.onewire_multi_app 切换按键: PWR_KEY
+[2025-11-24 23:49:45.898][000000000.262] I/user.onewire_multi_app 支持引脚: 54 和 23 循环切换
+[2025-11-24 23:49:45.932][000000000.262] I/user.onewire_multi_app 电源控制: GPIO31/GPIO2 (已设置为高电平)
+[2025-11-24 23:49:45.963][000000000.262] I/user.onewire_multi_app 电源控制: 开启
+[2025-11-24 23:49:45.997][000000000.363] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-24 23:49:46.026][000000000.374] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:54
+[2025-11-24 23:49:46.059][000000000.573] I/user.onewire_multi_app 检测DS18B20设备,引脚: 54
+[2025-11-24 23:49:46.089][000000000.575] I/user.onewire_multi_app 检测到DS18B20设备响应
+[2025-11-24 23:49:46.117][000000000.575] I/user.onewire_multi_app 开始双传感器连续监测...
+[2025-11-24 23:49:46.148][000000000.575] I/user.onewire_multi_app 按PWR_KEY按键可切换引脚(54和23)
+[2025-11-24 23:49:46.181][000000000.575] I/user.onewire_multi_app 第1次读取,引脚:54
+[2025-11-24 23:49:46.212][000000000.575] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:46.243][000000000.576] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:46.272][000000000.583] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:46.297][000000000.583] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:46.325][000000000.590] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:46.401][000000001.341] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:46.433][000000001.342] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:46.466][000000001.354] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:46.499][000000001.355] I/user.onewire_multi_app 温度读取成功: 27.44°C
+[2025-11-24 23:49:46.530][000000001.355] I/user.onewire_multi_app 引脚54温度: 27.44°C 成功率: 100.0%
+[2025-11-24 23:49:46.630][000000003.355] I/user.onewire_multi_app 第2次读取,引脚:54
+[2025-11-24 23:49:46.665][000000003.356] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:46.698][000000003.356] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:46.727][000000003.363] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:46.765][000000003.363] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:46.799][000000003.371] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:46.982][000000004.122] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:47.010][000000004.123] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:47.043][000000004.135] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:47.077][000000004.136] I/user.onewire_multi_app 温度读取成功: 27.50°C
+[2025-11-24 23:49:47.110][000000004.137] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
+[2025-11-24 23:49:48.999][000000006.137] I/user.onewire_multi_app 第3次读取,引脚:54
+[2025-11-24 23:49:49.030][000000006.138] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:49.061][000000006.138] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:49.094][000000006.145] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:49.124][000000006.145] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:49.154][000000006.153] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:49.778][000000006.904] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:49.806][000000006.905] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:49.836][000000006.917] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:49.866][000000006.918] I/user.onewire_multi_app 温度读取成功: 27.50°C
+[2025-11-24 23:49:49.907][000000006.919] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
+
+(3)双传感器按键切换演示
+[2025-11-24 23:49:51.147][000000008.278] I/user.onewire_multi_app 切换按键被按下
+[2025-11-24 23:49:51.783][000000008.919] I/user.onewire_multi_app 切换OneWire引脚...
+[2025-11-24 23:49:51.821][000000008.939] I/user.onewire_multi_app 将PAD54配置为GPIO3 true
+[2025-11-24 23:49:51.856][000000008.940] I/user.onewire_multi_app 将GPIO3设置为高电平输出 function: 0C7F4A10
+[2025-11-24 23:49:51.897][000000008.940] I/user.onewire_multi_app 切换到引脚23
+[2025-11-24 23:49:51.933][000000008.940] I/user.onewire_multi_app 当前使用引脚: 23
+[2025-11-24 23:49:51.965][000000008.941] I/user.onewire_multi_app 将引脚23配置为ONEWIRE功能 true
+[2025-11-24 23:49:51.994][000000008.961] I/user.onewire_multi_app 引脚切换完成,当前使用: 引脚23
+[2025-11-24 23:49:52.324][000000009.461] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-24 23:49:52.356][000000009.471] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:23
+[2025-11-24 23:49:52.431][000000009.571] I/user.onewire_multi_app 第4次读取,引脚:23
+[2025-11-24 23:49:52.474][000000009.571] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 23
+[2025-11-24 23:49:52.519][000000009.572] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:52.563][000000009.579] I/user.onewire_multi_app ROM ID校验成功: 2859F253000000 14
+[2025-11-24 23:49:52.593][000000009.579] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:52.622][000000009.587] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:53.203][000000010.338] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:53.239][000000010.339] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:53.272][000000010.351] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:53.302][000000010.352] I/user.onewire_multi_app 温度读取成功: 27.81°C
+[2025-11-24 23:49:53.332][000000010.353] I/user.onewire_multi_app 引脚23温度: 27.81°C 成功率: 100.0%
+
+
+```

+ 366 - 291
module/Air780EHM_Air780EHV_Air780EGH/demo/tf_card/tfcard_app.lua

@@ -1,341 +1,416 @@
 --[[
-@module  tfcard_app
-@summary TF卡文件操作测试模块
-@version 1.0.0
-@date    2025.08.25
-@author  王棚嶙
+@module  onewire_multi_app
+@summary OneWire多DS18B20温度传感器应用演示模块(带切换功能)
+@version 002.002.000
+@date    2025.11.25
+@author  王棚嶙
 @usage
-本文件为TF卡的文件操作测试流程:
-1. 创建目录
-2. 创建并写入文件
-3. 检查文件是否存在
-4. 获取文件大小
-5. 读取文件内容
-6. 启动计数文件操作
-7. 文件追加测试
-8. 按行读取测试
-9. 读取后关闭文件
-10. 文件重命名
-11. 列举目录内容
-12. 删除文件
-13. 删除目录
-本文件没有对外接口,直接在main.lua中require "tfcard_app"就可以加载运行
-]] 
-
-
-
-
-
-local function tfcard_main_task() -- 开始进行主测试流程。
-    -- ##########  SPI初始化 ##########
-    -- 如果使用核心板演示环境,请打开33——36行代码,同时关闭38——43行的代码。
-    -- 如果使用开发板演示环境,请打开38——43行代码,同时关闭33——36行的代码。
-    -- 在Air780EHM/EHV/EGH核心板上TF卡的的pin_cs为gpio8,spi_id为0.请根据实际硬件修改
-    spi_id, pin_cs = 0, 8
-    spi.setup(spi_id, nil, 0, 0, 400 * 1000)
-    --初始化后拉高pin_cs,准备开始挂载TF卡
-    gpio.setup(pin_cs, 1)
-
-    -- Air780EHM/EHV/EGH开发板上的pin_cs为gpio16,spi_id为0.请根据实际硬件修改
-    -- spi_id, pin_cs = 0, 16
-    -- spi.setup(spi_id, nil, 0, 0, 400 * 1000)
-    --设置片选引脚同一spi总线上的所有从设备在初始化时必须要先拉高CS脚,防止从设备之间互相干扰。
-    -- 在Air780EHM/EHV/EGH开发板上,TF卡和ch390共用SPI0总线。
-    -- gpio.setup(pin_cs, 1)
-
-    -- ########## 开始进行tf卡挂载 ##########
-    -- 挂载失败默认格式化,
-    -- 如无需格式化应改为fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000, nil, 1, false),
-    -- 一般是在测试硬件是否有问题的时候把格式化取消掉
-    mount_ok, mount_err = fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000)
-    if mount_ok then
-        log.info("fatfs.mount", "挂载成功", mount_err)
-    else
-        log.error("fatfs.mount", "挂载失败", mount_err)
-        goto resource_cleanup
-    end
-
-    -- ########## 获取SD卡的可用空间信息并打印。 ########## 
-    data, err = fatfs.getfree("/sd")
-    if data then
-        --打印SD卡的可用空间信息
-        log.info("fatfs", "getfree", json.encode(data))
-    else
-        --打印错误信息
-        log.info("fatfs", "getfree", "err", err)
-        goto resource_cleanup
+本模块演示多DS18B20温度传感器的完整功能:
+1. 多传感器切换控制
+2. 电源管理(GPIO控制)
+3. 按键切换传感器
+4. 多路温度同时监测
+5. 使用引脚复用功能(pins.setup)
+]]
+
+log.info("onewire_multi_app", "多传感器模块版本: 002.002.000")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- GPIO2和GPIO31控制电源,确保DS18B20供电正常
+gpio.setup(2, 1)  -- GPIO2输出高电平
+gpio.setup(31, 1) -- GPIO31输出高电平
+
+-- 传感器配置
+local sensor_config = {
+    {pin = 2,  channel = 0, name = "GPIO2(默认)"},    -- GPIO2使用通道0
+    {pin = 54, channel = 3, name = "引脚54(复用)"}    -- 引脚54使用通道3
+}
+
+local current_sensor = 1  -- 当前使用的传感器索引
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44     -- 温度转换命令
+local CMD_READ_SCRATCHPAD = 0xBE  -- 读取暂存器命令
+local CMD_SKIP_ROM = 0xCC      -- 跳过ROM命令
+
+-- 全局状态变量
+local task_running = false
+local switch_pressed = false
+
+-- CRC8校验函数
+local function crc8_check(data)
+    if not data or #data == 0 then
+        return false
     end
-
-    -- 列出所有挂载点,如不需要,可注释掉。
-    data = io.lsmount()
-    log.info("fs", "lsmount", json.encode(data))
-
-    -- ########## 功能: 启用fatfs调试模式 ##########
-    -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因.(设置调试模式)
-
-    -- 执行tfcard文件操作演示
-    log.info("文件操作", "===== 开始文件操作 =====")
-
-    dir_path = "/sd/io_test"
-
-    -- 1. 创建目录
-    if io.mkdir(dir_path) then
-        log.info("io.mkdir", "目录创建成功", "路径:" .. dir_path)
-    else
-        -- 检查是否目录已存在
-        if io.exists(dir_path) then
-            log.warn("io.mkdir", "目录已存在,跳过创建", "路径:" .. dir_path)
-        else
-            log.error("io.mkdir", "目录创建失败且目录不存在", "路径:" .. dir_path)
-            goto resource_cleanup
+    
+    local crc = 0
+    for i = 1, #data - 1 do
+        crc = crc ~ data:byte(i)
+        for j = 1, 8 do
+            if crc & 0x01 then
+                crc = (crc >> 1) ~ 0x8C
+            else
+                crc = crc >> 1
+            end
         end
     end
+    
+    return crc == data:byte(#data)
+end
 
-    -- 2. 创建并写入文件
-    file_path = dir_path .. "/boottime"
-    file = io.open(file_path, "wb")
-    if file then
-        file:write("这是io库API文档示例的测试内容")
-        file:close()
-        --在LuatOS文件操作中,执行file:close()是必须且关键的操作,它用于关闭文件句柄,释放资源,并确保数据被正确写入磁盘。
-        -- 如果不执行file:close(),可能会导致数据丢失、文件损坏或其他不可预测的问题。
-        log.info("文件创建", "文件写入成功", "路径:" .. file_path)
-    else
-        log.error("文件创建", "文件创建失败", "路径:" .. file_path)
-        goto resource_cleanup
+-- 计算温度值
+local function calculate_temperature(data)
+    if not data or #data < 2 then
+        log.warn("onewire_multi_app", "温度数据无效或长度不足")
+        return nil
     end
-
-    -- 3. 检查文件是否存在
-    if io.exists(file_path) then
-        log.info("io.exists", "文件存在", "路径:" .. file_path)
-    else
-        log.error("io.exists", "文件不存在", "路径:" .. file_path)
-        goto resource_cleanup
+    
+    local temp_raw = data:byte(1) + (data:byte(2) * 256)
+    
+    if temp_raw > 32767 then
+        temp_raw = temp_raw - 65536
     end
-
-    -- 4. 获取文件大小
-    file_size = io.fileSize(file_path)
-    if file_size then
-        log.info("io.fileSize", "文件大小:" .. file_size .. "字节", "路径:" .. file_path)
-    else
-        log.error("io.fileSize", "获取文件大小失败", "路径:" .. file_path)
-        goto resource_cleanup
+    
+    local temperature = temp_raw * 0.0625
+    
+    if temperature < -55.0 or temperature > 125.0 then
+        log.warn("onewire_multi_app", "温度值超出有效范围:", temperature)
+        return nil
     end
+    
+    return temperature
+end
 
-    -- 5. 读取文件内容
-    file = io.open(file_path, "rb")
-    if file then
-        content = file:read("*a")
-        log.info("文件读取", "路径:" .. file_path, "内容:" .. content)
-        file:close()
-    else
-        log.error("文件操作", "无法打开文件读取内容", "路径:" .. file_path)
-        goto resource_cleanup
+-- 电源控制函数
+local function power_control(on)
+    log.info("onewire_multi_app", "电源控制:", on and "开启" or "关闭")
+    if on then
+        sys.wait(100)  -- 等待电源稳定
     end
+    return true
+end
 
-    -- 6. 启动计数文件操作
-    count = 0
-    --以只读模式打开文件
-    file = io.open(file_path, "rb")
-    if file then
-        data = file:read("*a")
-        log.info("启动计数", "文件内容:", data, "十六进制:", data:toHex())
-        count = tonumber(data) or 0
-        file:close()
-    else
-        log.warn("启动计数", "文件不存在或无法打开")
-
+-- 初始化指定传感器
+local function init_sensor(sensor_idx)
+    local config = sensor_config[sensor_idx]
+    
+    log.info("onewire_multi_app", "初始化传感器:", config.name, "引脚:", config.pin, "通道:", config.channel)
+    
+    if config.pin == 54 then
+        pins.setup(config.pin, "ONEWIRE")
+        log.info("onewire_multi_app", "配置引脚54为ONEWIRE复用功能")
     end
+    
+    onewire.init(config.channel)
+    onewire.timing(config.channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
+    
+    log.info("onewire_multi_app", "传感器初始化完成:", config.name)
+    return config.channel
+end
 
-    log.info("启动计数", "当前值:", count)
-    count=count + 1
-    log.info("启动计数", "更新值:", count)
-
-    file = io.open(file_path, "wb")
-    if file then
-        file:write(tostring(count))
-        file:close()
-        log.info("文件写入", "路径:" .. file_path, "内容:", count)
+-- 检测DS18B20设备是否存在
+local function detect_ds18b20_device(channel)
+    local present = onewire.reset(channel, true)
+    if present then
+        log.info("onewire_multi_app", "通道", channel, "检测到DS18B20设备")
     else
-        log.error("文件写入", "无法打开文件", "路径:" .. file_path)
-        goto resource_cleanup
+        log.warn("onewire_multi_app", "通道", channel, "未检测到DS18B20设备")
     end
+    return present
+end
 
-    -- 7. 文件追加测试
-    append_file = dir_path .. "/test_a"
-    -- 清理旧文件
-    os.remove(append_file)
+-- 初始化OneWire总线
+local function init_onewire_bus(channel)
+    log.info("onewire_multi_app", "初始化OneWire总线,通道:", channel)
+    onewire.init(channel)
+    onewire.timing(channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
+    log.info("onewire_multi_app", "OneWire总线初始化完成,通道:", channel)
+    return true
+end
 
-    -- 创建并写入初始内容
-    file = io.open(append_file, "wb")
-    if file then
-        file:write("ABC")
-        file:close()
-        log.info("文件创建", "路径:" .. append_file, "初始内容:ABC")
-    else
-        log.error("文件创建", "无法创建文件", "路径:" .. append_file)
-        goto resource_cleanup
+-- 读取DS18B20温度
+local function read_ds18b20_temperature(channel)
+    log.info("onewire_multi_app", "读取DS18B20温度,通道:", channel)
+    
+    local tbuff = zbuff.create(2)
+    local rbuff = zbuff.create(9)
+    
+    local present = onewire.reset(channel, true)
+    if not present then
+        log.warn("onewire_multi_app", "通道", channel, "设备未响应")
+        return nil
     end
-
-    -- 追加内容
-    file = io.open(append_file, "a+")
-    if file then
-        file:write("def")
-        file:close()
-        log.info("文件追加", "路径:" .. append_file, "追加内容:def")
-    else
-        log.error("文件追加", "无法打开文件进行追加", "路径:" .. append_file)
-        goto resource_cleanup
-
+    
+    tbuff:set(0, CMD_SKIP_ROM)
+    tbuff:set(1, CMD_CONVERT_T)
+    local succ = onewire.tx(channel, tbuff, 0, 2, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "通道", channel, "发送温度转换命令失败")
+        return nil
     end
-
-    -- 验证追加结果
-    file = io.open(append_file, "r")
-    if file then
-        data = file:read("*a")
-        log.info("文件验证", "路径:" .. append_file, "内容:" .. data, "结果:",
-            data == "ABCdef" and "成功" or "失败")
-        file:close()
-    else
-        log.error("文件验证", "无法打开文件进行验证", "路径:" .. append_file)
-        goto resource_cleanup
+    
+    log.info("onewire_multi_app", "等待温度转换完成...")
+    sys.wait(750)
+    
+    local succ = onewire.reset(channel, true)
+    if not succ then
+        log.warn("onewire_multi_app", "通道", channel, "读取时设备未响应")
+        return nil
     end
-
-    -- 8. 按行读取测试
-    line_file = dir_path .. "/testline"
-    file = io.open(line_file, "w")
-    if file then
-        file:write("abc\n")
-        file:write("123\n")
-        file:write("wendal\n")
-        file:close()
-        log.info("文件创建", "路径:" .. line_file, "写入3行文本")
-    else
-        log.error("文件创建", "无法创建文件", "路径:" .. line_file)
-        goto resource_cleanup
+    
+    tbuff:set(0, CMD_SKIP_ROM)
+    tbuff:set(1, CMD_READ_SCRATCHPAD)
+    succ = onewire.tx(channel, tbuff, 0, 2, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "通道", channel, "发送读取命令失败")
+        return nil
     end
-
-    -- 按行读取文件
-    file = io.open(line_file, "r")
-    if file then
-        log.info("按行读取", "路径:" .. line_file, "第1行:", file:read("*l"))
-        log.info("按行读取", "路径:" .. line_file, "第2行:", file:read("*l"))
-        log.info("按行读取", "路径:" .. line_file, "第3行:", file:read("*l"))
-        file:close()
-    else
-        log.error("按行读取", "无法打开文件", "路径:" .. line_file)
-        goto resource_cleanup
+    
+    rbuff:resize(9)
+    local succ, rx_len = onewire.rx(channel, 9, nil, rbuff, 0, false, false, false)
+    if not succ or rx_len ~= 9 then
+        log.warn("onewire_multi_app", "通道", channel, "温度数据接收失败,长度:", rx_len or 0)
+        return nil
     end
-
-    -- 9. 文件重命名
-    old_path = append_file
-    new_path = dir_path .. "/renamed_file.txt"
-    success, err = os.rename(old_path, new_path)
-    if success then
-        log.info("os.rename", "文件重命名成功", "原路径:" .. old_path, "新路径:" .. new_path)
-
-        -- 验证重命名结果
-        if io.exists(new_path) and not io.exists(old_path) then
-            log.info("验证结果", "重命名验证成功", "新文件存在", "原文件不存在")
+    
+    local crc8c = crypto.crc8(rbuff:query(0,8), 0x31, 0, true)
+    if crc8c == rbuff[8] then
+        local temp_low = rbuff[0]
+        local temp_high = rbuff[1]
+        local temp_raw = temp_low + (temp_high * 256)
+        
+        if temp_raw > 32767 then
+            temp_raw = temp_raw - 65536
+        end
+        
+        local temperature = temp_raw * 0.0625
+        
+        if temperature >= -55.0 and temperature <= 125.0 then
+            log.info("onewire_multi_app", "温度读取成功,通道", channel, ":", string.format("%.2f°C", temperature))
+            return temperature
         else
-            log.error("验证结果", "重命名验证失败")
+            log.warn("onewire_multi_app", "温度值超出有效范围:", temperature)
+            return nil
         end
     else
-        log.error("os.rename", "重命名失败", "错误:" .. tostring(err), "原路径:" .. old_path)
-        goto resource_cleanup
+        log.warn("onewire_multi_app", "CRC校验失败,期望:", string.format("0x%02X", crc8c), 
+                 "实际:", string.format("0x%02X", rbuff[8]))
+        return nil
     end
+end
 
-    -- 10. 列举目录内容
-    log.info("目录操作", "===== 开始目录列举 =====")
+-- 切换传感器
+local function switch_onewire_sensor()
+    log.info("onewire_multi_app", "切换传感器...")
+    
+    local old_config = sensor_config[current_sensor]
+    onewire.deinit(old_config.channel)
+    
+    current_sensor = (current_sensor % #sensor_config) + 1
+    local new_config = sensor_config[current_sensor]
+    
+    local channel = init_sensor(current_sensor)
+    
+    log.info("onewire_multi_app", "切换到传感器:", new_config.name, "通道:", channel)
+    return channel
+end
 
-    ret, data = io.lsdir(dir_path, 50, 0) -- 50表示最多返回50个文件,0表示从目录开头开始
-    if ret then
-        log.info("fs", "lsdir", json.encode(data))
-    else
-        log.info("fs", "lsdir", "fail", ret, data)
-        goto resource_cleanup
+-- 初始化硬件
+local function init_hardware()
+    log.info("onewire_multi_app", "初始化硬件配置...")
+    
+    gpio.setup(gpio.PWR_KEY, function()
+        switch_pressed = true
+        log.info("onewire_multi_app", "切换按键被按下")
+    end, gpio.PULLUP, gpio.RISING)
+    
+    local channel = init_sensor(current_sensor)
+    local detected = detect_ds18b20_device(channel)
+    
+    if not detected then
+        log.warn("onewire_multi_app", "第一个传感器未检测到,尝试第二个传感器...")
+        current_sensor = 2
+        channel = init_sensor(current_sensor)
+        detected = detect_ds18b20_device(channel)
     end
+    
+    log.info("onewire_multi_app", "硬件初始化完成")
+    log.info("onewire_multi_app", "当前使用传感器:", sensor_config[current_sensor].name)
+    
+    return detected
+end
 
-    -- 11. 删除文件测试
-    -- 测试删除renamed_file.txt文件
-    if os.remove(new_path) then
-        log.info("os.remove", "文件删除成功", "路径:" .. new_path)
-
-        -- 验证renamed_file.txt删除结果
-        if not io.exists(new_path) then
-            log.info("验证结果", "renamed_file.txt文件删除验证成功")
-        else
-            log.error("验证结果", "renamed_file.txt文件删除验证失败")
-        end
-    else
-        log.error("io.remove", "renamed_file.txt文件删除失败", "路径:" .. new_path)
-        goto resource_cleanup
+-- 演示OneWire初始化功能
+local function demonstrate_onewire_init()
+    log.info("demo", "=== 1. 多通道onewire.init()演示 ===")
+    for i, config in ipairs(sensor_config) do
+        log.info("demo", "初始化通道", config.channel, "对应引脚", config.pin, config.name)
+        onewire.init(config.channel)
     end
+    log.info("demo", "OneWire初始化演示完成")
+end
 
-    -- 测试删除testline文件
-    if os.remove(line_file) then
-        log.info("os.remove", "testline文件删除成功", "路径:" .. line_file)
+-- 演示时序配置功能
+local function demonstrate_onewire_timing()
+    log.info("demo", "=== 2. 多通道onewire.timing()演示 ===")
+    for i, config in ipairs(sensor_config) do
+        log.info("demo", "配置通道", config.channel, "的DS18B20标准时序")
+        onewire.timing(config.channel, false, 0, 480, 70, 70, 410, 70, 10, 10, 15, 70)
+    end
+    log.info("demo", "时序配置演示完成")
+end
 
-        -- 验证删除结果
-        if not io.exists(line_file) then
-            log.info("验证结果", "testline文件删除验证成功")
-        else
-            log.error("验证结果", "testline文件删除验证失败")
-        end
-    else
-        log.error("io.remove", "testline文件删除失败", "路径:" .. line_file)
-        goto resource_cleanup
+-- 演示设备检测功能
+local function demonstrate_device_detection()
+    log.info("demo", "=== 3. 多通道设备检测演示 ===")
+    for i, config in ipairs(sensor_config) do
+        local present = onewire.reset(config.channel, true)
+        log.info("demo", "通道", config.channel, config.name, "检测状态:", present and "检测到设备" or "未检测到设备")
     end
+    log.info("demo", "设备检测演示完成")
+end
 
-    if os.remove(file_path) then
-        log.info("os.remove", "文件删除成功", "路径:" .. file_path)
+-- 演示电源控制功能
+local function demonstrate_power_control()
+    log.info("demo", "=== 4. 电源控制演示 ===")
+    power_control(true)
+    power_control(false)
+    log.info("demo", "电源控制演示完成")
+end
 
-        -- 验证删除结果
-        if not io.exists(file_path) then
-            log.info("验证结果", "boottime文件删除验证成功")
-        else
-            log.error("验证结果", "boottime文件删除验证失败")
-        end
-    else
-        log.error("io.remove", "boottime文件删除失败", "路径:" .. file_path)
-        goto resource_cleanup
+-- 演示传感器切换功能
+local function demonstrate_sensor_switching()
+    log.info("demo", "=== 5. 传感器切换功能演示 ===")
+    local original_sensor = current_sensor
+    
+    for i = 1, #sensor_config do
+        local channel = switch_onewire_sensor()
+        local detected = detect_ds18b20_device(channel)
+        log.info("demo", "切换到传感器", current_sensor, "检测状态:", detected and "成功" or "失败")
+        sys.wait(500)
     end
+    
+    current_sensor = original_sensor
+    init_sensor(current_sensor)
+    log.info("demo", "传感器切换演示完成,恢复原始传感器")
+end
 
-    -- 12. 删除目录(不能删除非空目录,所以在删除目录前要确保目录内没有文件或子目录)
-    if io.rmdir(dir_path) then
-        log.info("io.rmdir", "目录删除成功", "路径:" .. dir_path)
-
-        -- 验证删除结果
-        if not io.exists(dir_path) then
-            log.info("验证结果", "目录删除验证成功")
-        else
-            log.error("验证结果", "目录删除验证失败")
-        end
-    else
-        log.error("io.rmdir", "目录删除失败", "路径:" .. dir_path)
-        goto resource_cleanup
+-- 演示位操作功能
+local function demonstrate_bit_operations()
+    log.info("demo", "=== 6. 位操作功能演示 ===")
+    for i, config in ipairs(sensor_config) do
+        onewire.bit(config.channel, 1)
+        log.info("demo", "通道", config.channel, "发送位: 1")
+        
+        local bit_value = onewire.bit(config.channel)
+        log.info("demo", "通道", config.channel, "读取位值:", bit_value)
     end
+    log.info("demo", "位操作演示完成")
+end
+
+-- 演示调试模式功能
+local function demonstrate_debug_mode()
+    log.info("demo", "=== 7. 调试模式演示 ===")
+    log.info("demo", "调试模式当前状态: 关闭(可通过取消注释开启)")
+    -- for i, config in ipairs(sensor_config) do
+    --     onewire.debug(config.channel, true)
+    --     log.info("demo", "开启通道", config.channel, "的调试模式")
+    -- end
+    log.info("demo", "调试模式演示完成")
+end
 
-    log.info("文件操作", "===== 文件操作完成 =====")
+-- 演示资源释放功能
+local function demonstrate_resource_cleanup()
+    log.info("demo", "=== 8. 资源释放演示 ===")
+    for i, config in ipairs(sensor_config) do
+        onewire.deinit(config.channel)
+        log.info("demo", "释放通道", config.channel, "的资源")
+    end
+    log.info("demo", "资源释放演示完成")
+    
+    -- 重新初始化所有通道
+    for i, config in ipairs(sensor_config) do
+        init_sensor(i)
+    end
+end
 
-    -- ########## 功能: 收尾功能演示##########
-    -- 卸载文件系统和关闭SPI
-    ::resource_cleanup::
+-- 演示多传感器OneWire API接口
+local function demonstrate_multi_onewire_apis()
+    log.info("onewire_multi_app", "开始演示多传感器OneWire API接口...")
+    
+    demonstrate_onewire_init()
+    demonstrate_onewire_timing()
+    demonstrate_device_detection()
+    demonstrate_power_control()
+    demonstrate_sensor_switching()
+    demonstrate_bit_operations()
+    demonstrate_debug_mode()
+    demonstrate_resource_cleanup()
+    
+    log.info("onewire_multi_app", "多传感器API演示完成")
+end
 
-    log.info("结束", "开始执行关闭操作...")  
-    -- 如已挂载需先卸载文件系统,未挂载直接关闭SPI
-    if mount_ok then
-        if fatfs.unmount("/sd") then
-            log.info("文件系统", "卸载成功")
+-- 多传感器应用主函数
+local function multi_sensor_app_main()
+    log.info("onewire_multi_app", "启动多传感器应用")
+    
+    if not init_hardware() then
+        log.error("onewire_multi_app", "所有传感器都未检测到,请检查硬件连接")
+        log.warn("onewire_multi_app", "硬件连接提示:")
+        log.warn("onewire_multi_app", "1. 传感器1连接GPIO2 (默认OneWire功能)")
+        log.warn("onewire_multi_app", "2. 传感器2连接引脚54 (复用为GPIO3/ONEWIRE)")
+        log.warn("onewire_multi_app", "3. 确保GPIO31/GPIO2已设置为高电平供电")
+        return
+    end
+    
+    task_running = true
+    log.info("onewire_multi_app", "开始多传感器连续监测...")
+    log.info("onewire_multi_app", "按PWR_KEY按键可切换传感器")
+    
+    while task_running do
+        if switch_pressed then
+            switch_pressed = false
+            switch_onewire_sensor()
+        end
+        
+        local config = sensor_config[current_sensor]
+        local temperature = read_ds18b20_temperature(config.channel)
+        
+        if temperature then
+            log.info("onewire_multi_app", 
+                "传感器" .. current_sensor .. "(" .. config.name .. "):", 
+                string.format("%.2f°C", temperature))
         else
-            log.error("文件系统", "卸载失败")
+            log.warn("onewire_multi_app", "传感器" .. current_sensor .. "读取失败")
         end
+        
+        sys.wait(1000)
+    end
+    
+    for i, config in ipairs(sensor_config) do
+        onewire.deinit(config.channel)
     end
+    
+    log.info("onewire_multi_app", "多传感器应用结束")
+end
 
-    -- 2. 关闭SPI接口
-    spi.close(spi_id)
-    log.info("SPI接口", "已关闭")
+-- 启动多传感器应用任务
+local function start_multi_sensor_app()
+    sys.taskInit(function()
+        demonstrate_multi_onewire_apis()
+        multi_sensor_app_main()
+    end)
+end
 
+-- 模块初始化函数
+local function init_module()
+    log.info("onewire_multi_app", "多传感器应用模块初始化")
+    start_multi_sensor_app()
 end
 
-sys.taskInit(tfcard_main_task)
+-- 启动模块
+init_module()
+
+log.info("onewire_multi_app", "多传感器应用模块加载完成")

+ 65 - 0
module/Air780EPM/demo/onewire/main.lua

@@ -0,0 +1,65 @@
+--[[
+@module  main
+@summary OneWire综合演示项目主文件(单传感器 + 多传感器)
+@version 001.000.000
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本演示项目整合单DS18B20和多DS18B20传感器功能:
+1. 单传感器模式:GPIO2默认OneWire功能、硬件通道0模式、CRC校验、3秒间隔连续监测
+2. 多传感器模式:引脚54/23切换、PWR_KEY按键控制、电源管理、2秒间隔双路监测
+3. 完整的OneWire API接口演示、错误处理、设备检测、温度报警
+]]
+
+-- 项目信息
+PROJECT = "onewire_demo"
+VERSION = "001.000.000"
+
+
+
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
+
+--添加硬狗防止程序卡死
+if wdt then
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
+
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
+
+-- 在加载以下两个功能的时候建议分别打开,避免同时初始化OneWire总线,导致资源冲突
+-- 单设备模式:使用GPIO2默认OneWire功能
+-- 双设备模式:GPIO2默认 + 引脚54复用
+
+-- 加载单传感器应用模块
+-- require("onewire_single_app")
+
+-- 加载多传感器应用模块
+require("onewire_multi_app")
+
+
+-- 启动系统主循环
+sys.run()

+ 0 - 9
module/Air780EPM/demo/onewire/onewire_multi_18b20_swich_read/main.lua

@@ -1,9 +0,0 @@
-PROJECT = "DS18B20_GPIO_SWITCH_READ_temperature"
-VERSION = "1.0.0"
-sys = require("sys")
-log.style(1)
-
-
-require"switch_read"
-
-sys.run()

+ 0 - 125
module/Air780EPM/demo/onewire/onewire_multi_18b20_swich_read/switch_read.lua

@@ -1,125 +0,0 @@
-
-pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) -- 所有GPIO高电平输出3.3V(方便使用VDD_EXT给18B20供电)
-gpio.setup(2, 1) --GPIO2控制780EPM开发板V1.3版本camera电源打开和关闭
-gpio.setup(31, 1) -- GPIO31控制780EPM开发板V1.4版本camera电源打开和关闭
-
-local onewire_pin = 54 --18B20接的pin 54脚
-
-
-pins.setup(onewire_pin, "ONEWIRE") -- PAD54脚既是GPIO3也是cam_mclk 
-
---读取当前pin脚上的18B20温度
-local function read_ds18b20(id)
-log.info("读取温度",id)
-    local tbuff = zbuff.create(10)
-    local succ, crc8c, range, t
-    local rbuff = zbuff.create(9)
-    tbuff:write(0x55)
-    tbuff:copy(nil, id)
-    tbuff:write(0xb8)
-  
-    tbuff[tbuff:used() - 1] = 0x44
-    succ = onewire.tx(0, tbuff, false, true, true)
-    if not succ then
-        return
-    end
-
-    succ = onewire.reset(0, true)
-    if not succ then
-        return
-    end
-    if onewire.bit(0) > 0 then
-        log.info("温度转换完成")
-    end
-    tbuff[tbuff:used() - 1] = 0xbe
-    succ = onewire.tx(0, tbuff, false, true, true)
-    if not succ then
-        return
-    end
-    succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
-    crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
-    if crc8c == rbuff[8] then
-        range = (rbuff[4] >> 5) & 0x03
-        -- rbuff[0] = 0xF8
-        -- rbuff[1] = 0xFF
-        t = rbuff:query(0, 2, false, true)
-        t = t * (5000 >> range)
-        t = t / 10000
-        log.info("当前温度", t,"原始值为",mcu.x32(rbuff[8]))
-    else
-        log.info("RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
-        return
-    end
-
-end
-
---初始化当前pin脚上的18B20,并读取18B20的唯一识别ID
-local function test_ds18b20()
-    local succ, rx_data
-    local id = zbuff.create(8)
-    local crc8c
-    onewire.init(0) -- 初始化单总线
-    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
-    id:set() -- 清空id
-    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
-    if succ then
-        if id[0] == 0x28 then
-            crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
-            if crc8c == id[7] then
-                log.info("探测到DS18B20", "18B20对应唯一ID为", id:query(0, 7):toHex())
-                read_ds18b20(id)
-                -- log.info("DS18B20离线,重新探测")
-            else
-                log.info("ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
-            end
-        else
-            log.info("ROM ID不正确", mcu.x32(id[0]))
-        end
-    else
-        log.info("没有检测到DS18B20")
-    end
-end
-
-local switchover_pin = gpio.PWR_KEY --选择powerkey作为切换18B20读数的信号脚
-
-gpio.debounce(switchover_pin, 100) --设置防抖
-
-
---设置powerkey按下和抬起的功能(18B20温度的取值再54pin和56pin之间切换)
---如果客户需要其他pin(22/54/56/78)则改动switchover_pin为用户需要的即可
---注意,由于powerkey不能做单边沿触发,所以一次按下和抬起的动作,会触发两次切换pin
---看效果的话,可以先一直按住powerkey几秒,再松开
-gpio.setup(switchover_pin, function()
-    log.info("Touch_pin", switchover_pin, "被触发")
-    log.info("当前单总线pad", onewire_pin)
-    if onewire_pin == 54 then
-        log.info("给PAD" .. onewire_pin .. "配置到GPIO3上去", pins.setup(onewire_pin, "GPIO3"))
-        log.info("给GPIO3设置为高电平输出模式",gpio.setup(3,1))--一定要执行gpio.setup,至于是哪种模式,用户根据自身需求
-        onewire_pin = 56
-    else
-        log.info("给PAD" .. onewire_pin .. "配置到GPIO7上去", pins.setup(onewire_pin, "GPIO7"))
-        log.info("给GPIO7设置为高电平输出模式",gpio.setup(7,1))
-
-        onewire_pin = 54
-    end
-    log.info("设置后单总线pad", onewire_pin)
-
-    onewire.deinit(0) -- 切换的时候一定要先关闭单总线,在读取的时候重新初始化
-
-    log.info("给" .. onewire_pin .. "配置到onewire上去", pins.setup(onewire_pin, "ONEWIRE"))
-    sys.publish("powerkey被按下")
-end, gpio.PULLUP, gpio.RISING)
-
-sys.taskInit(function()
-    while 1 do
-        -- sys.waitUntil("powerkey被按下")
-        log.info("1S后读取"..onewire_pin.."脚上的18B20")
-        sys.wait(1000)
-        log.info("开始读取18B20")
-        test_ds18b20()
-    end
-end)
-
-
-
-

+ 367 - 0
module/Air780EPM/demo/onewire/onewire_multi_app.lua

@@ -0,0 +1,367 @@
+--[[
+@module  onewire_multi_app
+@summary OneWire多DS18B20温度传感器应用演示模块(54和23切换版本)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示多DS18B20温度传感器的完整功能:
+1. 双传感器切换控制(引脚54和23)
+2. 电源管理(GPIO控制)
+3. 按键切换传感器
+4. 双路温度同时监测
+5. 使用引脚复用功能(pins.setup)
+]]
+
+log.info("onewire_multi_app", "多传感器模块版本: 1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- 和GPIO31控制传感器电源使能,确保DS18B20供电正常
+gpio.setup(31, 1)
+
+-- 硬件配置(双设备模式:支持引脚54和23切换)
+local onewire_pin = 54
+local switchover_pin = gpio.PWR_KEY
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_READ_ROM = 0x33
+
+-- 全局状态变量
+local pwr_key_pressed = false
+
+-- PWR_KEY按键中断处理函数
+-- 功能:处理引脚切换按键事件,设置标志位供主循环查询
+local function handle_pwr_key_interrupt()
+    pwr_key_pressed = true
+    log.info("onewire_multi_app", "切换按键被按下")
+end
+
+-- 初始化硬件配置
+local function init_hardware()
+    log.info("onewire_multi_app", "初始化硬件配置...")
+    
+    -- 配置PWR_KEY按键,使用上升沿触发并添加防抖
+    gpio.debounce(switchover_pin, 100)
+    gpio.setup(switchover_pin, handle_pwr_key_interrupt, gpio.PULLUP, gpio.RISING)
+    
+    -- 初始配置当前引脚为ONEWIRE功能
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    log.info("onewire_multi_app", "硬件初始化完成")
+    log.info("onewire_multi_app", "初始引脚: 引脚" .. onewire_pin .. " (ONEWIRE功能)")
+    log.info("onewire_multi_app", "切换按键: PWR_KEY")
+    log.info("onewire_multi_app", "支持引脚: 54 和 23 循环切换")
+    log.info("onewire_multi_app", "电源控制: GPIO31/GPIO2 (已设置为高电平)")
+    
+    return true
+end
+
+
+-- 时序要求:DS18B20上电后需要稳定时间,100ms延时确保电源稳定
+-- 技术背景:DS18B20在电源切换后需要tREC(恢复时间)完成内部初始化
+-- 实际测试:无延时可能导致设备检测失败或温度读取异常
+-- 建议值:最小50ms,推荐100ms以确保可靠性
+local function power_stabilization_delay()
+    log.info("onewire_multi_app", "电源稳定延时(确保DS18B20内部电路就绪)")
+    sys.wait(100)  -- DS18B20 tREC恢复时间,最小50ms,推荐100ms
+end
+
+-- 单总线分时使用引脚切换(同一条总线,分时复用)
+-- 核心逻辑:使用GPIO54和GPIO23两个引脚连接同一条OneWire总线,实现分时复用
+-- 应用场景:当需要在同一总线上分时访问不同设备时使用
+-- 技术原理:通过切换总线连接引脚,实现同一条物理总线的分时使用
+-- 切换效果:
+-- - GPIO54:当前时间段连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
+-- - GPIO23:切换到时间段连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
+-- 注意:这不是多总线并行,而是单总线的分时复用策略
+local function switch_onewire_pin()
+    log.info("onewire_multi_app", "切换OneWire引脚...")
+    
+    -- 关闭当前OneWire总线
+    onewire.deinit(0)
+    
+    
+    -- 分时复用切换逻辑
+    -- 技术原理:将当前不使用的引脚配置为GPIO功能并输出高电平
+    -- 目的:确保非活动设备处于高阻态,避免干扰当前连接的设备
+    -- 电气特性:GPIO设置为开漏输出模式,高电平由上拉电阻提供
+    if onewire_pin == 54 then
+        -- 从54切换到23
+        -- 将PIN54配置为GPIO3功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN54配置为GPIO3", pins.setup(54, "GPIO3"))
+        -- 设置GPIO3为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO3设置为高电平输出(OneWire总线空闲状态)", gpio.setup(3, 1))
+        onewire_pin = 23
+        log.info("onewire_multi_app", "切换到引脚23")
+    else
+        -- 从23切换到54
+        -- 将PIN23配置为GPIO2功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN23配置为GPIO2", pins.setup(23, "GPIO2"))
+        -- 设置GPIO2为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO2设置为高电平输出(OneWire总线空闲状态)", gpio.setup(2, 1))
+        onewire_pin = 54
+        log.info("onewire_multi_app", "切换到引脚54")
+    end
+    
+    log.info("onewire_multi_app", "当前使用引脚:", onewire_pin)
+    
+    -- 配置新引脚为ONEWIRE功能
+    -- 分时复用原理:将选中的引脚配置为OneWire功能,连接到对应设备
+    -- 连接过程:先断开之前的设备连接,再连接新的设备
+    -- 电气特性:确保当前连接的设备具有完整的OneWire通信能力
+    log.info("onewire_multi_app", "将引脚" .. onewire_pin .. "配置为ONEWIRE功能", pins.setup(onewire_pin, "ONEWIRE"))
+    
+    log.info("onewire_multi_app", "引脚切换完成,当前使用: 引脚" .. onewire_pin)
+end
+
+-- 初始化OneWire总线
+local function init_onewire_bus()
+    log.info("onewire_multi_app", "初始化OneWire总线,通道: 0")
+    
+    -- 配置当前引脚
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    -- 初始化OneWire总线
+    onewire.init(0)
+    
+    -- 配置DS18B20标准时序参数
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    
+    log.info("onewire_multi_app", "OneWire总线初始化完成,通道: 0,引脚:" .. onewire_pin)
+    
+    return true
+end
+
+-- 检测DS18B20设备是否存在(分时复用场景)
+-- 分时逻辑:在当前连接的引脚上发送复位脉冲,检测该设备响应
+-- 单总线场景:只有当前连接的引脚上的设备会响应复位脉冲
+-- 返回值:true表示当前引脚连接的设备响应,false表示无设备响应
+local function detect_ds18b20_device()
+    log.info("onewire_multi_app", "检测DS18B20设备,引脚: " .. onewire_pin)
+    
+    -- 发送复位脉冲并检测设备
+    local present = onewire.reset(0, true)
+    
+    if present then
+        log.info("onewire_multi_app", "检测到DS18B20设备响应")
+        return true
+    else
+        log.warn("onewire_multi_app", "未检测到DS18B20设备响应")
+        return false
+    end
+end
+
+-- 读取DS18B20温度(单总线分时复用)
+-- 核心流程:读ROM ID → 选设备 → 温度转换 → 读数据 → CRC校验
+local function read_ds18b20_temperature()
+    log.info("onewire_multi_app", "开始读取DS18B20温度,引脚: " .. onewire_pin)
+    
+    local tbuff = zbuff.create(10)
+    local succ, crc8c, range, t
+    local rbuff = zbuff.create(9)
+    
+    -- 读取设备ROM ID(每个设备唯一)
+    log.info("onewire_multi_app", "读取设备ROM ID(64位唯一标识)")
+    
+    local id = zbuff.create(8)
+    id:set()
+    
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "读取ROM ID失败")
+        return nil
+    end
+    
+    -- 检查设备类型码(DS18B20应为0x28)
+    if id[0] ~= 0x28 then
+        log.warn("onewire_multi_app", "非DS18B20设备,类型码:", mcu.x32(id[0]))
+        return nil
+    end
+    
+    -- CRC校验设备ID
+    crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
+    if crc8c ~= id[7] then
+        log.warn("onewire_multi_app", "ROM ID CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(id[7]))
+        log.info("onewire_multi_app", "完整ROM ID:", id:query(0, 7):toHex())
+        return nil
+    end
+    
+    log.info("onewire_multi_app", "ROM ID校验成功:", id:query(0, 7):toHex())
+    
+    -- 通过MATCH ROM选择设备(确保只选中目标设备)
+    log.info("onewire_multi_app", "开始温度转换(通过ROM匹配选择设备)")
+    
+    -- 构建命令缓冲区:MATCH ROM(0x55) + 目标设备ROM ID + 温度转换命令(0x44)
+    -- 0x55是MATCH ROM命令,后面必须跟64位目标设备的ROM ID
+    tbuff:write(0x55)     -- MATCH ROM命令
+    tbuff:copy(nil, id)  -- 复制64位ROM ID(确保选择正确的设备)
+    tbuff:write(0xb8)
+    tbuff[tbuff:used() - 1] = 0x44  -- CONVERT T温度转换命令
+    
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送温度转换命令失败")
+        return nil
+    end
+
+    -- 第三步:等待转换完成
+    log.info("onewire_multi_app", "等待温度转换完成")
+    
+    -- 等待一段时间让转换完成
+    sys.wait(750)
+    
+    -- 发送复位脉冲检查设备
+    succ = onewire.reset(0, true)
+    if not succ then
+        log.warn("onewire_multi_app", "等待转换完成时设备未响应")
+        return nil
+    end
+    
+    -- 检查转换是否完成
+    if onewire.bit(0) > 0 then
+        log.info("onewire_multi_app", "温度转换完成")
+    end
+    
+    -- 第四步:读取温度数据
+    log.info("onewire_multi_app", "读取温度数据")
+    
+    -- 构建读取命令:匹配ROM(0x55) + ROM ID + 读取暂存器命令(0xBE)
+    tbuff[tbuff:used() - 1] = 0xbe
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送读取命令失败")
+        return nil
+    end
+    
+    -- 接收9字节温度数据
+    succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+    if not succ then
+        log.warn("onewire_multi_app", "温度数据接收失败")
+        return nil
+    end
+    
+    -- 第五步:CRC校验和温度计算
+    log.info("onewire_multi_app", "CRC校验和温度计算")
+    
+    -- CRC校验
+    crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
+    if crc8c == rbuff[8] then
+        -- 计算温度值
+        range = (rbuff[4] >> 5) & 0x03
+        t = rbuff:query(0, 2, false, true)
+        t = t * (5000 >> range)
+        t = t / 10000
+        
+        -- 范围检查
+        if t >= -55.0 and t <= 125.0 then
+            log.info("onewire_multi_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_multi_app", "温度值超出有效范围:", t)
+            return nil
+        end
+    else
+        log.warn("onewire_multi_app", "温度数据CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(rbuff[8]))
+        return nil
+    end
+end
+
+-- 简化版温度读取(用于快速测试)
+local function quick_read_ds18b20()
+    log.info("onewire_multi_app", "快速读取温度,引脚: " .. onewire_pin)
+    
+    -- 首先检测设备是否存在
+    if not detect_ds18b20_device() then
+        return nil
+    end
+    
+    -- 使用完整读取函数
+    return read_ds18b20_temperature()
+end
+
+-- 单总线分时复用主函数(同一条总线,分时访问不同设备)
+local function multi_sensor_app_main()
+    log.info("onewire_multi_app", "启动双传感器应用(引脚54和23)")
+    
+    -- 初始化硬件
+    if not init_hardware() then
+        log.error("onewire_multi_app", "硬件初始化失败,任务无法启动")
+        return
+    end
+    
+    -- 初始化OneWire总线
+    init_onewire_bus()
+    
+    -- 电源稳定延时:确保DS18B20内部电路就绪
+    power_stabilization_delay()
+    
+    -- 检测设备
+    local device_present = detect_ds18b20_device()
+    
+    if not device_present then
+        log.error("onewire_multi_app", "未检测到设备响应")
+        log.warn("onewire_multi_app", "硬件连接提示:")
+        log.warn("onewire_multi_app", "1. 传感器连接引脚54或23")
+        log.warn("onewire_multi_app", "2. 确保GPIO31/GPIO2已设置为高电平供电")
+        log.warn("onewire_multi_app", "3. 确保4.7kΩ上拉电阻正确安装")
+        log.warn("onewire_multi_app", "4. 检查传感器VDD、GND、DQ连接")
+        -- 关闭OneWire总线
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_multi_app", "开始双传感器连续监测...")
+    log.info("onewire_multi_app", "按PWR_KEY按键可切换引脚(54和23)")
+    
+  -- 主循环:按键切换设备,分时读取温度
+    local read_count = 0
+    local success_count = 0
+    
+    while true do
+        read_count = read_count + 1
+        
+        -- 检查按键状态
+        if pwr_key_pressed then
+            pwr_key_pressed = false
+            switch_onewire_pin()
+            
+            -- 重新初始化OneWire总线
+            init_onewire_bus()
+        end
+        
+        log.info("onewire_multi_app", "第" .. read_count .. "次读取,引脚:" .. onewire_pin)
+        
+        -- 尝试读取温度
+        local temperature = read_ds18b20_temperature()
+        
+        if temperature then
+            success_count = success_count + 1
+            log.info("onewire_multi_app", "引脚" .. onewire_pin .. "温度:", 
+                    string.format("%.2f°C", temperature), 
+                    "成功率:", string.format("%.1f%%", success_count/read_count*100))
+            
+            -- 简单的温度报警逻辑
+            if temperature > 30 then
+                log.warn("onewire_multi_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_multi_app", "温度偏低:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_multi_app", "本次读取失败")
+            log.info("onewire_multi_app", "成功率:", string.format("%.1f%%", success_count/read_count*100))
+        end
+        
+        -- 等待下一次读取
+        sys.wait(2000)
+    end
+end
+log.info("onewire_multi_app", "双传感器应用模块加载完成(54和23切换)")
+-- 启动多传感器应用任务
+sys.taskInit(multi_sensor_app_main)
+

+ 0 - 107
module/Air780EPM/demo/onewire/onewire_single_18b20/main.lua

@@ -1,107 +0,0 @@
-PROJECT = "onewiredemo"
-VERSION = "1.0.0"
-sys = require("sys")
-log.style(1)
-
---[[
-接线说明:
-   DS18B20    Air780EPM
-1. GND    -> GND
-2. VDD    -> 3.3V
-3. DATA    -> GPIO2
-
-注意:
-1. 3.3v在老版本的开发板上没有引脚, 所以需要外接, 一定要确保共地
-2. ONEWIRE功能支持在4个引脚使用, 但硬件通道只有一个, 默认是GPIO2
-3. 如需切换到其他脚, 参考上一级目录下的onewire_multi_18b20_swich_read
-]]
-
-local function read_ds18b20(id)
-    local tbuff = zbuff.create(10)
-    local succ,crc8c,range,t
-    local rbuff = zbuff.create(9)
-    --如果有多个DS18B20,需要带上ID
-    tbuff:write(0x55)
-    tbuff:copy(nil, id)
-    tbuff:write(0xb8)
-    --如果只有1个DS18B20,就用无ID方式
-    --tbuff:write(0xcc,0xb8)
-    while true do
-        tbuff[tbuff:used() - 1] = 0x44
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        while true do
-            succ = onewire.reset(0, true)
-            if not succ then
-                return
-            end
-            if onewire.bit(0) > 0 then
-                log.info("温度转换完成")
-                break
-            end
-            sys.wait(10)
-        end
-        tbuff[tbuff:used() - 1] = 0xbe
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        succ,rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
-        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
-        if crc8c == rbuff[8] then
-            range = (rbuff[4] >> 5) & 0x03
-            -- rbuff[0] = 0xF8
-            -- rbuff[1] = 0xFF
-            t = rbuff:query(0,2,false,true)
-            t = t * (5000 >> range)
-            t = t / 10000
-            log.info(t)
-        else
-            log.info("RAM DATA CRC校验不对",  mcu.x32(crc8c), mcu.x32(rbuff[8]))
-            return
-        end
-        sys.wait(500)
-    end
-end
-
-local function test_ds18b20()
-    local succ,rx_data
-    local id = zbuff.create(8)
-
-    local crc8c
-    onewire.init(0)
-    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
-    while true do
-        id:set() --清空id
-        succ,rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
-        if succ then
-            if id[0] == 0x28 then
-                crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
-                if crc8c == id[7] then
-                    log.info("探测到DS18B20", id:query(0, 7):toHex())
-                    read_ds18b20(id)
-                    log.info("DS18B20离线,重新探测")
-                else
-                    log.info("ROM ID CRC校验不对",  mcu.x32(crc8c), mcu.x32(id[7]))
-                end
-            else
-                log.info("ROM ID不正确", mcu.x32(id[0]))
-            end
-        end
-        log.info("没有检测到DS18B20, 5秒后重试")
-        sys.wait(5000)
-
-    end
-    
-
-end
-
-if onewire then
-    sys.taskInit(test_ds18b20)
-else
-    log.info("no onewire")
-end
-
-sys.run()

+ 203 - 0
module/Air780EPM/demo/onewire/onewire_single_app.lua

@@ -0,0 +1,203 @@
+--[[
+@module  onewire_single_app
+@summary OneWire单DS18B20温度传感器应用演示模块(GPIO2默认模式)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示单DS18B20温度传感器的完整功能:
+1. 使用GPIO2默认OneWire功能
+2. 硬件通道0模式,无需引脚复用
+3. 优化的时序参数和错误处理
+4. 连续温度监测
+5. 完整的OneWire API接口演示
+]]
+
+
+log.info("onewire_single_app", "单传感器模块版本:1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_SKIP_ROM = 0xCC
+local CMD_READ_ROM = 0x33
+
+-- 单传感器应用主函数
+local function single_sensor_app_main()
+    log.info("onewire_single_app", "启动单传感器应用")
+    
+    -- 初始化OneWire总线(使用硬件通道0模式)
+    log.info("onewire_single_app", "初始化OneWire总线...")
+    onewire.init(0)
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    log.info("onewire_single_app", "OneWire总线初始化完成,使用GPIO2默认引脚")
+    
+    
+    
+    -- 检测DS18B20设备
+    log.info("onewire_single_app", "检测DS18B20设备...")
+    
+    local succ, rx_data
+    local id = zbuff.create(8)
+    local crc8c
+    
+    -- 清空ID缓冲区
+    id:set()
+    
+    -- 读取设备ROM ID(使用手动配置的引脚)
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    
+    local detected = false
+    local device_id = nil
+    
+    if succ then
+        -- 检查家族码(DS18B20为0x28)
+        if id[0] == 0x28 then
+            -- CRC校验
+            crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
+            if crc8c == id[7] then
+                log.info("onewire_single_app", "探测到DS18B20", id:query(0, 7):toHex())
+                detected = true
+                device_id = id
+            else
+                log.warn("onewire_single_app", "ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
+            end
+        else
+            log.warn("onewire_single_app", "ROM ID不正确", mcu.x32(id[0]))
+        end
+    else
+        log.warn("onewire_single_app", "未检测到DS18B20设备,请检查硬件连接")
+        log.info("onewire_single_app", "硬件连接提示:")
+        log.info("onewire_single_app", "1. DS18B20 DATA引脚 -> GPIO2 (默认OneWire功能)")
+        log.info("onewire_single_app", "2. 确保上拉电阻4.7kΩ连接DATA到3.3V")
+        log.info("onewire_single_app", "3. 使用硬件通道0模式,无需引脚复用配置")
+    end
+    
+    if not detected then
+        log.warn("onewire_single_app", "设备检测失败,任务无法启动")
+        log.info("onewire_single_app", "单传感器应用启动完成")
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_single_app", "开始连续温度监测...")
+    
+    -- 读取DS18B20温度数据(单总线单设备模式)
+    -- 与多传感器模式的对比:
+    -- - 单传感器:使用SKIP ROM(0xCC)直接通信,无需ROM ID
+    -- - 多传感器:使用MATCH ROM(0x55)选择设备,需要目标ROM ID
+    -- 
+    -- 单设备读取流程:
+    -- 1. SKIP ROM:发送0xCC命令,跳过ROM ID识别
+    -- 2. 温度转换:发送CONVERT T(0x44)启动温度转换
+    -- 3. 读取数据:发送READ SCRATCHPAD(0xBE)读取温度数据
+    -- 4. CRC校验:验证数据完整性
+    -- 
+    -- 优势:通信简单高效,无需设备寻址
+    -- 限制:只能用于总线上只有一个设备的场景
+    local function read_temperature(dev_id)
+        local tbuff = zbuff.create(10)
+        local rbuff = zbuff.create(9)
+        local succ, crc8c, range, t
+        
+        -- 发送SKIP ROM命令(0xCC) - 跳过ROM识别,直接与设备通信
+        -- 工作原理:所有设备都会响应SKIP ROM命令,无需发送64位ROM ID
+        -- 适用场景:总线上只有一个设备,无需设备寻址和选择
+        -- 优势:通信效率高,无需传输ROM ID,简化通信流程
+        -- 风险:如果总线上有多个设备,所有设备会同时响应,造成冲突
+        tbuff:write(0xcc)
+        
+        -- 发送温度转换命令
+        tbuff[tbuff:used() - 1] = 0x44
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送温度转换命令失败")
+            return nil
+        end
+        
+        -- 等待转换完成(使用位检测)
+        local conversion_complete = false
+        local max_wait = 100
+        local wait_count = 0
+        
+        while wait_count < max_wait do
+            succ = onewire.reset(0, true)
+            if not succ then
+                log.warn("onewire_single_app", "等待转换完成时设备未响应")
+                return nil
+            end
+            if onewire.bit(0) > 0 then
+                log.info("onewire_single_app", "温度转换完成")
+                conversion_complete = true
+                break
+            end
+            sys.wait(10)
+            wait_count = wait_count + 1
+        end
+        
+        if not conversion_complete then
+            log.warn("onewire_single_app", "温度转换超时")
+            return nil
+        end
+        
+        -- 读取温度数据
+        tbuff[tbuff:used() - 1] = 0xBE
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送读取命令失败")
+            return nil
+        end
+        
+        succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+        if not succ or rbuff:used() ~= 9 then
+            log.warn("onewire_single_app", "温度数据读取失败")
+            return nil
+        end
+        
+        -- CRC校验
+        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
+        if crc8c == rbuff[8] then
+            range = (rbuff[4] >> 5) & 0x03
+            t = rbuff:query(0,2,false,true)
+            t = t * (5000 >> range)
+            t = t / 10000
+            log.info("onewire_single_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_single_app", "RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
+            return nil
+        end
+    end
+    
+    -- 主循环 - 连续温度监测
+    while true do
+        local temperature = read_temperature(device_id)
+        
+        if temperature then
+            -- 简单的温度报警逻辑(示例)
+            if temperature > 30 then
+                log.warn("onewire_single_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_single_app", "温度偏低:", string.format("%.2f°C", temperature))
+            else
+                log.info("onewire_single_app", "温度正常:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_single_app", "本次读取失败,继续下一次")
+        end
+        
+        -- 等待下一次读取
+        sys.wait(3000)
+    end
+    
+    log.info("onewire_single_app", "单传感器连续读取任务结束")
+    log.info("onewire_single_app", "单传感器应用启动完成")
+end
+
+log.info("onewire_single_app", "单传感器应用模块加载完成")
+
+-- 启动单传感器应用任务
+sys.taskInit(single_sensor_app_main)

+ 212 - 0
module/Air780EPM/demo/onewire/readme.md

@@ -0,0 +1,212 @@
+> 王棚嶙
+
+# OneWire综合演示项目
+
+## 功能模块介绍
+
+本demo演示了完整的DS18B20温度传感器OneWire单总线协议实现。项目采用模块化架构,分别实现单传感器和多传感器应用场景。
+
+1、main.lua:主程序入口 <br> 
+2、onewire_single_app.lua:演示单传感器功能模块(GPIO2默认OneWire功能,硬件通道0模式,3秒间隔连续监测)<br> 
+3、onewire_multi_app.lua:演示多传感器功能模块(引脚54/23切换,PWR_KEY按键控制,2秒间隔双路监测)<br> 
+
+## 演示功能概述
+
+###  主程序入口模块 (main.lua)
+
+- 初始化项目信息和版本号
+- 初始化看门狗,并定时喂狗
+- 启动一个循环定时器,每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
+- 加载onewire_single_app模块(通过require "onewire_single_app")
+- 加载onewire_multi_app模块(通过require "onewire_multi_app")
+
+### 单传感器模式 (onewire_single_app.lua)
+- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
+- 完整的CRC8数据校验机制,确保数据可靠性
+- 设备自动识别和ROM验证,支持设备类型检测
+- 3秒间隔连续温度监测,实时温度报警功能
+- zbuff缓冲区优化,提高数据传输效率
+
+
+### 多传感器模式 (onewire_multi_app.lua - 单总线多设备演示)
+
+
+**单总线多设备挂载原理**:
+1. **物理连接**:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
+2. **设备识别**:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
+3. **总线扫描**:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
+4. **设备选择**:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
+5. **分时操作**:每次只与一个设备通信,避免总线冲突
+
+**分时复用测试逻辑**(按键切换设备):
+- **引脚54**:连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
+- **引脚23**:连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
+- **PWR_KEY按键**:按一次切换一个设备,实现同一条总线的分时使用
+
+**核心测试流程**:
+1. 初始化当前引脚的OneWire总线
+2. 发送SEARCH ROM命令扫描总线上的设备
+3. 读取并验证设备的64位ROM ID(家族码+序列号+CRC)
+4. 使用MATCH ROM(0x55)命令选择目标设备
+5. 发送温度转换命令(0x44)并等待完成
+6. 读取温度数据并进行CRC校验
+7. 输出设备ROM ID、温度值、读取成功率
+
+
+
+## 演示硬件环境
+1、Air780EPM核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、ds18b20传感器两个
+
+4、Air780EPM核心板和数据线的硬件接线方式为
+
+- Air780EPM核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
+
+- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
+
+5、Air780EPM核心板和ds18b20传感器接线方式
+
+### 单传感器连接
+
+|   Air780EPM核心板     |    DS18B20传感器    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    23/GPIO2     |         DQ         |
+|    GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air780epm/luatos/app/driver/onewire/image/ce9d3b2c9b3a36c22388d710913668a7.jpg)
+
+### 多传感器连接
+
+
+|   Air780EPM核心板     |    DS18B20传感器1    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    23/GPIO2     |         DQ         |
+|    任意GND          |         GND        |
+
+|   Air780EPM核心板     |    DS18B20传感器2    |
+| --------------- | -------------------|
+|    32/GPIO31         |         VCC        |
+|    54/CAM_MCLK     |         DQ         |
+|    任意GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air780epm/luatos/app/driver/onewire/image/1957f5eb447654ec31894efb589e809b.jpg)
+
+## 演示软件环境
+
+1、Luatools下载调试工具: https://docs.openluat.com/air780epm/common/Luatools/
+
+2、内核固件版本:
+Air780EPM:https://docs.openluat.com/air780epm/luatos/firmware/version/
+
+## 演示核心步骤
+1、搭建好硬件环境
+
+2、通过Luatools将demo与固件烧录到核心板或开发板中
+
+3、烧录好后,板子开机将会在Luatools上看到如下打印:
+
+```lua
+(1)单传感器演示
+[2025-11-24 23:46:59.904][000000000.251] I/user.main onewire_demo 1.0.0
+[2025-11-24 23:46:59.932][000000000.258] I/user.onewire_single_app 单传感器模块版本: 002.002.000
+[2025-11-24 23:46:59.970][000000000.258] I/user.onewire_single_app 单传感器应用模块加载完成
+[2025-11-24 23:47:00.002][000000000.259] I/user.onewire_single_app 启动单传感器应用
+[2025-11-24 23:47:00.032][000000000.259] I/user.onewire_single_app 初始化OneWire总线...
+[2025-11-24 23:47:00.064][000000000.259] I/user.onewire_single_app OneWire总线初始化完成,使用GPIO2默认引脚
+[2025-11-24 23:47:00.096][000000000.259] I/user.onewire_single_app 检测DS18B20设备...
+[2025-11-24 23:47:00.124][000000000.267] I/user.onewire_single_app 探测到DS18B20 2859F253000000 14
+[2025-11-24 23:47:00.159][000000000.267] I/user.onewire_single_app 开始连续温度监测...
+[2025-11-24 23:47:00.186][000000000.276] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:00.216][000000000.289] I/user.onewire_single_app 温度读取成功: 85.00°C
+[2025-11-24 23:47:00.246][000000000.290] W/user.onewire_single_app 温度偏高: 85.00°C
+[2025-11-24 23:47:00.409][000000003.299] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:00.436][000000003.312] I/user.onewire_single_app 温度读取成功: 28.25°C
+[2025-11-24 23:47:00.465][000000003.313] I/user.onewire_single_app 温度正常: 28.25°C
+[2025-11-24 23:47:03.404][000000006.322] I/user.onewire_single_app 温度转换完成
+[2025-11-24 23:47:03.437][000000006.335] I/user.onewire_single_app 温度读取成功: 28.25°C
+[2025-11-24 23:47:03.469][000000006.335] I/user.onewire_single_app 温度正常: 28.25°C
+
+(2)双传感器演示
+[2025-11-24 23:49:45.699][000000000.260] I/user.onewire_multi_app 双传感器应用模块加载完成(54和23切换)
+[2025-11-24 23:49:45.732][000000000.261] I/user.onewire_multi_app 启动双传感器应用(引脚54和23)
+[2025-11-24 23:49:45.761][000000000.261] I/user.onewire_multi_app 初始化硬件配置...
+[2025-11-24 23:49:45.789][000000000.261] I/user.onewire_multi_app 硬件初始化完成
+[2025-11-24 23:49:45.822][000000000.262] I/user.onewire_multi_app 初始引脚: 引脚54 (ONEWIRE功能)
+[2025-11-24 23:49:45.859][000000000.262] I/user.onewire_multi_app 切换按键: PWR_KEY
+[2025-11-24 23:49:45.898][000000000.262] I/user.onewire_multi_app 支持引脚: 54 和 23 循环切换
+[2025-11-24 23:49:45.932][000000000.262] I/user.onewire_multi_app 电源控制: GPIO31/GPIO2 (已设置为高电平)
+[2025-11-24 23:49:45.963][000000000.262] I/user.onewire_multi_app 电源控制: 开启
+[2025-11-24 23:49:45.997][000000000.363] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-24 23:49:46.026][000000000.374] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:54
+[2025-11-24 23:49:46.059][000000000.573] I/user.onewire_multi_app 检测DS18B20设备,引脚: 54
+[2025-11-24 23:49:46.089][000000000.575] I/user.onewire_multi_app 检测到DS18B20设备响应
+[2025-11-24 23:49:46.117][000000000.575] I/user.onewire_multi_app 开始双传感器连续监测...
+[2025-11-24 23:49:46.148][000000000.575] I/user.onewire_multi_app 按PWR_KEY按键可切换引脚(54和23)
+[2025-11-24 23:49:46.181][000000000.575] I/user.onewire_multi_app 第1次读取,引脚:54
+[2025-11-24 23:49:46.212][000000000.575] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:46.243][000000000.576] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:46.272][000000000.583] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:46.297][000000000.583] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:46.325][000000000.590] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:46.401][000000001.341] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:46.433][000000001.342] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:46.466][000000001.354] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:46.499][000000001.355] I/user.onewire_multi_app 温度读取成功: 27.44°C
+[2025-11-24 23:49:46.530][000000001.355] I/user.onewire_multi_app 引脚54温度: 27.44°C 成功率: 100.0%
+[2025-11-24 23:49:46.630][000000003.355] I/user.onewire_multi_app 第2次读取,引脚:54
+[2025-11-24 23:49:46.665][000000003.356] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:46.698][000000003.356] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:46.727][000000003.363] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:46.765][000000003.363] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:46.799][000000003.371] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:46.982][000000004.122] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:47.010][000000004.123] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:47.043][000000004.135] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:47.077][000000004.136] I/user.onewire_multi_app 温度读取成功: 27.50°C
+[2025-11-24 23:49:47.110][000000004.137] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
+[2025-11-24 23:49:48.999][000000006.137] I/user.onewire_multi_app 第3次读取,引脚:54
+[2025-11-24 23:49:49.030][000000006.138] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 54
+[2025-11-24 23:49:49.061][000000006.138] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:49.094][000000006.145] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-24 23:49:49.124][000000006.145] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:49.154][000000006.153] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:49.778][000000006.904] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:49.806][000000006.905] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:49.836][000000006.917] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:49.866][000000006.918] I/user.onewire_multi_app 温度读取成功: 27.50°C
+[2025-11-24 23:49:49.907][000000006.919] I/user.onewire_multi_app 引脚54温度: 27.50°C 成功率: 100.0%
+
+(3)双传感器按键切换演示
+[2025-11-24 23:49:51.147][000000008.278] I/user.onewire_multi_app 切换按键被按下
+[2025-11-24 23:49:51.783][000000008.919] I/user.onewire_multi_app 切换OneWire引脚...
+[2025-11-24 23:49:51.821][000000008.939] I/user.onewire_multi_app 将PAD54配置为GPIO3 true
+[2025-11-24 23:49:51.856][000000008.940] I/user.onewire_multi_app 将GPIO3设置为高电平输出 function: 0C7F4A10
+[2025-11-24 23:49:51.897][000000008.940] I/user.onewire_multi_app 切换到引脚23
+[2025-11-24 23:49:51.933][000000008.940] I/user.onewire_multi_app 当前使用引脚: 23
+[2025-11-24 23:49:51.965][000000008.941] I/user.onewire_multi_app 将引脚23配置为ONEWIRE功能 true
+[2025-11-24 23:49:51.994][000000008.961] I/user.onewire_multi_app 引脚切换完成,当前使用: 引脚23
+[2025-11-24 23:49:52.324][000000009.461] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-24 23:49:52.356][000000009.471] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:23
+[2025-11-24 23:49:52.431][000000009.571] I/user.onewire_multi_app 第4次读取,引脚:23
+[2025-11-24 23:49:52.474][000000009.571] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 23
+[2025-11-24 23:49:52.519][000000009.572] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-24 23:49:52.563][000000009.579] I/user.onewire_multi_app ROM ID校验成功: 2859F253000000 14
+[2025-11-24 23:49:52.593][000000009.579] I/user.onewire_multi_app 开始温度转换
+[2025-11-24 23:49:52.622][000000009.587] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-24 23:49:53.203][000000010.338] I/user.onewire_multi_app 温度转换完成
+[2025-11-24 23:49:53.239][000000010.339] I/user.onewire_multi_app 读取温度数据
+[2025-11-24 23:49:53.272][000000010.351] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-24 23:49:53.302][000000010.352] I/user.onewire_multi_app 温度读取成功: 27.81°C
+[2025-11-24 23:49:53.332][000000010.353] I/user.onewire_multi_app 引脚23温度: 27.81°C 成功率: 100.0%
+
+
+```

+ 56 - 105
module/Air8000/demo/onewire/main.lua

@@ -1,114 +1,65 @@
+--[[
+@module  main
+@summary OneWire综合演示项目主文件(单传感器 + 多传感器)
+@version 001.000.000
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本演示项目整合单DS18B20和多DS18B20传感器功能:
+1. 单传感器模式:GPIO2默认OneWire功能、硬件通道0模式、CRC校验、3秒间隔连续监测
+2. 多传感器模式:引脚30/98切换、PWR_KEY按键控制、电源管理、2秒间隔双路监测
+3. 完整的OneWire API接口演示、错误处理、设备检测、温度报警
+]]
 
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "onewiredemo"
-VERSION = "1.0.0"
+-- 项目信息
+PROJECT = "onewire_demo"
+VERSION = "001.000.000"
 
--- sys库是标配
-sys = require("sys")
 
--- 以 log.info("ABC", "DEF", 123) 为例, 假设该代码位于main.lua的12行
--- 调试风格1, 添加额外的调试信息
--- I/main.lua:12 ABC DEF 123
-log.style(1)
 
---[[
-接线说明:
-   DS18B20    Air8000
-1. GND    -> GND
-2. VDD    -> 3.3V
-3. DATA    -> GPIO2
-
-注意:
-1. ONEWIRE功能支持在4个引脚使用, 但硬件通道只有一个, 默认是GPIO2
-2. 如需切换到其他脚, 参考Air780EPM目录下的onewire_multi_18b20_swich_read
-]]
 
-local function read_ds18b20(id)
-    local tbuff = zbuff.create(10)
-    local succ,crc8c,range,t
-    local rbuff = zbuff.create(9)
-    --如果有多个DS18B20,需要带上ID
-    tbuff:write(0x55)
-    tbuff:copy(nil, id)
-    tbuff:write(0xb8)
-    --如果只有1个DS18B20,就用无ID方式
-    --tbuff:write(0xcc,0xb8)
-    while true do
-        tbuff[tbuff:used() - 1] = 0x44
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        while true do
-            succ = onewire.reset(0, true)
-            if not succ then
-                return
-            end
-            if onewire.bit(0) > 0 then
-                log.info("温度转换完成")
-                break
-            end
-            sys.wait(10)
-        end
-        tbuff[tbuff:used() - 1] = 0xbe
-        succ = onewire.tx(0, tbuff, false, true, true)
-        if not succ then
-            return
-        end
-        succ,rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
-        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
-        if crc8c == rbuff[8] then
-            range = (rbuff[4] >> 5) & 0x03
-            -- rbuff[0] = 0xF8
-            -- rbuff[1] = 0xFF
-            t = rbuff:query(0,2,false,true)
-            t = t * (5000 >> range)
-            t = t / 10000
-            log.info(t)
-        else
-            log.info("RAM DATA CRC校验不对",  mcu.x32(crc8c), mcu.x32(rbuff[8]))
-            return
-        end
-        sys.wait(500)
-    end
-end
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
 
-local function test_ds18b20()
-    local succ,rx_data
-    local id = zbuff.create(8)
-
-    local crc8c
-    onewire.init(0)
-    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
-    while true do
-        id:set() --清空id
-        succ,rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
-        if succ then
-            if id[0] == 0x28 then
-                crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
-                if crc8c == id[7] then
-                    log.info("探测到DS18B20", id:query(0, 7):toHex())
-                    read_ds18b20(id)
-                    log.info("DS18B20离线,重新探测")
-                else
-                    log.info("ROM ID CRC校验不对",  mcu.x32(crc8c), mcu.x32(id[7]))
-                end
-            else
-                log.info("ROM ID不正确", mcu.x32(id[0]))
-            end
-        end
-        log.info("没有检测到DS18B20, 5秒后重试")
-        sys.wait(5000)
-    end
-end
 
-if onewire then
-    sys.taskInit(test_ds18b20)
-else
-    log.info("no onewire")
+--添加硬狗防止程序卡死
+if wdt then
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
 end
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
+
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
+
+-- 在加载以下两个功能的时候建议分别打开,避免同时初始化OneWire总线,导致资源冲突
+-- 单设备模式:使用GPIO2默认OneWire功能
+-- 双设备模式:GPIO2默认 + 引脚54复用
+
+-- 加载单传感器应用模块
+-- require("onewire_single_app")
+
+-- 加载多传感器应用模块
+require("onewire_multi_app")
+
 
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!
+-- 启动系统主循环
+sys.run()

+ 367 - 0
module/Air8000/demo/onewire/onewire_multi_app.lua

@@ -0,0 +1,367 @@
+--[[
+@module  onewire_multi_app
+@summary OneWire多DS18B20温度传感器应用演示模块(30和98切换版本)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示多DS18B20温度传感器的完整功能:
+1. 双传感器切换控制(引脚30和98)
+2. 电源管理(GPIO控制)
+3. 按键切换传感器
+4. 双路温度同时监测
+5. 使用引脚复用功能(pins.setup)
+]]
+
+log.info("onewire_multi_app", "多传感器模块版本: 1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- GPIO20控制传感器电源使能,确保DS18B20供电正常
+gpio.setup(20, 1)
+
+-- 硬件配置(双设备模式:支持引脚30和98切换)
+local onewire_pin = 98
+local switchover_pin = gpio.PWR_KEY
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_READ_ROM = 0x33
+
+-- 全局状态变量
+local pwr_key_pressed = false
+
+-- PWR_KEY按键中断处理函数
+-- 功能:处理引脚切换按键事件,设置标志位供主循环查询
+local function handle_pwr_key_interrupt()
+    pwr_key_pressed = true
+    log.info("onewire_multi_app", "切换按键被按下")
+end
+
+-- 初始化硬件配置
+local function init_hardware()
+    log.info("onewire_multi_app", "初始化硬件配置...")
+    
+    -- 配置PWR_KEY按键,使用上升沿触发并添加防抖
+    gpio.debounce(switchover_pin, 100)
+    gpio.setup(switchover_pin, handle_pwr_key_interrupt, gpio.PULLUP, gpio.RISING)
+    
+    -- 初始配置当前引脚为ONEWIRE功能
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    log.info("onewire_multi_app", "硬件初始化完成")
+    log.info("onewire_multi_app", "初始引脚: 引脚" .. onewire_pin .. " (ONEWIRE功能)")
+    log.info("onewire_multi_app", "切换按键: PWR_KEY")
+    log.info("onewire_multi_app", "支持引脚: 98 和 30 循环切换")
+    log.info("onewire_multi_app", "电源控制: GPIO20(已设置为高电平)")
+    
+    return true
+end
+
+
+-- 时序要求:DS18B20上电后需要稳定时间,100ms延时确保电源稳定
+-- 技术背景:DS18B20在电源切换后需要tREC(恢复时间)完成内部初始化
+-- 实际测试:无延时可能导致设备检测失败或温度读取异常
+-- 建议值:最小50ms,推荐100ms以确保可靠性
+local function power_stabilization_delay()
+    log.info("onewire_multi_app", "电源稳定延时(确保DS18B20内部电路就绪)")
+    sys.wait(100)  -- DS18B20 tREC恢复时间,最小50ms,推荐100ms
+end
+
+-- 单总线分时使用引脚切换(同一条总线,分时复用)
+-- 核心逻辑:使用GPIO98和GPIO30两个引脚连接同一条OneWire总线,实现分时复用
+-- 应用场景:当需要在同一总线上分时访问不同设备时使用
+-- 技术原理:通过切换总线连接引脚,实现同一条物理总线的分时使用
+-- 切换效果:
+-- - GPIO98:当前时间段连接设备A(ROM ID: 28-9F-C4-93-00-00-00-14)
+-- - GPIO30:切换到时间段连接设备B(ROM ID: 28-59-F2-53-00-00-00-14)
+-- 注意:这不是多总线并行,而是单总线的分时复用策略
+local function switch_onewire_pin()
+    log.info("onewire_multi_app", "切换OneWire引脚...")
+    
+    -- 关闭当前OneWire总线
+    onewire.deinit(0)
+    
+    
+    -- 分时复用切换逻辑
+    -- 技术原理:将当前不使用的引脚配置为GPIO功能并输出高电平
+    -- 目的:确保非活动设备处于高阻态,避免干扰当前连接的设备
+    -- 电气特性:GPIO设置为开漏输出模式,高电平由上拉电阻提供
+    if onewire_pin == 98 then
+        -- 从98切换到30
+        -- 将PIN98配置为GPIO3功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN98配置为GPIO3", pins.setup(98, "GPIO3"))
+        -- 设置GPIO3为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO3设置为高电平输出(OneWire总线空闲状态)", gpio.setup(3, 1))
+        onewire_pin = 30
+        log.info("onewire_multi_app", "切换到引脚30")
+    else
+        -- 从30切换到98
+        -- 将PIN30配置为GPIO2功能,不再作为OneWire使用
+        log.info("onewire_multi_app", "将PIN30配置为GPIO2", pins.setup(30, "GPIO2"))
+        -- 设置GPIO2为高电平输出(开漏模式,高电平由上拉电阻提供)
+        log.info("onewire_multi_app", "将GPIO2设置为高电平输出(OneWire总线空闲状态)", gpio.setup(2, 1))
+        onewire_pin = 98
+        log.info("onewire_multi_app", "切换到引脚98")
+    end
+    
+    log.info("onewire_multi_app", "当前使用引脚:", onewire_pin)
+    
+    -- 配置新引脚为ONEWIRE功能
+    -- 分时复用原理:将选中的引脚配置为OneWire功能,连接到对应设备
+    -- 连接过程:先断开之前的设备连接,再连接新的设备
+    -- 电气特性:确保当前连接的设备具有完整的OneWire通信能力
+    log.info("onewire_multi_app", "将引脚" .. onewire_pin .. "配置为ONEWIRE功能", pins.setup(onewire_pin, "ONEWIRE"))
+     
+    log.info("onewire_multi_app", "引脚切换完成,当前使用: 引脚" .. onewire_pin)
+end
+
+-- 初始化OneWire总线
+local function init_onewire_bus()
+    log.info("onewire_multi_app", "初始化OneWire总线,通道: 0")
+    
+    -- 配置当前引脚
+    pins.setup(onewire_pin, "ONEWIRE")
+    
+    -- 初始化OneWire总线
+    onewire.init(0)
+    
+    -- 配置DS18B20标准时序参数
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    
+    log.info("onewire_multi_app", "OneWire总线初始化完成,通道: 0,引脚:" .. onewire_pin)
+    
+    return true
+end
+
+-- 检测DS18B20设备是否存在(分时复用场景)
+-- 分时逻辑:在当前连接的引脚上发送复位脉冲,检测该设备响应
+-- 单总线场景:只有当前连接的引脚上的设备会响应复位脉冲
+-- 返回值:true表示当前引脚连接的设备响应,false表示无设备响应
+local function detect_ds18b20_device()
+    log.info("onewire_multi_app", "检测DS18B20设备,引脚: " .. onewire_pin)
+    
+    -- 发送复位脉冲并检测设备
+    local present = onewire.reset(0, true)
+    
+    if present then
+        log.info("onewire_multi_app", "检测到DS18B20设备响应")
+        return true
+    else
+        log.warn("onewire_multi_app", "未检测到DS18B20设备响应")
+        return false
+    end
+end
+
+-- 读取DS18B20温度(单总线分时复用)
+-- 核心流程:读ROM ID → 选设备 → 温度转换 → 读数据 → CRC校验
+local function read_ds18b20_temperature()
+    log.info("onewire_multi_app", "开始读取DS18B20温度,引脚: " .. onewire_pin)
+    
+    local tbuff = zbuff.create(10)
+    local succ, crc8c, range, t
+    local rbuff = zbuff.create(9)
+    
+    -- 读取设备ROM ID(每个设备唯一)
+    log.info("onewire_multi_app", "读取设备ROM ID(64位唯一标识)")
+    
+    local id = zbuff.create(8)
+    id:set()
+    
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "读取ROM ID失败")
+        return nil
+    end
+    
+    -- 检查设备类型码(DS18B20应为0x28)
+    if id[0] ~= 0x28 then
+        log.warn("onewire_multi_app", "非DS18B20设备,类型码:", mcu.x32(id[0]))
+        return nil
+    end
+    
+    -- CRC校验设备ID
+    crc8c = crypto.crc8(id:query(0, 7), 0x31, 0, true)
+    if crc8c ~= id[7] then
+        log.warn("onewire_multi_app", "ROM ID CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(id[7]))
+        log.info("onewire_multi_app", "完整ROM ID:", id:query(0, 7):toHex())
+        return nil
+    end
+    
+    log.info("onewire_multi_app", "ROM ID校验成功:", id:query(0, 7):toHex())
+    
+    -- 通过MATCH ROM选择设备(确保只选中目标设备)
+    log.info("onewire_multi_app", "开始温度转换(通过ROM匹配选择设备)")
+    
+    -- 构建命令缓冲区:MATCH ROM(0x55) + 目标设备ROM ID + 温度转换命令(0x44)
+    -- 0x55是MATCH ROM命令,后面必须跟64位目标设备的ROM ID
+    tbuff:write(0x55)     -- MATCH ROM命令
+    tbuff:copy(nil, id)  -- 复制64位ROM ID(确保选择正确的设备)
+    tbuff:write(0xb8)
+    tbuff[tbuff:used() - 1] = 0x44  -- CONVERT T温度转换命令
+    
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送温度转换命令失败")
+        return nil
+    end
+
+    -- 第三步:等待转换完成
+    log.info("onewire_multi_app", "等待温度转换完成")
+    
+    -- 等待一段时间让转换完成
+    sys.wait(750)
+    
+    -- 发送复位脉冲检查设备
+    succ = onewire.reset(0, true)
+    if not succ then
+        log.warn("onewire_multi_app", "等待转换完成时设备未响应")
+        return nil
+    end
+    
+    -- 检查转换是否完成
+    if onewire.bit(0) > 0 then
+        log.info("onewire_multi_app", "温度转换完成")
+    end
+    
+    -- 第四步:读取温度数据
+    log.info("onewire_multi_app", "读取温度数据")
+    
+    -- 构建读取命令:匹配ROM(0x55) + ROM ID + 读取暂存器命令(0xBE)
+    tbuff[tbuff:used() - 1] = 0xbe
+    succ = onewire.tx(0, tbuff, false, true, true)
+    if not succ then
+        log.warn("onewire_multi_app", "发送读取命令失败")
+        return nil
+    end
+    
+    -- 接收9字节温度数据
+    succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+    if not succ then
+        log.warn("onewire_multi_app", "温度数据接收失败")
+        return nil
+    end
+    
+    -- 第五步:CRC校验和温度计算
+    log.info("onewire_multi_app", "CRC校验和温度计算")
+    
+    -- CRC校验
+    crc8c = crypto.crc8(rbuff:toStr(0, 8), 0x31, 0, true)
+    if crc8c == rbuff[8] then
+        -- 计算温度值
+        range = (rbuff[4] >> 5) & 0x03
+        t = rbuff:query(0, 2, false, true)
+        t = t * (5000 >> range)
+        t = t / 10000
+        
+        -- 范围检查
+        if t >= -55.0 and t <= 125.0 then
+            log.info("onewire_multi_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_multi_app", "温度值超出有效范围:", t)
+            return nil
+        end
+    else
+        log.warn("onewire_multi_app", "温度数据CRC校验不对", 
+                "计算值:", mcu.x32(crc8c), "期望值:", mcu.x32(rbuff[8]))
+        return nil
+    end
+end
+
+-- 简化版温度读取(用于快速测试)
+local function quick_read_ds18b20()
+    log.info("onewire_multi_app", "快速读取温度,引脚: " .. onewire_pin)
+    
+    -- 首先检测设备是否存在
+    if not detect_ds18b20_device() then
+        return nil
+    end
+    
+    -- 使用完整读取函数
+    return read_ds18b20_temperature()
+end
+
+-- 单总线分时复用主函数(同一条总线,分时访问不同设备)
+local function multi_sensor_app_main()
+    log.info("onewire_multi_app", "启动双传感器应用(引脚30和98)")
+    
+    -- 初始化硬件
+    if not init_hardware() then
+        log.error("onewire_multi_app", "硬件初始化失败,任务无法启动")
+        return
+    end
+    
+    -- 初始化OneWire总线(GPIO20已在init_hardware中设置为高电平供电)
+    init_onewire_bus()
+    
+    -- 电源稳定延时:确保DS18B20内部电路就绪
+    power_stabilization_delay()
+    
+    -- 检测设备
+    local device_present = detect_ds18b20_device()
+    
+    if not device_present then
+        log.error("onewire_multi_app", "未检测到设备响应")
+        log.warn("onewire_multi_app", "硬件连接提示:")
+        log.warn("onewire_multi_app", "1. 传感器连接引脚98或30")
+        log.warn("onewire_multi_app", "2. 确保GPIO31/GPIO2已设置为高电平供电")
+        log.warn("onewire_multi_app", "3. 确保4.7kΩ上拉电阻正确安装")
+        log.warn("onewire_multi_app", "4. 检查传感器VDD、GND、DQ连接")
+        -- 关闭OneWire总线
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_multi_app", "开始双传感器连续监测...")
+    log.info("onewire_multi_app", "按PWR_KEY按键可切换引脚(30和98)")
+    
+    -- 主循环:按键切换设备,分时读取温度
+    local read_count = 0
+    local success_count = 0
+    
+    while true do
+        read_count = read_count + 1
+        
+        -- 检查按键状态
+        if pwr_key_pressed then
+            pwr_key_pressed = false
+            switch_onewire_pin()
+            
+            -- 重新初始化OneWire总线
+            init_onewire_bus()
+        end
+        
+        log.info("onewire_multi_app", "第" .. read_count .. "次读取,引脚:" .. onewire_pin)
+        
+        -- 尝试读取温度
+        local temperature = read_ds18b20_temperature()
+        
+        if temperature then
+            success_count = success_count + 1
+            log.info("onewire_multi_app", "引脚" .. onewire_pin .. "温度:", 
+                    string.format("%.2f°C", temperature), 
+                    "成功率:", string.format("%.1f%%", success_count/read_count*100))
+            
+            -- 简单的温度报警逻辑
+            if temperature > 30 then
+                log.warn("onewire_multi_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_multi_app", "温度偏低:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_multi_app", "本次读取失败")
+            log.info("onewire_multi_app", "成功率:", string.format("%.1f%%", success_count/read_count*100))
+        end
+        
+        -- 等待下一次读取
+        sys.wait(2000)
+    end
+end
+log.info("onewire_multi_app", "双传感器应用模块加载完成(30和98切换)")
+-- 启动多传感器应用任务
+sys.taskInit(multi_sensor_app_main)
+

+ 203 - 0
module/Air8000/demo/onewire/onewire_single_app.lua

@@ -0,0 +1,203 @@
+--[[
+@module  onewire_single_app
+@summary OneWire单DS18B20温度传感器应用演示模块(GPIO2默认模式)
+@version 1.0.0
+@date    2025.11.25
+@author  王棚嶙
+@usage
+本模块演示单DS18B20温度传感器的完整功能:
+1. 使用GPIO2默认OneWire功能
+2. 硬件通道0模式,无需引脚复用
+3. 优化的时序参数和错误处理
+4. 连续温度监测
+5. 完整的OneWire API接口演示
+]]
+
+
+log.info("onewire_single_app", "单传感器模块版本:1.0.0")
+
+-- 设置所有GPIO引脚电压为3.3V,确保DS18B20传感器正常供电
+pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
+
+-- DS18B20命令定义
+local CMD_CONVERT_T = 0x44
+local CMD_READ_SCRATCHPAD = 0xBE
+local CMD_SKIP_ROM = 0xCC
+local CMD_READ_ROM = 0x33
+
+-- 单传感器应用主函数
+local function single_sensor_app_main()
+    log.info("onewire_single_app", "启动单传感器应用")
+    
+    -- 初始化OneWire总线(使用硬件通道0模式)
+    log.info("onewire_single_app", "初始化OneWire总线...")
+    onewire.init(0)
+    onewire.timing(0, false, 0, 500, 500, 15, 240, 70, 1, 15, 10, 2)
+    log.info("onewire_single_app", "OneWire总线初始化完成,使用GPIO2默认引脚")
+    
+ 
+    
+    -- 检测DS18B20设备
+    log.info("onewire_single_app", "检测DS18B20设备...")
+    
+    local succ, rx_data
+    local id = zbuff.create(8)
+    local crc8c
+    
+    -- 清空ID缓冲区
+    id:set()
+    
+    -- 读取设备ROM ID(使用手动配置的引脚)
+    succ, rx_data = onewire.rx(0, 8, 0x33, id, false, true, true)
+    
+    local detected = false
+    local device_id = nil
+    
+    if succ then
+        -- 检查家族码(DS18B20为0x28)
+        if id[0] == 0x28 then
+            -- CRC校验
+            crc8c = crypto.crc8(id:query(0,7), 0x31, 0, true)
+            if crc8c == id[7] then
+                log.info("onewire_single_app", "探测到DS18B20", id:query(0, 7):toHex())
+                detected = true
+                device_id = id
+            else
+                log.warn("onewire_single_app", "ROM ID CRC校验不对", mcu.x32(crc8c), mcu.x32(id[7]))
+            end
+        else
+            log.warn("onewire_single_app", "ROM ID不正确", mcu.x32(id[0]))
+        end
+    else
+        log.warn("onewire_single_app", "未检测到DS18B20设备,请检查硬件连接")
+        log.info("onewire_single_app", "硬件连接提示:")
+        log.info("onewire_single_app", "1. DS18B20 DATA引脚 -> GPIO2 (默认OneWire功能)")
+        log.info("onewire_single_app", "2. 确保上拉电阻4.7kΩ连接DATA到3.3V")
+        log.info("onewire_single_app", "3. 使用硬件通道0模式,无需引脚复用配置")
+    end
+    
+    if not detected then
+        log.warn("onewire_single_app", "设备检测失败,任务无法启动")
+        log.info("onewire_single_app", "单传感器应用启动完成")
+        onewire.deinit(0)
+        return
+    end
+    
+    log.info("onewire_single_app", "开始连续温度监测...")
+    
+    -- 读取DS18B20温度数据(单总线单设备模式)
+    -- 与多传感器模式的对比:
+    -- - 单传感器:使用SKIP ROM(0xCC)直接通信,无需ROM ID
+    -- - 多传感器:使用MATCH ROM(0x55)选择设备,需要目标ROM ID
+    -- 
+    -- 单设备读取流程:
+    -- 1. SKIP ROM:发送0xCC命令,跳过ROM ID识别
+    -- 2. 温度转换:发送CONVERT T(0x44)启动温度转换
+    -- 3. 读取数据:发送READ SCRATCHPAD(0xBE)读取温度数据
+    -- 4. CRC校验:验证数据完整性
+    -- 
+    -- 优势:通信简单高效,无需设备寻址
+    -- 限制:只能用于总线上只有一个设备的场景
+    local function read_temperature(dev_id)
+        local tbuff = zbuff.create(10)
+        local rbuff = zbuff.create(9)
+        local succ, crc8c, range, t
+        
+        -- 发送SKIP ROM命令(0xCC) - 跳过ROM识别,直接与设备通信
+        -- 工作原理:所有设备都会响应SKIP ROM命令,无需发送64位ROM ID
+        -- 适用场景:总线上只有一个设备,无需设备寻址和选择
+        -- 优势:通信效率高,无需传输ROM ID,简化通信流程
+        -- 风险:如果总线上有多个设备,所有设备会同时响应,造成冲突
+        tbuff:write(0xcc)
+        
+        -- 发送温度转换命令
+        tbuff[tbuff:used() - 1] = 0x44
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送温度转换命令失败")
+            return nil
+        end
+        
+        -- 等待转换完成(使用位检测)
+        local conversion_complete = false
+        local max_wait = 100
+        local wait_count = 0
+        
+        while wait_count < max_wait do
+            succ = onewire.reset(0, true)
+            if not succ then
+                log.warn("onewire_single_app", "等待转换完成时设备未响应")
+                return nil
+            end
+            if onewire.bit(0) > 0 then
+                log.info("onewire_single_app", "温度转换完成")
+                conversion_complete = true
+                break
+            end
+            sys.wait(10)
+            wait_count = wait_count + 1
+        end
+        
+        if not conversion_complete then
+            log.warn("onewire_single_app", "温度转换超时")
+            return nil
+        end
+        
+        -- 读取温度数据
+        tbuff[tbuff:used() - 1] = 0xBE
+        succ = onewire.tx(0, tbuff, false, true, true)
+        if not succ then
+            log.warn("onewire_single_app", "发送读取命令失败")
+            return nil
+        end
+        
+        succ, rx_data = onewire.rx(0, 9, nil, rbuff, false, false, false)
+        if not succ or rbuff:used() ~= 9 then
+            log.warn("onewire_single_app", "温度数据读取失败")
+            return nil
+        end
+        
+        -- CRC校验
+        crc8c = crypto.crc8(rbuff:toStr(0,8), 0x31, 0, true)
+        if crc8c == rbuff[8] then
+            range = (rbuff[4] >> 5) & 0x03
+            t = rbuff:query(0,2,false,true)
+            t = t * (5000 >> range)
+            t = t / 10000
+            log.info("onewire_single_app", "温度读取成功:", string.format("%.2f°C", t))
+            return t
+        else
+            log.warn("onewire_single_app", "RAM DATA CRC校验不对", mcu.x32(crc8c), mcu.x32(rbuff[8]))
+            return nil
+        end
+    end
+    
+    -- 主循环 - 连续温度监测
+    while true do
+        local temperature = read_temperature(device_id)
+        
+        if temperature then
+            -- 简单的温度报警逻辑(示例)
+            if temperature > 30 then
+                log.warn("onewire_single_app", "温度偏高:", string.format("%.2f°C", temperature))
+            elseif temperature < 10 then
+                log.warn("onewire_single_app", "温度偏低:", string.format("%.2f°C", temperature))
+            else
+                log.info("onewire_single_app", "温度正常:", string.format("%.2f°C", temperature))
+            end
+        else
+            log.warn("onewire_single_app", "本次读取失败,继续下一次")
+        end
+        
+        -- 等待下一次读取
+        sys.wait(3000)
+    end
+    
+    log.info("onewire_single_app", "单传感器连续读取任务结束")
+    log.info("onewire_single_app", "单传感器应用启动完成")
+end
+
+log.info("onewire_single_app", "单传感器应用模块加载完成")
+
+-- 启动单传感器应用任务
+sys.taskInit(single_sensor_app_main)

+ 213 - 0
module/Air8000/demo/onewire/readme.md

@@ -0,0 +1,213 @@
+> 王棚嶙
+
+# OneWire综合演示项目
+
+## 功能模块介绍
+
+本demo演示了完整的DS18B20温度传感器OneWire单总线协议实现。项目采用模块化架构,分别实现单传感器和多传感器应用场景。
+
+1、main.lua:主程序入口 <br> 
+2、onewire_single_app.lua:演示单传感器功能模块(GPIO2默认OneWire功能,硬件通道0模式,3秒间隔连续监测)<br> 
+3、onewire_multi_app.lua:演示多传感器功能模块(引脚98/30切换,PWR_KEY按键控制,2秒间隔双路监测)<br> 
+
+## 演示功能概述
+
+###  主程序入口模块 (main.lua)
+
+- 初始化项目信息和版本号
+- 初始化看门狗,并定时喂狗
+- 启动一个循环定时器,每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
+- 加载onewire_single_app模块(通过require "onewire_single_app")
+- 加载onewire_multi_app模块(通过require "onewire_multi_app")
+
+### 单传感器模式 (onewire_single_app.lua)
+- 使用GPIO2默认OneWire功能,硬件通道0模式,无需引脚复用
+- 完整的CRC8数据校验机制,确保数据可靠性
+- 设备自动识别和ROM验证,支持设备类型检测
+- 3秒间隔连续温度监测,实时温度报警功能
+- zbuff缓冲区优化,提高数据传输效率
+
+
+### 多传感器模式 (onewire_multi_app.lua - 单总线多设备演示)
+
+
+**单总线多设备挂载原理**:
+1. **物理连接**:所有DS18B20的VDD、GND、DQ引脚分别并联到同一组单总线
+2. **设备识别**:每个DS18B20出厂时烧录了全球唯一的64位ROM ID
+3. **总线扫描**:主机发送SEARCH ROM(0xF0)命令发现总线上的所有设备
+4. **设备选择**:通过MATCH ROM(0x55)命令+目标设备ROM ID选择特定设备通信
+5. **分时操作**:每次只与一个设备通信,避免总线冲突
+
+**分时复用测试逻辑**(2秒切换一次):
+- **前2秒**:使用总线端A设备(引脚98,ROM ID: 28-9F-C4-93-00-00-00-14)
+- **按PWR_KEY后2秒**:切换使用总线端B设备(引脚30,ROM ID: 28-59-F2-53-00-00-00-14)
+- **循环切换**:按键一次切换一个设备,实现同一条总线的分时使用
+
+**核心测试流程**:
+1. 初始化当前引脚的OneWire总线
+2. 发送SEARCH ROM命令扫描总线上的设备
+3. 读取并验证设备的64位ROM ID(家族码+序列号+CRC)
+4. 使用MATCH ROM(0x55)命令选择目标设备
+5. 发送温度转换命令(0x44)并等待完成
+6. 读取温度数据并进行CRC校验
+7. 输出设备ROM ID、温度值、读取成功率
+
+
+
+## 演示硬件环境
+1、Air8000A核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、ds18b20传感器两个
+
+4、Air8000A核心板和数据线的硬件接线方式为
+
+- Air8000A核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
+
+- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
+
+5、Air8000A核心板和ds18b20传感器接线方式
+
+### 单传感器连接
+
+|   Air8000A核心板     |    DS18B20传感器    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    GPIO2     |         DQ         |
+|    GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air8000/luatos/app/driver/onewire/image/b1e471848d3181dcd822dc93c62d660d.jpg)
+
+
+
+### 多传感器连接
+
+
+|   Air8000A核心板     |    DS18B20传感器1    |
+| --------------- | -------------------|
+|    VDD_EXT         |         VCC        |
+|    GPIO2     |         DQ         |
+|    任意GND          |         GND        |
+
+|   Air8000A核心板     |    DS18B20传感器2    |
+| --------------- | -------------------|
+|    GPIO20         |         VCC        |
+|    GPIO3     |         DQ         |
+|    任意GND          |         GND        |
+
+连接图:
+
+![image](https://docs.openluat.com/air8000/luatos/app/driver/onewire/image/8a1b2ebfc3749f8d5e84e40a78a31aa4.jpg)
+
+## 演示软件环境
+
+1、Luatools下载调试工具:https://docs.openluat.com/air780epm/common/Luatools/
+
+2、内核固件版本:https://docs.openluat.com/air8000/luatos/firmware/
+
+## 演示核心步骤
+1、搭建好硬件环境
+
+2、通过Luatools将demo与固件烧录到核心板或开发板中
+
+3、烧录好后,板子开机将会在Luatools上看到如下打印:
+
+```lua
+(1)单传感器演示
+[2025-11-25 15:14:59.660][000000000.387] I/user.onewire_single_app 单传感器模块版本:1.0.0
+[2025-11-25 15:14:59.683][000000000.387] I/user.onewire_single_app 单传感器应用模块加载完成
+[2025-11-25 15:14:59.705][000000000.387] I/user.onewire_single_app 启动单传感器应用
+[2025-11-25 15:14:59.721][000000000.388] I/user.onewire_single_app 初始化OneWire总线...
+[2025-11-25 15:14:59.737][000000000.388] I/user.onewire_single_app OneWire总线初始化完成,使用GPIO2默认引脚
+[2025-11-25 15:14:59.755][000000000.388] I/user.onewire_single_app 检测DS18B20设备...
+[2025-11-25 15:14:59.769][000000000.395] I/user.onewire_single_app 探测到DS18B20 2859F253000000 14
+[2025-11-25 15:14:59.793][000000000.396] I/user.onewire_single_app 开始连续温度监测...
+[2025-11-25 15:14:59.817][000000000.405] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:14:59.842][000000000.418] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:14:59.858][000000000.419] I/user.onewire_single_app 温度正常: 26.12°C
+[2025-11-25 15:15:00.727][000000003.428] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:15:00.751][000000003.441] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:15:00.766][000000003.442] I/user.onewire_single_app 温度正常: 26.12°C
+[2025-11-25 15:15:03.755][000000006.451] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:15:03.771][000000006.464] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:15:03.788][000000006.465] I/user.onewire_single_app 温度正常: 26.12°C
+[2025-11-25 15:15:06.775][000000009.474] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:15:06.794][000000009.487] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:15:06.817][000000009.488] I/user.onewire_single_app 温度正常: 26.12°C
+[2025-11-25 15:15:09.800][000000012.497] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:15:09.812][000000012.510] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:15:09.832][000000012.511] I/user.onewire_single_app 温度正常: 26.12°C
+[2025-11-25 15:15:12.830][000000015.520] I/user.onewire_single_app 温度转换完成
+[2025-11-25 15:15:12.842][000000015.533] I/user.onewire_single_app 温度读取成功: 26.12°C
+[2025-11-25 15:15:12.856][000000015.534] I/user.onewire_single_app 温度正常: 26.12°C
+
+(2)单总线分时复用演示
+[2025-11-25 15:10:27.765][000000000.393] I/user.onewire_multi_app 多传感器模块版本: 1.0.0
+[2025-11-25 15:10:27.826][000000000.394] I/user.onewire_multi_app 双传感器应用模块加载完成(30和98切换)
+[2025-11-25 15:10:27.910][000000000.394] I/user.onewire_multi_app 启动双传感器应用(引脚30和98)
+[2025-11-25 15:10:27.968][000000000.394] I/user.onewire_multi_app 初始化硬件配置...
+[2025-11-25 15:10:28.023][000000000.395] I/user.onewire_multi_app 硬件初始化完成
+[2025-11-25 15:10:28.067][000000000.395] I/user.onewire_multi_app 初始引脚: 引脚98 (ONEWIRE功能)
+[2025-11-25 15:10:28.115][000000000.396] I/user.onewire_multi_app 切换按键: PWR_KEY
+[2025-11-25 15:10:28.174][000000000.396] I/user.onewire_multi_app 支持引脚: 98 和 30 循环切换
+[2025-11-25 15:10:28.235][000000000.396] I/user.onewire_multi_app 电源控制: GPIO31/GPIO2 (已设置为高电平)
+[2025-11-25 15:10:28.284][000000000.396] I/user.onewire_multi_app 电源控制: 开启
+[2025-11-25 15:10:28.312][000000000.497] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-25 15:10:28.350][000000000.508] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:98
+[2025-11-25 15:10:28.468][000000000.709] I/user.onewire_multi_app 检测DS18B20设备,引脚: 98
+[2025-11-25 15:10:28.502][000000000.710] I/user.onewire_multi_app 检测到DS18B20设备响应
+[2025-11-25 15:10:28.531][000000000.710] I/user.onewire_multi_app 开始双传感器连续监测...
+[2025-11-25 15:10:28.561][000000000.710] I/user.onewire_multi_app 按PWR_KEY按键可切换引脚(30和98)
+[2025-11-25 15:10:28.592][000000000.711] I/user.onewire_multi_app 第1次读取,引脚:98
+[2025-11-25 15:10:28.625][000000000.711] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 98
+[2025-11-25 15:10:28.653][000000000.711] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-25 15:10:28.685][000000000.718] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-25 15:10:28.719][000000000.719] I/user.onewire_multi_app 开始温度转换
+[2025-11-25 15:10:28.747][000000000.726] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-25 15:10:28.777][000000001.478] I/user.onewire_multi_app 温度转换完成
+[2025-11-25 15:10:28.800][000000001.478] I/user.onewire_multi_app 读取温度数据
+[2025-11-25 15:10:28.828][000000001.491] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-25 15:10:28.860][000000001.492] I/user.onewire_multi_app 温度读取成功: 25.75°C
+[2025-11-25 15:10:28.890][000000001.492] I/user.onewire_multi_app 引脚98温度: 25.75°C 成功率: 100.0%
+[2025-11-25 15:10:29.029][000000003.493] I/user.onewire_multi_app 第2次读取,引脚:98
+[2025-11-25 15:10:29.063][000000003.493] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 98
+[2025-11-25 15:10:29.094][000000003.493] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-25 15:10:29.124][000000003.500] I/user.onewire_multi_app ROM ID校验成功: 289FC493000000 14
+[2025-11-25 15:10:29.158][000000003.501] I/user.onewire_multi_app 开始温度转换
+[2025-11-25 15:10:29.192][000000003.508] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-25 15:10:29.220][000000004.260] I/user.onewire_multi_app 温度转换完成
+[2025-11-25 15:10:29.251][000000004.260] I/user.onewire_multi_app 读取温度数据
+[2025-11-25 15:10:29.281][000000004.273] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-25 15:10:29.308][000000004.274] I/user.onewire_multi_app 温度读取成功: 25.81°C
+[2025-11-25 15:10:29.342][000000004.274] I/user.onewire_multi_app 引脚98温度: 25.81°C 成功率: 100.0%
+
+
+(3)单总线分时复用按键切换演示
+[2025-11-25 15:10:34.504][000000010.718] I/user.onewire_multi_app 切换按键被按下
+[2025-11-25 15:10:35.624][000000011.838] I/user.onewire_multi_app 切换OneWire引脚...
+[2025-11-25 15:10:35.647][000000011.859] I/user.onewire_multi_app 将PIN984配置为GPIO3 true
+[2025-11-25 15:10:35.677][000000011.859] I/user.onewire_multi_app 将GPIO3设置为高电平输出 function: 0C7F4648
+[2025-11-25 15:10:35.698][000000011.859] I/user.onewire_multi_app 切换到引脚30
+[2025-11-25 15:10:35.721][000000011.860] I/user.onewire_multi_app 当前使用引脚: 30
+[2025-11-25 15:10:35.745][000000011.860] I/user.onewire_multi_app 将引脚30配置为ONEWIRE功能 true
+[2025-11-25 15:10:35.769][000000011.880] I/user.onewire_multi_app 引脚切换完成,当前使用: 引脚30
+[2025-11-25 15:10:36.167][000000012.380] I/user.onewire_multi_app 初始化OneWire总线,通道: 0
+[2025-11-25 15:10:36.189][000000012.391] I/user.onewire_multi_app OneWire总线初始化完成,通道: 0,引脚:30
+[2025-11-25 15:10:36.275][000000012.490] I/user.onewire_multi_app 第5次读取,引脚:30
+[2025-11-25 15:10:36.296][000000012.491] I/user.onewire_multi_app 开始读取DS18B20温度,引脚: 30
+[2025-11-25 15:10:36.315][000000012.491] I/user.onewire_multi_app 读取设备ROM ID
+[2025-11-25 15:10:36.335][000000012.498] I/user.onewire_multi_app ROM ID校验成功: 2859F253000000 14
+[2025-11-25 15:10:36.361][000000012.499] I/user.onewire_multi_app 开始温度转换
+[2025-11-25 15:10:36.390][000000012.506] I/user.onewire_multi_app 等待温度转换完成
+[2025-11-25 15:10:37.038][000000013.258] I/user.onewire_multi_app 温度转换完成
+[2025-11-25 15:10:37.063][000000013.258] I/user.onewire_multi_app 读取温度数据
+[2025-11-25 15:10:37.084][000000013.271] I/user.onewire_multi_app CRC校验和温度计算
+[2025-11-25 15:10:37.107][000000013.272] I/user.onewire_multi_app 温度读取成功: 26.00°C
+[2025-11-25 15:10:37.130][000000013.272] I/user.onewire_multi_app 引脚30温度: 26.00°C 成功率: 100.0%
+
+
+
+```