Răsfoiți Sursa

update:更新主流模组的 PWM 示例代码为最新版

mengyang 3 luni în urmă
părinte
comite
756325f6cc
27 a modificat fișierele cu 1947 adăugiri și 518 ștergeri
  1. 0 29
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/breathing_led.lua
  2. 38 11
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/main.lua
  3. 49 0
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EGH.json
  4. 52 0
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EHM.json
  5. 205 0
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EHV.json
  6. 184 0
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pwm_app.lua
  7. 0 26
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pwm_output.lua
  8. 67 10
      module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/readme.md
  9. 93 0
      module/Air780EPM/demo/pwm/main.lua
  10. 52 0
      module/Air780EPM/demo/pwm/pins_Air780EPM.json
  11. 181 0
      module/Air780EPM/demo/pwm/pwm_app.lua
  12. 81 0
      module/Air780EPM/demo/pwm/readme.md
  13. 0 38
      module/Air780EPM/demo/pwm/示例1 PWM输出/main.lua
  14. 0 58
      module/Air780EPM/demo/pwm/示例2 呼吸灯效果/main.lua
  15. 0 50
      module/Air8000/demo/pwm/PWM呼吸灯/main.lua
  16. 0 54
      module/Air8000/demo/pwm/PWM呼吸灯/pins_Air8000.json
  17. 0 49
      module/Air8000/demo/pwm/PWM输出/main.lua
  18. 0 54
      module/Air8000/demo/pwm/PWM输出/pins_Air8000.json
  19. 93 0
      module/Air8000/demo/pwm/main.lua
  20. 250 0
      module/Air8000/demo/pwm/pins_Air8000.json
  21. 181 0
      module/Air8000/demo/pwm/pwm_app.lua
  22. 81 0
      module/Air8000/demo/pwm/readme.md
  23. 0 34
      module/Air8000/demo/pwm/示例1 PWM输出/main.lua
  24. 0 58
      module/Air8000/demo/pwm/示例2 呼吸灯效果/main.lua
  25. 79 47
      module/Air8101/demo/pwm/main.lua
  26. 177 0
      module/Air8101/demo/pwm/pwm_app.lua
  27. 84 0
      module/Air8101/demo/pwm/readme.md

+ 0 - 29
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/breathing_led.lua

@@ -1,29 +0,0 @@
---[[
-@module  breathing_led
-@summary PWM呼吸灯效果模块
-@version 1.0
-@date    2025.07.08
-@author  王世豪
-@usage
-使用Air780EHV核心板的GPIO引脚输出PWM波形,演示呼吸灯效果。
-]]
-
-local PWM_ID = 0
-local function breathing_led()
-    log.info("pwm", "ch", PWM_ID)
-    while 1 do
-        -- 仿呼吸灯效果
-        log.info("pwm", ">>>>>")
-        for i = 10, 1, -1 do 
-            pwm.open(PWM_ID, 1000, i*9) -- 频率1000hz, 占空比从 90% 递减到 9%
-            sys.wait(100 + i*10) 
-        end
-        for i = 10, 1, -1 do 
-            pwm.open(PWM_ID, 1000, 100 - i*9) -- 频率1000hz, 占空比从 10% 递增到 91%
-            sys.wait(100 + i*10)
-        end
-        sys.wait(2000)
-    end
-end
-
-sys.taskInit(breathing_led)

+ 38 - 11
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/main.lua

@@ -2,16 +2,38 @@
 @module  main
 @summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
 @version 1.0
-@date    2025.07.08
-@author  王世豪
+@date    2025.11.05
+@author  马梦阳
 @usage
+
 本demo演示的核心功能为:
-1. 加载pwm输出模块,控制GPIO引脚输出PWM波形
-2. 加载呼吸灯效果模块,控制GPIO引脚输出呼吸灯效果
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+
+注意事项:
+1. 本 demo 演示所使用的是 Air780EHM/EHV/EGH 模组的 PWM4 通道(GPIO27,PIN16);
+2. 该引脚需要通过 LuatIO 工具进行复用配置:
+    pins_Air780EHM.json 为 Air780EHM 模组的复用配置文件;
+    pins_Air780EHV.json 为 Air780EHV 模组的复用配置文件;
+    pins_Air780EGH.json 为 Air780EGH 模组的复用配置文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+注意!!!!pwm.setFreq() 函数目前出现一些 BUG,调用成功后无法正常输出波形,正在紧急修复,时间 2025.10.29
 
-更多说明参考本目录下的readme.md文件
+更多说明参考本目录下的 readme.md 文件
 ]]
 
+
 --[[
 必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
 PROJECT:项目名,ascii string类型
@@ -22,10 +44,13 @@ VERSION:项目版本号,ascii string类型
             因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
         如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
 ]]
-PROJECT = "pwm"
+PROJECT = "PWM"
 VERSION = "001.000.000"
 
-log.info("main", "project name is ", PROJECT, "version is ", VERSION)
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
 
 -- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
 -- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
@@ -36,6 +61,7 @@ if wdt then
     sys.timerLoopStart(wdt.feed, 3000)
 end
 
+
 -- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
 -- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
 -- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
@@ -44,11 +70,13 @@ end
 --     errDump.config(true, 600)
 -- end
 
+
 -- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
 -- 可以使用合宙的iot.openluat.com平台进行远程升级
 -- 也可以使用客户自己搭建的平台进行远程升级
 -- 远程升级的详细用法,可以参考fota的demo进行使用
 
+
 -- 启动一个循环定时器
 -- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
 -- 方便分析内存使用是否有异常
@@ -57,11 +85,10 @@ end
 --     log.info("mem.sys", rtos.meminfo("sys"))
 -- end, 3000)
 
--- 加载pwm输出模块
-require "pwm_output"
 
--- -- 加载呼吸灯效果模块
--- require "breathing_led"
+-- 加载 PWM 应用模块
+require "pwm_app"
+
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句

+ 49 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EGH.json

@@ -0,0 +1,49 @@
+{
+  "model": "Air780EGH",
+  "pins": [
+    [7, "PWR_KEY", ""],
+    [16, "PWM4", ""],
+    [17, "UART1_RXD", ""],
+    [18, "UART1_TXD", ""],
+    [19, "GPIO22", ""],
+    [20, "PWM1", ""],
+    [22, "PWM0", ""],
+    [23, "ONEWIRE", ""],
+    [25, "CAN_TXD", ""],
+    [26, "GPIO33", ""],
+    [30, "GPIO29", ""],
+    [31, "GPIO30", ""],
+    [32, "GPIO31", ""],
+    [33, "GPIO32", ""],
+    [38, "DBG_RXD", ""],
+    [39, "DBG_TXD", ""],
+    [49, "LCD_RST", ""],
+    [50, "LCD_SDA", ""],
+    [51, "LCD_RS", ""],
+    [52, "LCD_CS", ""],
+    [53, "LCD_CLK", ""],
+    [54, "CAM_MCLK", ""],
+    [55, "CAM_RX0", ""],
+    [56, "CAM_RX1", ""],
+    [57, "UART3_TXD", ""],
+    [58, "UART3_RXD", ""],
+    [61, "VBUS", ""],
+    [66, "I2C1_SDA", ""],
+    [67, "I2C1_SCL", ""],
+    [78, "CAN_STB", ""],
+    [79, "USIM_DET", ""],
+    [80, "CAM_BCLK", ""],
+    [81, "CAM_CS", ""],
+    [82, "USB_BOOT", ""],
+    [83, "SPI0_CS", ""],
+    [84, "SPI0_MISO", ""],
+    [85, "SPI0_MOSI", ""],
+    [86, "SPI0_CLK", ""],
+    [97, "GPIO16", ""],
+    [99, "GPIO23", ""],
+    [100, "GPIO17", ""],
+    [101, "WAKEUP0", ""],
+    [102, "GPIO20", ""],
+    [106, "CAN_RXD", ""]
+  ]
+}

+ 52 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EHM.json

@@ -0,0 +1,52 @@
+{
+  "model": "Air780EHM",
+  "pins": [
+    [7, "PWR_KEY", ""],
+    [16, "PWM4", ""],
+    [17, "UART1_RXD", ""],
+    [18, "UART1_TXD", ""],
+    [19, "GPIO22", ""],
+    [20, "PWM1", ""],
+    [22, "PWM0", ""],
+    [23, "ONEWIRE", ""],
+    [25, "CAN_TXD", ""],
+    [26, "GPIO33", ""],
+    [28, "UART2_RXD", ""],
+    [29, "UART2_TXD", ""],
+    [30, "GPIO29", ""],
+    [31, "GPIO30", ""],
+    [32, "GPIO31", ""],
+    [33, "GPIO32", ""],
+    [38, "DBG_RXD", ""],
+    [39, "DBG_TXD", ""],
+    [49, "LCD_RST", ""],
+    [50, "LCD_SDA", ""],
+    [51, "LCD_RS", ""],
+    [52, "LCD_CS", ""],
+    [53, "LCD_CLK", ""],
+    [54, "CAM_MCLK", ""],
+    [55, "CAM_RX0", ""],
+    [56, "CAM_RX1", ""],
+    [57, "UART3_TXD", ""],
+    [58, "UART3_RXD", ""],
+    [61, "VBUS", ""],
+    [66, "I2C1_SDA", ""],
+    [67, "I2C1_SCL", ""],
+    [78, "GPIO28", ""],
+    [79, "USIM_DET", ""],
+    [80, "CAM_BCLK", ""],
+    [81, "CAM_CS", ""],
+    [82, "USB_BOOT", ""],
+    [83, "SPI0_CS", ""],
+    [84, "SPI0_MISO", ""],
+    [85, "SPI0_MOSI", ""],
+    [86, "SPI0_CLK", ""],
+    [97, "GPIO16", ""],
+    [99, "GPIO23", ""],
+    [100, "GPIO17", ""],
+    [101, "WAKEUP0", ""],
+    [102, "GPIO20", ""],
+    [106, "CAN_RXD", ""],
+    [107, "GPIO21", ""]
+  ]
+}

+ 205 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pins_Air780EHV.json

@@ -0,0 +1,205 @@
+{
+  "model": "Air780EHV",
+  "pins": [
+    [
+      7,
+      "PWR_KEY",
+      ""
+    ],
+    [
+      16,
+      "PWM4",
+      ""
+    ],
+    [
+      17,
+      "UART1_RXD",
+      ""
+    ],
+    [
+      18,
+      "UART1_TXD",
+      ""
+    ],
+    [
+      19,
+      "GPIO22",
+      ""
+    ],
+    [
+      20,
+      "PWM1",
+      ""
+    ],
+    [
+      22,
+      "PWM0",
+      ""
+    ],
+    [
+      23,
+      "ONEWIRE",
+      ""
+    ],
+    [
+      25,
+      "CAN_TXD",
+      ""
+    ],
+    [
+      28,
+      "UART2_RXD",
+      ""
+    ],
+    [
+      29,
+      "UART2_TXD",
+      ""
+    ],
+    [
+      38,
+      "DBG_RXD",
+      ""
+    ],
+    [
+      39,
+      "DBG_TXD",
+      ""
+    ],
+    [
+      49,
+      "LCD_RST",
+      ""
+    ],
+    [
+      50,
+      "LCD_SDA",
+      ""
+    ],
+    [
+      51,
+      "LCD_RS",
+      ""
+    ],
+    [
+      52,
+      "LCD_CS",
+      ""
+    ],
+    [
+      53,
+      "LCD_CLK",
+      ""
+    ],
+    [
+      54,
+      "CAM_MCLK",
+      ""
+    ],
+    [
+      55,
+      "CAM_RX0",
+      ""
+    ],
+    [
+      56,
+      "CAM_RX1",
+      ""
+    ],
+    [
+      61,
+      "VBUS",
+      ""
+    ],
+    [
+      66,
+      "I2C1_SDA",
+      ""
+    ],
+    [
+      67,
+      "I2C1_SCL",
+      ""
+    ],
+    [
+      75,
+      "WAKEUP6",
+      ""
+    ],
+    [
+      78,
+      "CAN_STB",
+      ""
+    ],
+    [
+      79,
+      "USIM_DET",
+      ""
+    ],
+    [
+      80,
+      "CAM_BCLK",
+      ""
+    ],
+    [
+      81,
+      "CAM_CS",
+      ""
+    ],
+    [
+      82,
+      "USB_BOOT",
+      ""
+    ],
+    [
+      83,
+      "SPI0_CS",
+      ""
+    ],
+    [
+      84,
+      "SPI0_MISO",
+      ""
+    ],
+    [
+      85,
+      "SPI0_MOSI",
+      ""
+    ],
+    [
+      86,
+      "SPI0_CLK",
+      ""
+    ],
+    [
+      97,
+      "GPIO16",
+      ""
+    ],
+    [
+      99,
+      "GPIO23",
+      ""
+    ],
+    [
+      100,
+      "GPIO17",
+      ""
+    ],
+    [
+      101,
+      "WAKEUP0",
+      ""
+    ],
+    [
+      106,
+      "CAN_RXD",
+      ""
+    ],
+    [
+      107,
+      "GPIO21",
+      ""
+    ]
+  ]
+}

+ 184 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pwm_app.lua

@@ -0,0 +1,184 @@
+--[[
+@module  pwm_app
+@summary PWM 输出功能模块
+@version 1.0
+@date    2025.11.05
+@author  马梦阳
+@usage
+本功能模块演示的内容为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+3. 综合任务调度:顺序运行上述两种风格示例,并在关键节点进行日志输出
+
+注意事项:
+1. 本 demo 演示所使用的是 Air780EHM/EHV/EGH 模组的 PWM4 通道(GPIO27,PIN16);
+2. 该引脚需要通过 LuatIO 工具进行复用配置:
+    pins_Air780EHM.json 为 Air780EHM 模组的复用配置文件;
+    pins_Air780EHV.json 为 Air780EHV 模组的复用配置文件;
+    pins_Air780EGH.json 为 Air780EGH 模组的复用配置文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+本文件没有对外接口,直接在 main.lua 中 require "pwm_app" 就可以加载运行;
+]]
+
+--[[
+旧风格 PWM 演示函数
+使用 pwm.open() 一次性完成配置和启动
+适合固定频率/占空比、无需中途调整的场景
+]]
+local function task1_old_pwm()
+    log.info("PWM", "旧风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air780EHM/EHV/EGH 模组的 PWM4 通道(GPIO27,PIN16);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 第一次输出:1 kHz,45% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 1000, 45, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 1 s 后关闭
+    sys.wait(1000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第二次输出:500 Hz,60% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 500, 60, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 2 s 后关闭
+    sys.wait(2000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第三次输出:300 Hz,80% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 300, 80, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 3 s 后关闭
+    sys.wait(3000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    log.info("PWM", "旧风格 PWM 示例结束")
+end
+
+
+--[[
+新风格 PWM 演示函数
+使用 pwm.setup() 分步完成配置与启动,支持运行中动态修改频率和占空比
+适合需要实时调节输出参数的场景
+]]
+local function task2_new_pwm()
+    log.info("PWM", "新风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air780EHM/EHV/EGH 模组的 PWM4 通道(GPIO27,PIN16);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 50, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%")
+    else
+        log.info("PWM", "PWM4 配置失败")
+    end
+
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 启动成功")
+    else
+        log.info("PWM", "PWM4 启动失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整占空比至 25%
+    local setduty_success = pwm.setDuty(pwm_channel, 25)
+    if setduty_success then
+        log.info("PWM", "PWM4 占空比更新为 25%")
+    else
+        log.info("PWM", "PWM4 占空比设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整信号频率为 2000 Hz
+    local setfreq_success = pwm.setFreq(pwm_channel, 2000)
+    if setfreq_success then
+        log.info("PWM", "PWM4 频率更新为 2000 Hz")
+    else
+        log.error("PWM", "PWM4 频率设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 停止成功")
+    else
+        log.info("PWM", "PWM4 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+
+--[[
+主演示任务:
+顺序调用旧风格与新风格 PWM 示例函数
+并在两者之间插入 3 秒间隔方便区分新旧风格示例输出情况
+]]
+local function pwm_demo_task()
+    log.info("PWM", "PWM 综合演示任务开始")
+
+    -- 运行旧风格 PWM 示例
+    task1_old_pwm()
+
+    -- 间隔 3 秒
+    sys.wait(3000)
+
+    -- 运行新风格 PWM 示例
+    task2_new_pwm()
+
+    log.info("PWM", "PWM 综合演示任务结束")
+end
+
+-- 创建并启动一个 task
+-- 用于运行 pwm_demo_task 函数
+sys.taskInit(pwm_demo_task)

+ 0 - 26
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/pwm_output.lua

@@ -1,26 +0,0 @@
---[[
-@module  pwm_output
-@summary PWM输出模块
-@version 1.0
-@date    2025.07.08
-@author  王世豪
-@usage
-使用Air780EHV核心板的GPIO引脚输出PWM波形,演示不同占空比的PWM波形输出效果。
-]]
-
-local PWM_ID = 0
-local function pwm_output()
-    while true do
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
-        pwm.open(PWM_ID, 1000, 10, 0, 1000) -- 小灯微微发光
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为1000,占空比为500/1000=50% 持续输出
-        pwm.open(PWM_ID, 1000, 500, 0, 1000) -- 小灯中等亮度
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为1000,占空比为1000/1000=100% 持续输出
-        pwm.open(PWM_ID, 1000, 1000, 0, 1000) -- 小灯很高亮度
-        sys.wait(1000)
-    end
-end
-
-sys.taskInit(pwm_output)

+ 67 - 10
module/Air780EHM_Air780EHV_Air780EGH/demo/pwm/readme.md

@@ -1,32 +1,89 @@
+## 演示模块概述
+
+1、main.lua:主程序入口;
+
+2、pwm_app.lua:PWM 输出功能模块;
+
+3、pins_Air780EHM.json:用于配置 Air780EHM 模组管脚复用功能的 json 文件;
+
+4、pins_Air780EHV.json:用于配置 Air780EHV 模组管脚复用功能的 json 文件;
+
+5、pins_Air780EGH.json:用于配置 Air780EGH 模组管脚复用功能的 json 文件;
+
+- 关于如何生成 json 文件参考:https://docs.openluat.com/air780epm/common/luatio/;
+- 示例代码中使用的是 Air780EHM/EHV/EGH 模组的 PWM4 通道(GPIO27,PIN16),参考完上述文档后通过 LuatIO 工具配置好并保存,最后将对应模组的 json 文件与脚本代码一同烧录到对应模组中即可实现 PWM 输出功能;
 
 ## 演示功能概述
 
-将使用Air780EHV核心板,演示PWM控制GPIO引脚输出PWM波形,以及控制GPIO引脚输出呼吸灯效果。
+使用 Air780EHM/EHV/EGH 核心板搭配 PWM 库演示 PWM 输出功能;
+
+PWM 库目前有两套 API 风格:
+
+1、旧风格 PWM 演示:
+
+- 使用 pwm.open() 函数一次性完成 PWM 通道的配置与启动
+- 使用 pwm.close() 函数关闭 PWM 通道
+- 旧风格 PWM 接口不支持动态调整参数
+
+2、新风格 PWM 演示:
+
+- 使用 pwm.setup() 函数进行 PWM 参数配置
+- 使用 pwm.start() 函数开启 PWM 通道进行 PWM 输出
+- 使用 pwm.setDuty() 函数动态调整占空比,支持在开启 PWM 通道后调用
+- 使用 pwm.setFreq() 函数动态调整信号频率,支持在开启 PWM 通道后调用
+- 新风格 PWM 接口支持实时动态调整占空比和信号频率
 
 ## 演示硬件环境
 
-1、Air780EHV核心板一块
+1、Air780EHM/EHV/EGH 核心板一块
 
 2、TYPE-C USB数据线一根
 
-3、Air780EHV核心板和数据线的硬件接线方式为
+3、杜邦线若干
 
-- Air780EHV核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
+4、逻辑分析仪或者示波器,用于观察 PWM 输出的波形
 
-- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
+5、代码中选用的 PWM 通道是 Air780EHM/EHV/EGH 模组的 PWM4(GPIO27,PIN16)
 
 ## 演示软件环境
 
-1、Luatools下载调试工具
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air780EHM V2016 版本](https://docs.openluat.com/air780epm/luatos/firmware/version/)(理论上最新版本固件也可以,如果使用最新版本的固件不可以,可以烧录 V2016-1 固件对比验证)
+
+3、[Air780EHV V2016 版本](https://docs.openluat.com/air780ehv/luatos/firmware/version/)(理论上最新版本固件也可以,如果使用最新版本的固件不可以,可以烧录 V2016-1 固件对比验证)
 
-2、[Air780EHV V2008版本固件](https://docs.openluat.com/air780ehv/luatos/firmware/version/)(测试使用V2008 1号固件)
+4、[Air780EGH V2016 版本](https://docs.openluat.com/air780egh/luatos/firmware/version/)(理论上最新版本固件也可以,如果使用最新版本的固件不可以,可以烧录 V2016-1 固件对比验证
 
 ## 演示核心步骤
 
-1、搭建好演示硬件环境
+1、搭建好硬件环境
 
-2、通过Luatools将demo与固件烧录到核心板中
+2、Luatools 工具烧录内核固件和 demo 脚本代码
 
 3、烧录成功后,自动开机运行
 
-4、接下来通过示波器查看波形,使用发光二极管演示呼吸灯效果。
+4、正常运行情况时的日志如下:
+
+```
+[000000000.427] I/user.main PWM 001.000.000
+[000000000.434] I/user.PWM PWM 综合演示任务开始
+[000000000.434] I/user.PWM 旧风格 PWM 示例开始
+[000000000.435] I/user.PWM PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%
+[000000001.435] I/user.PWM PWM4 通道已关闭
+[000000002.435] I/user.PWM PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%
+[000000004.436] I/user.PWM PWM4 通道已关闭
+[000000005.436] I/user.PWM PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%
+[000000008.437] I/user.PWM PWM4 通道已关闭
+[000000008.437] I/user.PWM 旧风格 PWM 示例结束
+[000000011.437] I/user.PWM 新风格 PWM 示例开始
+[000000011.438] I/user.PWM PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%
+[000000011.438] I/user.PWM PWM4 启动成功
+[000000013.438] I/user.PWM PWM4 占空比更新为 25%
+[000000015.439] I/user.PWM PWM4 频率更新为 2000 Hz
+[000000017.439] I/user.PWM PWM4 停止成功
+[000000017.440] I/user.PWM 新风格 PWM 示例结束
+[000000017.440] I/user.PWM PWM 综合演示任务结束
+```
+
+5、使用逻辑分析仪或者示波器观察 PWM 输出波形是否与配置的参数一致

+ 93 - 0
module/Air780EPM/demo/pwm/main.lua

@@ -0,0 +1,93 @@
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
+@version 1.0
+@date    2025.11.05
+@author  马梦阳
+@usage
+
+本demo演示的核心功能为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+
+注意事项:
+1. 本 demo 演示所使用的是 Air780EPM 模组的 PWM4 通道(GPIO27,PIN16);
+2. 该引脚需要通过 LuatIO 工具进行复用配置,pins_Air780EPM.json 文件即复用配置后生成的文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+注意!!!!pwm.setFreq() 函数目前出现一些 BUG,调用成功后无法正常输出波形,正在紧急修复,时间 2025.10.29
+
+更多说明参考本目录下的 readme.md 文件;
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "PWM"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
+
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
+if wdt then
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
+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)
+
+
+-- 加载 PWM 应用模块
+require "pwm_app"
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 52 - 0
module/Air780EPM/demo/pwm/pins_Air780EPM.json

@@ -0,0 +1,52 @@
+{
+  "model": "Air780EPM",
+  "pins": [
+    [7, "PWR_KEY", ""],
+    [16, "PWM4", ""],
+    [17, "UART1_RXD", ""],
+    [18, "UART1_TXD", ""],
+    [19, "GPIO22", ""],
+    [20, "PWM1", ""],
+    [22, "PWM0", ""],
+    [23, "ONEWIRE", ""],
+    [25, "CAN_TXD", ""],
+    [26, "GPIO33", ""],
+    [28, "UART2_RXD", ""],
+    [29, "UART2_TXD", ""],
+    [30, "GPIO29", ""],
+    [31, "GPIO30", ""],
+    [32, "GPIO31", ""],
+    [33, "GPIO32", ""],
+    [38, "DBG_RXD", ""],
+    [39, "DBG_TXD", ""],
+    [49, "LCD_RST", ""],
+    [50, "LCD_SDA", ""],
+    [51, "LCD_RS", ""],
+    [52, "LCD_CS", ""],
+    [53, "LCD_CLK", ""],
+    [54, "CAM_MCLK", ""],
+    [55, "CAM_RX0", ""],
+    [56, "CAM_RX1", ""],
+    [57, "UART3_TXD", ""],
+    [58, "UART3_RXD", ""],
+    [61, "VBUS", ""],
+    [66, "I2C1_SDA", ""],
+    [67, "I2C1_SCL", ""],
+    [78, "GPIO28", ""],
+    [79, "USIM_DET", ""],
+    [80, "CAM_BCLK", ""],
+    [81, "CAM_CS", ""],
+    [82, "USB_BOOT", ""],
+    [83, "SPI0_CS", ""],
+    [84, "SPI0_MISO", ""],
+    [85, "SPI0_MOSI", ""],
+    [86, "SPI0_CLK", ""],
+    [97, "GPIO16", ""],
+    [99, "GPIO23", ""],
+    [100, "GPIO17", ""],
+    [101, "WAKEUP0", ""],
+    [102, "GPIO20", ""],
+    [106, "CAN_RXD", ""],
+    [107, "GPIO21", ""]
+  ]
+}

+ 181 - 0
module/Air780EPM/demo/pwm/pwm_app.lua

@@ -0,0 +1,181 @@
+--[[
+@module  pwm_app
+@summary PWM 输出功能模块
+@version 1.0
+@date    2025.11.05
+@author  马梦阳
+@usage
+本功能模块演示的内容为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+3. 综合任务调度:顺序运行上述两种风格示例,并在关键节点进行日志输出
+
+注意事项:
+1. 本 demo 演示所使用的是 Air780EPM 模组的 PWM4 通道(GPIO27,PIN16);
+2. 该引脚需要通过 LuatIO 工具进行复用配置,pins_Air780EPM.json 文件即复用配置后生成的文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+本文件没有对外接口,直接在 main.lua 中 require "pwm_app" 就可以加载运行;
+]]
+
+--[[
+旧风格 PWM 演示函数
+使用 pwm.open() 一次性完成配置和启动
+适合固定频率/占空比、无需中途调整的场景
+]]
+local function task1_old_pwm()
+    log.info("PWM", "旧风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air780EPM 模组的 PWM4 通道(GPIO27,PIN16);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 第一次输出:1 kHz,45% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 1000, 45, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 1 s 后关闭
+    sys.wait(1000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第二次输出:500 Hz,60% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 500, 60, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 2 s 后关闭
+    sys.wait(2000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第三次输出:300 Hz,80% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 300, 80, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 3 s 后关闭
+    sys.wait(3000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    log.info("PWM", "旧风格 PWM 示例结束")
+end
+
+
+--[[
+新风格 PWM 演示函数
+使用 pwm.setup() 分步完成配置与启动,支持运行中动态修改频率和占空比
+适合需要实时调节输出参数的场景
+]]
+local function task2_new_pwm()
+    log.info("PWM", "新风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air780EPM 模组的 PWM4 通道(GPIO27,PIN16);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 50, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%")
+    else
+        log.info("PWM", "PWM4 配置失败")
+    end
+
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 启动成功")
+    else
+        log.info("PWM", "PWM4 启动失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整占空比至 25%
+    local setduty_success = pwm.setDuty(pwm_channel, 25)
+    if setduty_success then
+        log.info("PWM", "PWM4 占空比更新为 25%")
+    else
+        log.info("PWM", "PWM4 占空比设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整信号频率为 2000 Hz
+    local setfreq_success = pwm.setFreq(pwm_channel, 2000)
+    if setfreq_success then
+        log.info("PWM", "PWM4 频率更新为 2000 Hz")
+    else
+        log.error("PWM", "PWM4 频率设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 停止成功")
+    else
+        log.info("PWM", "PWM4 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+
+--[[
+主演示任务:
+顺序调用旧风格与新风格 PWM 示例函数
+并在两者之间插入 3 秒间隔方便区分新旧风格示例输出情况
+]]
+local function pwm_demo_task()
+    log.info("PWM", "PWM 综合演示任务开始")
+
+    -- 运行旧风格 PWM 示例
+    task1_old_pwm()
+
+    -- 间隔 3 秒
+    sys.wait(3000)
+
+    -- 运行新风格 PWM 示例
+    task2_new_pwm()
+
+    log.info("PWM", "PWM 综合演示任务结束")
+end
+
+-- 创建并启动一个 task
+-- 用于运行 pwm_demo_task 函数
+sys.taskInit(pwm_demo_task)

+ 81 - 0
module/Air780EPM/demo/pwm/readme.md

@@ -0,0 +1,81 @@
+## 演示模块概述
+
+1、main.lua:主程序入口;
+
+2、pwm_app.lua:PWM 输出功能模块;
+
+3、pins_Air780EPM.json:用于配置管脚复用功能的 json 文件;
+
+- 关于如何生成 json 文件参考:https://docs.openluat.com/air780epm/common/luatio/;
+- 示例代码中使用的是 Air780EPM 模组的 PWM4 通道(GPIO27,PIN16),参考完上述文档后通过 LuatIO 工具配置好并保存,最后连同脚本一起烧录到 Air780EPM 模组中即可实现 PWM 输出功能;
+
+## 演示功能概述
+
+使用 Air780EPM 核心板搭配 PWM 库演示 PWM 输出功能;
+
+PWM 库目前有两套 API 风格:
+
+1、旧风格 PWM 演示:
+
+- 使用 pwm.open() 函数一次性完成 PWM 通道的配置与启动
+- 使用 pwm.close() 函数关闭 PWM 通道
+- 旧风格 PWM 接口不支持动态调整参数
+
+2、新风格 PWM 演示:
+
+- 使用 pwm.setup() 函数进行 PWM 参数配置
+- 使用 pwm.start() 函数开启 PWM 通道进行 PWM 输出
+- 使用 pwm.setDuty() 函数动态调整占空比,支持在开启 PWM 通道后调用
+- 使用 pwm.setFreq() 函数动态调整信号频率,支持在开启 PWM 通道后调用
+- 新风格 PWM 接口支持实时动态调整占空比和信号频率
+
+## 演示硬件环境
+
+1、Air780EPM 核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、杜邦线若干
+
+4、逻辑分析仪或者示波器,用于观察 PWM 输出的波形
+
+5、代码中选用的 PWM 通道是 Air780EPM 模组的 PWM4(GPIO27,PIN16)
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air780EPM V2016 版本](https://docs.openluat.com/air780epm/luatos/firmware/version/)(理论上最新版本固件也可以,如果使用最新版本的固件不可以,可以烧录 V2016-1 固件对比验证)
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools 工具烧录内核固件和 demo 脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、正常运行情况时的日志如下:
+
+```
+[000000000.427] I/user.main PWM 001.000.000
+[000000000.434] I/user.PWM PWM 综合演示任务开始
+[000000000.434] I/user.PWM 旧风格 PWM 示例开始
+[000000000.435] I/user.PWM PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%
+[000000001.435] I/user.PWM PWM4 通道已关闭
+[000000002.435] I/user.PWM PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%
+[000000004.436] I/user.PWM PWM4 通道已关闭
+[000000005.436] I/user.PWM PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%
+[000000008.437] I/user.PWM PWM4 通道已关闭
+[000000008.437] I/user.PWM 旧风格 PWM 示例结束
+[000000011.437] I/user.PWM 新风格 PWM 示例开始
+[000000011.438] I/user.PWM PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%
+[000000011.438] I/user.PWM PWM4 启动成功
+[000000013.438] I/user.PWM PWM4 占空比更新为 25%
+[000000015.439] I/user.PWM PWM4 频率更新为 2000 Hz
+[000000017.439] I/user.PWM PWM4 停止成功
+[000000017.440] I/user.PWM 新风格 PWM 示例结束
+[000000017.440] I/user.PWM PWM 综合演示任务结束
+```
+
+5、使用逻辑分析仪或者示波器观察 PWM 输出波形是否与配置的参数一致

+ 0 - 38
module/Air780EPM/demo/pwm/示例1 PWM输出/main.lua

@@ -1,38 +0,0 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-sys.taskInit(function()
-    gpio.setup(27,1)
-end)
-
--- sys.taskInit(function()
---     while true do
---         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
---         pwm.open(4, 1000, 10, 0, 1000) -- 小灯微微发光
---         sys.wait(1000)
---         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为500/1000=50% 持续输出
---         pwm.open(4, 1000, 500, 0, 1000) -- 小灯中等亮度
---         sys.wait(1000)
---         -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为1000/1000=100% 持续输出
---         pwm.open(4, 1000, 1000, 0, 1000) -- 小灯很高亮度
---         sys.wait(1000)
---     end
--- end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 58
module/Air780EPM/demo/pwm/示例2 呼吸灯效果/main.lua

@@ -1,58 +0,0 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local PWM_ID = 0
-local rtos_bsp = rtos.bsp()
-if rtos_bsp == "EC618" then
-    PWM_ID = 1 -- GPIO 24
-elseif string.find(rtos_bsp,"EC718") then
-    PWM_ID = 2 -- GPIO 25
-elseif rtos_bsp == "AIR101" or rtos_bsp == "AIR103" or rtos_bsp == "AIR601"  then
-    PWM_ID = 4 -- GPIO 4
-elseif rtos_bsp:startsWith("ESP32") then
-    -- 注意, ESP32系列的PWM, PWM通道均与GPIO号相同
-    -- 例如需要用GPIO1输出PWM, 对应的PWM通道就是1
-    -- 需要用GPIO16输出PWM, 对应的PWM通道就是16
-    if rtos_bsp == "ESP32C3" then
-        PWM_ID = 12 -- GPIO 12
-    elseif rtos_bsp == "ESP32S3" then
-        PWM_ID = 11 -- GPIO 11
-    end
-elseif rtos_bsp == "AIR105" then
-    PWM_ID = 1 -- GPIO 17
-end
-
-sys.taskInit(function()
-    log.info("pwm", "ch", PWM_ID)
-    while 1 do
-        -- 仿呼吸灯效果
-        log.info("pwm", ">>>>>")
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, i*9) -- 频率1000hz, 占空比0-100
-            sys.wait(100 + i*10)
-        end
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, 100 - i*9)
-            sys.wait(100 + i*10)
-        end
-        sys.wait(2000)
-    end
-end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 50
module/Air8000/demo/pwm/PWM呼吸灯/main.lua

@@ -1,50 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.1"
-
---[[
-注意:Air8000_V2007及以上固件复用方式已经改为使用LuatIO工具。
-本demo也已经使用LuatIO方式进行复用,代码中仅初始化PWM所用IO,没有进行复用操作。
-运行本demo需要将pins_Air8000.json文件一并烧录进Air8000中,才能正常使用PWM功能。
-LuatIO工具使用方法+下载地址:https://docs.openluat.com/air8000/common/luatio/?h=luatio
-]]
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000) -- 初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local PWM_ID = 4  -- 代码中使用pwm通道4,如需使用其他pwm通道请查看Air8000/pwm使用指南/pwm通道说明。
-sys.taskInit(function()
-    
-    -- 设置演示所用的IO GPIO21 且初始化电平为低
-    gpio.setup(21, 0)
-
-    log.info("pwm", "ch", PWM_ID)
-    while 1 do
-        -- 仿呼吸灯效果
-        log.info("pwm", ">>>>>")
-        -- 占空比从90%(i=10时)到9%(i=1时)
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, i*9) -- 频率1000hz, 占空比0-100
-            sys.wait(100 + i*10)
-        end
-        -- 占空比从10%增加到90%
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, 100 - i*9)
-            sys.wait(100 + i*10)
-        end
-        sys.wait(2000)
-    end
-end) 
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 54
module/Air8000/demo/pwm/PWM呼吸灯/pins_Air8000.json

@@ -1,54 +0,0 @@
-{
-  "model": "Air8000",
-  "pins": [
-    [1, "USB_BOOT", ""],
-    [2, "VBUS", ""],
-    [14, "PWR_KEY", ""],
-    [16, "UART1_TXD", ""],
-    [17, "UART1_RXD", ""],
-    [18, "I2S_BCLK", ""],
-    [19, "I2S_LRCK", ""],
-    [20, "I2S_DIN", ""],
-    [21, "I2S_DOUT", ""],
-    [22, "I2S_MCLK", ""],
-    [23, "GPIO20", ""],
-    [24, "PWM4", "PWM4"],
-    [25, "LCD_CLK", ""],
-    [26, "LCD_CS", ""],
-    [27, "LCD_RST", ""],
-    [28, "LCD_SDA", ""],
-    [29, "LCD_RS", ""],
-    [30, "GPIO2", ""],
-    [31, "GPIO1", ""],
-    [35, "CAN_STB", ""],
-    [36, "CAN_TXD", ""],
-    [37, "CAN_RXD", ""],
-    [38, "SPI1_SCLK", ""],
-    [39, "SPI1_MISO", ""],
-    [40, "SPI1_MOSI", ""],
-    [41, "SPI1_CS", ""],
-    [43, "WAKEUP6", ""],
-    [44, "WAKEUP0", ""],
-    [46, "DBG_TXD", ""],
-    [47, "DBG_RXD", ""],
-    [48, "UART11_RXD", ""],
-    [49, "UART11_TXD", ""],
-    [52, "GPIO153", ""],
-    [53, "GPIO147", ""],
-    [54, "GPIO146", ""],
-    [55, "GPIO141", ""],
-    [56, "GPIO140", ""],
-    [59, "UART12_RXD", ""],
-    [60, "UART12_TXD", ""],
-    [66, "I2C1_SCL", ""],
-    [67, "I2C1_SDA", ""],
-    [73, "GPIO162", ""],
-    [74, "GPIO164", ""],
-    [80, "I2C0_SCL", ""],
-    [81, "I2C0_SDA", ""],
-    [82, "GPIO17", ""],
-    [83, "GPIO16", ""],
-    [96, "GPIO160", ""],
-    [98, "GPIO3", ""]
-  ]
-}

+ 0 - 49
module/Air8000/demo/pwm/PWM输出/main.lua

@@ -1,49 +0,0 @@
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.1"
-
---[[
-注意:Air8000_V2007及以上固件复用方式已经改为使用LuatIO工具。
-本demo也已经使用LuatIO方式进行复用,代码中仅初始化PWM所用IO,没有进行复用操作。
-运行本demo需要将pins_Air8000.json文件一并烧录进Air8000中,才能正常使用PWM功能。
-LuatIO工具使用方法+下载地址:https://docs.openluat.com/air8000/common/luatio/?h=luatio
-]]
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000) -- 初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local PWM_ID = 4  -- 代码中使用pwm通道4,如需使用其他pwm通道请查看Air8000/pwm使用指南/pwm通道说明。
-sys.taskInit(function()
-
-    -- 设置演示所用的IO GPIO21 且初始化电平为低
-    gpio.setup(21, 0)
-
-    log.info("pwm", "ch", PWM_ID)
-    while true do
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
-        pwm.open(PWM_ID, 1000, 10, 0, 1000) -- 小灯微微发光
-        log.info("pwm", "当前分频精度1000,占空比1%")
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为256,占空比为128/256=50% 持续输出
-        pwm.open(PWM_ID, 1000, 128, 0, 256) -- 小灯中等亮度
-        log.info("pwm", "当前分频精度256,占空比50%")
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为100,占空比为100/100=100% 持续输出
-        pwm.open(PWM_ID, 1000, 100, 0, 100) -- 小灯很高亮度
-        log.info("pwm", "当前分频精度100,占空比100%")
-        sys.wait(1000)
-    end
-end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 54
module/Air8000/demo/pwm/PWM输出/pins_Air8000.json

@@ -1,54 +0,0 @@
-{
-  "model": "Air8000",
-  "pins": [
-    [1, "USB_BOOT", ""],
-    [2, "VBUS", ""],
-    [14, "PWR_KEY", ""],
-    [16, "UART1_TXD", ""],
-    [17, "UART1_RXD", ""],
-    [18, "I2S_BCLK", ""],
-    [19, "I2S_LRCK", ""],
-    [20, "I2S_DIN", ""],
-    [21, "I2S_DOUT", ""],
-    [22, "I2S_MCLK", ""],
-    [23, "GPIO20", ""],
-    [24, "PWM4", "PWM4"],
-    [25, "LCD_CLK", ""],
-    [26, "LCD_CS", ""],
-    [27, "LCD_RST", ""],
-    [28, "LCD_SDA", ""],
-    [29, "LCD_RS", ""],
-    [30, "GPIO2", ""],
-    [31, "GPIO1", ""],
-    [35, "CAN_STB", ""],
-    [36, "CAN_TXD", ""],
-    [37, "CAN_RXD", ""],
-    [38, "SPI1_SCLK", ""],
-    [39, "SPI1_MISO", ""],
-    [40, "SPI1_MOSI", ""],
-    [41, "SPI1_CS", ""],
-    [43, "WAKEUP6", ""],
-    [44, "WAKEUP0", ""],
-    [46, "DBG_TXD", ""],
-    [47, "DBG_RXD", ""],
-    [48, "UART11_RXD", ""],
-    [49, "UART11_TXD", ""],
-    [52, "GPIO153", ""],
-    [53, "GPIO147", ""],
-    [54, "GPIO146", ""],
-    [55, "GPIO141", ""],
-    [56, "GPIO140", ""],
-    [59, "UART12_RXD", ""],
-    [60, "UART12_TXD", ""],
-    [66, "I2C1_SCL", ""],
-    [67, "I2C1_SDA", ""],
-    [73, "GPIO162", ""],
-    [74, "GPIO164", ""],
-    [80, "I2C0_SCL", ""],
-    [81, "I2C0_SDA", ""],
-    [82, "GPIO17", ""],
-    [83, "GPIO16", ""],
-    [96, "GPIO160", ""],
-    [98, "GPIO3", ""]
-  ]
-}

+ 93 - 0
module/Air8000/demo/pwm/main.lua

@@ -0,0 +1,93 @@
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
+@version 1.0
+@date    2025.10.29
+@author  马梦阳
+@usage
+
+本demo演示的核心功能为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+
+注意事项:
+1. 本 demo 演示所使用的是 Air8000 模组的 PWM4 通道(GPIO21,PIN24);
+2. 该引脚需要通过 LuatIO 工具进行复用配置,pins_Air8000.json 文件即复用配置后生成的文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+注意!!!!pwm.setFreq() 函数目前出现一些 BUG,调用成功后无法正常输出波形,正在紧急修复,时间 2025.10.29
+
+更多说明参考本目录下的 readme.md 文件;
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "PWM"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
+
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
+if wdt then
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
+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)
+
+
+-- 加载 PWM 应用模块
+require "pwm_app"
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 250 - 0
module/Air8000/demo/pwm/pins_Air8000.json

@@ -0,0 +1,250 @@
+{
+  "model": "Air8000",
+  "pins": [
+    [
+      1,
+      "USB_BOOT",
+      ""
+    ],
+    [
+      2,
+      "VBUS",
+      ""
+    ],
+    [
+      14,
+      "PWR_KEY",
+      ""
+    ],
+    [
+      16,
+      "UART1_TXD",
+      ""
+    ],
+    [
+      17,
+      "UART1_RXD",
+      ""
+    ],
+    [
+      18,
+      "I2S_BCLK",
+      ""
+    ],
+    [
+      19,
+      "I2S_LRCK",
+      ""
+    ],
+    [
+      20,
+      "I2S_DIN",
+      ""
+    ],
+    [
+      21,
+      "I2S_DOUT",
+      ""
+    ],
+    [
+      22,
+      "I2S_MCLK",
+      ""
+    ],
+    [
+      23,
+      "GPIO20",
+      ""
+    ],
+    [
+      24,
+      "PWM4",
+      ""
+    ],
+    [
+      25,
+      "LCD_CLK",
+      ""
+    ],
+    [
+      26,
+      "LCD_CS",
+      ""
+    ],
+    [
+      27,
+      "LCD_RST",
+      ""
+    ],
+    [
+      28,
+      "LCD_SDA",
+      ""
+    ],
+    [
+      29,
+      "LCD_RS",
+      ""
+    ],
+    [
+      30,
+      "GPIO2",
+      ""
+    ],
+    [
+      31,
+      "GPIO1",
+      ""
+    ],
+    [
+      35,
+      "CAN_STB",
+      ""
+    ],
+    [
+      36,
+      "CAN_TXD",
+      ""
+    ],
+    [
+      37,
+      "CAN_RXD",
+      ""
+    ],
+    [
+      38,
+      "SPI1_SCLK",
+      ""
+    ],
+    [
+      39,
+      "SPI1_MISO",
+      ""
+    ],
+    [
+      40,
+      "SPI1_MOSI",
+      ""
+    ],
+    [
+      41,
+      "SPI1_CS",
+      ""
+    ],
+    [
+      43,
+      "WAKEUP6",
+      ""
+    ],
+    [
+      44,
+      "WAKEUP0",
+      ""
+    ],
+    [
+      46,
+      "DBG_TXD",
+      ""
+    ],
+    [
+      47,
+      "DBG_RXD",
+      ""
+    ],
+    [
+      48,
+      "UART11_RXD",
+      ""
+    ],
+    [
+      49,
+      "UART11_TXD",
+      ""
+    ],
+    [
+      52,
+      "GPIO153",
+      ""
+    ],
+    [
+      53,
+      "GPIO147",
+      ""
+    ],
+    [
+      54,
+      "GPIO146",
+      ""
+    ],
+    [
+      55,
+      "GPIO141",
+      ""
+    ],
+    [
+      56,
+      "GPIO140",
+      ""
+    ],
+    [
+      59,
+      "UART12_RXD",
+      ""
+    ],
+    [
+      60,
+      "UART12_TXD",
+      ""
+    ],
+    [
+      66,
+      "I2C1_SCL",
+      ""
+    ],
+    [
+      67,
+      "I2C1_SDA",
+      ""
+    ],
+    [
+      73,
+      "GPIO162",
+      ""
+    ],
+    [
+      74,
+      "GPIO164",
+      ""
+    ],
+    [
+      80,
+      "I2C0_SCL",
+      ""
+    ],
+    [
+      81,
+      "I2C0_SDA",
+      ""
+    ],
+    [
+      82,
+      "GPIO17",
+      ""
+    ],
+    [
+      83,
+      "GPIO16",
+      ""
+    ],
+    [
+      96,
+      "GPIO160",
+      ""
+    ],
+    [
+      98,
+      "GPIO3",
+      ""
+    ]
+  ]
+}

+ 181 - 0
module/Air8000/demo/pwm/pwm_app.lua

@@ -0,0 +1,181 @@
+--[[
+@module  pwm_app
+@summary PWM 输出功能模块
+@version 1.0
+@date    2025.10.29
+@author  马梦阳
+@usage
+本功能模块演示的内容为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+3. 综合任务调度:顺序运行上述两种风格示例,并在关键节点进行日志输出
+
+注意事项:
+1. 本 demo 演示所使用的是 Air8000 模组的 PWM4 通道(GPIO21,PIN24);
+2. 该引脚需要通过 LuatIO 工具进行复用配置,pins_Air8000.json 文件即复用配置后生成的文件;
+3. 关于 LuatIO 工具的使用介绍以及如何生成 json 文件,请参考 https://docs.openluat.com/air780epm/common/luatio/;
+3. 将通过 LuatIO 工具配置好复用关系后生成的 json 文件与脚本文件一同烧录到模组中即可实现 PWM 输出功能;
+
+本文件没有对外接口,直接在 main.lua 中 require "pwm_app" 就可以加载运行;
+]]
+
+--[[
+旧风格 PWM 演示函数
+使用 pwm.open() 一次性完成配置和启动
+适合固定频率/占空比、无需中途调整的场景
+]]
+local function task1_old_pwm()
+    log.info("PWM", "旧风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8000 模组的 PWM4 通道(GPIO21,PIN24);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 第一次输出:1 kHz,45% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 1000, 45, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 1 s 后关闭
+    sys.wait(1000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第二次输出:500 Hz,60% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 500, 60, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 2 s 后关闭
+    sys.wait(2000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第三次输出:300 Hz,80% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 300, 80, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 3 s 后关闭
+    sys.wait(3000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    log.info("PWM", "旧风格 PWM 示例结束")
+end
+
+
+--[[
+新风格 PWM 演示函数
+使用 pwm.setup() 分步完成配置与启动,支持运行中动态修改频率和占空比
+适合需要实时调节输出参数的场景
+]]
+local function task2_new_pwm()
+    log.info("PWM", "新风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8000 模组的 PWM4 通道(GPIO21,PIN24);
+    -- 该引脚需要通过 LuatIO 工具进行复用配置,详细说明看最顶部的注意事项;
+    local pwm_channel = 4
+
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 50, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%")
+    else
+        log.info("PWM", "PWM4 配置失败")
+    end
+
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 启动成功")
+    else
+        log.info("PWM", "PWM4 启动失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整占空比至 25%
+    local setduty_success = pwm.setDuty(pwm_channel, 25)
+    if setduty_success then
+        log.info("PWM", "PWM4 占空比更新为 25%")
+    else
+        log.info("PWM", "PWM4 占空比设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整信号频率为 2000 Hz
+    local setfreq_success = pwm.setFreq(pwm_channel, 2000)
+    if setfreq_success then
+        log.info("PWM", "PWM4 频率更新为 2000 Hz")
+    else
+        log.error("PWM", "PWM4 频率设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 停止成功")
+    else
+        log.info("PWM", "PWM4 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+
+--[[
+主演示任务:
+顺序调用旧风格与新风格 PWM 示例函数
+并在两者之间插入 3 秒间隔方便区分新旧风格示例输出情况
+]]
+local function pwm_demo_task()
+    log.info("PWM", "PWM 综合演示任务开始")
+
+    -- 运行旧风格 PWM 示例
+    task1_old_pwm()
+
+    -- 间隔 3 秒
+    sys.wait(3000)
+
+    -- 运行新风格 PWM 示例
+    task2_new_pwm()
+
+    log.info("PWM", "PWM 综合演示任务结束")
+end
+
+-- 创建并启动一个 task
+-- 用于运行 pwm_demo_task 函数
+sys.taskInit(pwm_demo_task)

+ 81 - 0
module/Air8000/demo/pwm/readme.md

@@ -0,0 +1,81 @@
+## 演示模块概述
+
+1、main.lua:主程序入口;
+
+2、pwm_app.lua:PWM 输出功能模块;
+
+3、pins_Air8000.json:用于配置管脚复用功能的 json 文件;
+
+- 关于如何生成 json 文件参考:https://docs.openluat.com/air780epm/common/luatio/;
+- 示例代码中使用的是 Air8000 模组的 PWM4 通道(GPIO21,PIN24),参考完上述文档后通过 LuatIO 工具配置好并保存,最后连同脚本一起烧录到 Air8000 模组中即可实现 PWM 输出功能;
+
+## 演示功能概述
+
+使用 Air8000 核心板搭配 PWM 库演示 PWM 输出功能;
+
+PWM 库目前有两套 API 风格:
+
+1、旧风格 PWM 演示:
+
+- 使用 pwm.open() 函数一次性完成 PWM 通道的配置与启动
+- 使用 pwm.close() 函数关闭 PWM 通道
+- 旧风格 PWM 接口不支持动态调整参数
+
+2、新风格 PWM 演示:
+
+- 使用 pwm.setup() 函数进行 PWM 参数配置
+- 使用 pwm.start() 函数开启 PWM 通道进行 PWM 输出
+- 使用 pwm.setDuty() 函数动态调整占空比,支持在开启 PWM 通道后调用
+- 使用 pwm.setFreq() 函数动态调整信号频率,支持在开启 PWM 通道后调用
+- 新风格 PWM 接口支持实时动态调整占空比和信号频率
+
+## 演示硬件环境
+
+1、Air8000 核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、杜邦线若干
+
+4、逻辑分析仪或者示波器,用于观察 PWM 输出的波形
+
+5、代码中选用的 PWM 通道是 Air8000 模组的 PWM4(GPIO21)
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air8000 V2016 版本](https://docs.openluat.com/air8000/luatos/common/download/)(理论上最新版本固件也可以,如果使用最新版本的固件不可以,可以烧录 V2016-1 固件对比验证)
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools 工具烧录内核固件和 demo 脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、正常运行情况时的日志如下:
+
+```
+[000000000.427] I/user.main PWM 001.000.000
+[000000000.434] I/user.PWM PWM 综合演示任务开始
+[000000000.434] I/user.PWM 旧风格 PWM 示例开始
+[000000000.435] I/user.PWM PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%
+[000000001.435] I/user.PWM PWM4 通道已关闭
+[000000002.435] I/user.PWM PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%
+[000000004.436] I/user.PWM PWM4 通道已关闭
+[000000005.436] I/user.PWM PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%
+[000000008.437] I/user.PWM PWM4 通道已关闭
+[000000008.437] I/user.PWM 旧风格 PWM 示例结束
+[000000011.437] I/user.PWM 新风格 PWM 示例开始
+[000000011.438] I/user.PWM PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%
+[000000011.438] I/user.PWM PWM4 启动成功
+[000000013.438] I/user.PWM PWM4 占空比更新为 25%
+[000000015.439] I/user.PWM PWM4 频率更新为 2000 Hz
+[000000017.439] I/user.PWM PWM4 停止成功
+[000000017.440] I/user.PWM 新风格 PWM 示例结束
+[000000017.440] I/user.PWM PWM 综合演示任务结束
+```
+
+5、使用逻辑分析仪或者示波器观察 PWM 输出波形是否与配置的参数一致

+ 0 - 34
module/Air8000/demo/pwm/示例1 PWM输出/main.lua

@@ -1,34 +0,0 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-sys.taskInit(function()
-    while true do
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
-        pwm.open(4, 1000, 10, 0, 1000) -- 小灯微微发光
-        sys.wait(1000)
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为500/1000=50% 持续输出
-        pwm.open(4, 1000, 500, 0, 1000) -- 小灯中等亮度
-        sys.wait(1000)
-        -- 开启pwm通道4,设置脉冲频率为1kHz,分频精度为1000,占空比为1000/1000=100% 持续输出
-        pwm.open(4, 1000, 1000, 0, 1000) -- 小灯很高亮度
-        sys.wait(1000)
-    end
-end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 0 - 58
module/Air8000/demo/pwm/示例2 呼吸灯效果/main.lua

@@ -1,58 +0,0 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.0"
-
-log.info("main", PROJECT, VERSION)
-
--- sys库是标配
-_G.sys = require("sys")
-
---添加硬狗防止程序卡死
-if wdt then
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
-local PWM_ID = 0
-local rtos_bsp = rtos.bsp()
-if rtos_bsp == "EC618" then
-    PWM_ID = 1 -- GPIO 24
-elseif string.find(rtos_bsp,"EC718") then
-    PWM_ID = 2 -- GPIO 25
-elseif rtos_bsp == "AIR101" or rtos_bsp == "AIR103" or rtos_bsp == "AIR601"  then
-    PWM_ID = 4 -- GPIO 4
-elseif rtos_bsp:startsWith("ESP32") then
-    -- 注意, ESP32系列的PWM, PWM通道均与GPIO号相同
-    -- 例如需要用GPIO1输出PWM, 对应的PWM通道就是1
-    -- 需要用GPIO16输出PWM, 对应的PWM通道就是16
-    if rtos_bsp == "ESP32C3" then
-        PWM_ID = 12 -- GPIO 12
-    elseif rtos_bsp == "ESP32S3" then
-        PWM_ID = 11 -- GPIO 11
-    end
-elseif rtos_bsp == "AIR105" then
-    PWM_ID = 1 -- GPIO 17
-end
-
-sys.taskInit(function()
-    log.info("pwm", "ch", PWM_ID)
-    while 1 do
-        -- 仿呼吸灯效果
-        log.info("pwm", ">>>>>")
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, i*9) -- 频率1000hz, 占空比0-100
-            sys.wait(100 + i*10)
-        end
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, 100 - i*9)
-            sys.wait(100 + i*10)
-        end
-        sys.wait(2000)
-    end
-end)
-
--- 用户代码已结束---------------------------------------------
--- 结尾总是这一句
-sys.run()
--- sys.run()之后后面不要加任何语句!!!!!

+ 79 - 47
module/Air8101/demo/pwm/main.lua

@@ -1,57 +1,89 @@
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
+@version 1.0
+@date    2025.11.05
+@author  马梦阳
+@usage
 
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "pwmdemo"
-VERSION = "1.0.0"
+本demo演示的核心功能为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
 
+注意事项:
+1. 本 demo 演示所使用的是 Air8101 模组的 PWM4 通道(GPIO24,PIN33);
+2. PWM 功能需要使用 V2xxx 版本固件,固件下载链接:https://docs.openluat.com/air8101/luatos/firmware/;
+
+注意!!!!pwm.setFreq() 函数目前出现一些 BUG,调用成功后无法正常输出波形,正在紧急修复,时间 2025.10.29
+
+更多说明参考本目录下的 readme.md 文件;
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "PWM"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
 log.info("main", PROJECT, VERSION)
 
---添加硬狗防止程序卡死
+
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
 if wdt then
-    wdt.init(9000) -- 初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 
--- 测试一
-local PWM_ID = 0  -- 代码中使用pwm通道0,如需使用其他pwm通道请查看Air8101/pwm使用指南/pwm通道说明。
-sys.taskInit(function()
-    while true do
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为1000,占空比为10/1000=1% 持续输出
-        pwm.open(PWM_ID, 1000, 10, 0, 1000) -- 小灯微微发光
-        log.info("pwm", "当前分频精度1000,占空比1%")
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为256,占空比为128/256=50% 持续输出
-        pwm.open(PWM_ID, 1000, 128, 0, 256) -- 小灯中等亮度
-        log.info("pwm", "当前分频精度256,占空比50%")
-        sys.wait(1000)
-        -- 开启pwm通道0,设置脉冲频率为1kHz,分频精度为100,占空比为100/100=100% 持续输出
-        pwm.open(PWM_ID, 1000, 100, 0, 100) -- 小灯很高亮度
-        log.info("pwm", "当前分频精度100,占空比100%")
-        sys.wait(1000)
-    end
-end)
-
-
--- 测试二
---[[ 
-local PWM_ID = 0
-sys.taskInit(function()
-    log.info("pwm", "ch", PWM_ID)
-    while 1 do
-        -- 仿呼吸灯效果
-        log.info("pwm", ">>>>>")
-        -- 占空比从90%(i=10时)到9%(i=1时)
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, i*9) -- 频率1000hz, 占空比0-100
-            sys.wait(100 + i*10)
-        end
-        -- 占空比从10%增加到90%
-        for i = 10,1,-1 do 
-            pwm.open(PWM_ID, 1000, 100 - i*9)
-            sys.wait(100 + i*10)
-        end
-        sys.wait(2000)
-    end
-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)
+
+
+-- 加载 PWM 应用模块
+require "pwm_app"
+
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句

+ 177 - 0
module/Air8101/demo/pwm/pwm_app.lua

@@ -0,0 +1,177 @@
+--[[
+@module  pwm_app
+@summary PWM 输出功能模块
+@version 1.0
+@date    2025.11.05
+@author  马梦阳
+@usage
+本功能模块演示的内容为:
+1. 旧风格 PWM 演示:
+    使用 pwm.open() 完成 PWM 通道的配置与启动
+    使用 pwm.close() 关闭 PWM 通道
+    旧风格 PWM 接口不支持单独配置和动态调整占空比和信号频率
+2. 新风格 PWM 演示:
+    使用 pwm.setup() 完成 PWM 通道的配置
+    使用 pwm.start() 启动 PWM 输出
+    使用 pwm.setDuty() 动态调整占空比
+    使用 pwm.setFreq() 动态调整信号频率
+    使用 pwm.stop() 停止 PWM 输出
+    新风格 PWM 接口支持在运行中动态调整占空比和信号频率
+3. 综合任务调度:顺序运行上述两种风格示例,并在关键节点进行日志输出
+
+注意事项:
+1. 本 demo 演示所使用的是 Air8101 模组的 PWM4 通道(GPIO24,PIN33);
+2. PWM 功能需要使用 V2xxx 版本固件,固件下载链接:https://docs.openluat.com/air8101/luatos/firmware/;
+
+本文件没有对外接口,直接在 main.lua 中 require "pwm_app" 就可以加载运行;
+]]
+
+--[[
+旧风格 PWM 演示函数
+使用 pwm.open() 一次性完成配置和启动
+适合固定频率/占空比、无需中途调整的场景
+]]
+local function task1_old_pwm()
+    log.info("PWM", "旧风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8101 模组的 PWM4 通道(GPIO24,PIN33);
+    local pwm_channel = 4
+
+    -- 第一次输出:1 kHz,45% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 1000, 45, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 1 s 后关闭
+    sys.wait(1000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第二次输出:500 Hz,60% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 500, 60, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 2 s 后关闭
+    sys.wait(2000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    -- 增加 1 秒的间隔时间
+    sys.wait(1000)
+
+    -- 第三次输出:300 Hz,80% 占空比,分频精度 100
+    local pwm_success = pwm.open(pwm_channel, 300, 80, 0, 100)
+    if pwm_success then
+        log.info("PWM", "PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%")
+    else
+        log.info("PWM", "PWM4 通道开启失败")
+    end
+
+    -- 持续 3 s 后关闭
+    sys.wait(3000)
+    pwm.close(pwm_channel)
+    log.info("PWM", "PWM4 通道已关闭")
+
+    log.info("PWM", "旧风格 PWM 示例结束")
+end
+
+
+--[[
+新风格 PWM 演示函数
+使用 pwm.setup() 分步完成配置与启动,支持运行中动态修改频率和占空比
+适合需要实时调节输出参数的场景
+]]
+local function task2_new_pwm()
+    log.info("PWM", "新风格 PWM 示例开始")
+
+    -- 选择 PWM 通道 4
+    -- 注意:本 demo 演示所使用的是 Air8101 模组的 PWM4 通道(GPIO24,PIN33);
+    local pwm_channel = 4
+
+    -- 配置 PWM 参数:频率 1000 Hz、占空比 50%、分频精度 100
+    local setup_success = pwm.setup(pwm_channel, 1000, 50, 0, 100)
+    if setup_success then
+        log.info("PWM", "PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%")
+    else
+        log.info("PWM", "PWM4 配置失败")
+    end
+
+    -- 启动 PWM 输出
+    local pwm_success = pwm.start(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 启动成功")
+    else
+        log.info("PWM", "PWM4 启动失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整占空比至 25%
+    local setduty_success = pwm.setDuty(pwm_channel, 25)
+    if setduty_success then
+        log.info("PWM", "PWM4 占空比更新为 25%")
+    else
+        log.info("PWM", "PWM4 占空比设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 动态调整信号频率为 2000 Hz
+    local setfreq_success = pwm.setFreq(pwm_channel, 2000)
+    if setfreq_success then
+        log.info("PWM", "PWM4 频率更新为 2000 Hz")
+    else
+        log.error("PWM", "PWM4 频率设置失败")
+    end
+
+    -- 持续输出 2 秒
+    sys.wait(2000)
+
+    -- 停止 PWM 输出
+    local pwm_success = pwm.stop(pwm_channel)
+    if pwm_success then
+        log.info("PWM", "PWM4 停止成功")
+    else
+        log.info("PWM", "PWM4 停止失败")
+    end
+
+    log.info("PWM", "新风格 PWM 示例结束")
+end
+
+
+--[[
+主演示任务:
+顺序调用旧风格与新风格 PWM 示例函数
+并在两者之间插入 3 秒间隔方便区分新旧风格示例输出情况
+]]
+local function pwm_demo_task()
+    log.info("PWM", "PWM 综合演示任务开始")
+
+    -- 运行旧风格 PWM 示例
+    task1_old_pwm()
+
+    -- 间隔 3 秒
+    sys.wait(3000)
+
+    -- 运行新风格 PWM 示例
+    task2_new_pwm()
+
+    log.info("PWM", "PWM 综合演示任务结束")
+end
+
+-- 创建并启动一个 task
+-- 用于运行 pwm_demo_task 函数
+sys.taskInit(pwm_demo_task)

+ 84 - 0
module/Air8101/demo/pwm/readme.md

@@ -0,0 +1,84 @@
+## 演示模块概述
+
+1、main.lua:主程序入口;
+
+2、pwm_app.lua:PWM 输出功能模块;
+
+
+
+注意事项:
+
+1、本 demo 演示所使用的是 Air8101 模组的 PWM4 通道(GPIO24,PIN33);
+
+2、PWM 功能需要使用 V2xxx 版本固件,固件下载链接:https://docs.openluat.com/air8101/luatos/firmware/;
+
+## 演示功能概述
+
+使用 Air8101 核心板搭配 PWM 库演示 PWM 输出功能;
+
+PWM 库目前有两套 API 风格:
+
+1、旧风格 PWM 演示:
+
+- 使用 pwm.open() 函数一次性完成 PWM 通道的配置与启动
+- 使用 pwm.close() 函数关闭 PWM 通道
+- 旧风格 PWM 接口不支持动态调整参数
+
+2、新风格 PWM 演示:
+
+- 使用 pwm.setup() 函数进行 PWM 参数配置
+- 使用 pwm.start() 函数开启 PWM 通道进行 PWM 输出
+- 使用 pwm.setDuty() 函数动态调整占空比,支持在开启 PWM 通道后调用
+- 使用 pwm.setFreq() 函数动态调整信号频率,支持在开启 PWM 通道后调用
+- 新风格 PWM 接口支持实时动态调整占空比和信号频率
+
+## 演示硬件环境
+
+1、Air8101 核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、杜邦线若干
+
+4、逻辑分析仪或者示波器,用于观察 PWM 输出的波形
+
+5、代码中选用的 PWM 通道是 Air8101 模组的 PWM4 通道(GPIO24,PIN33)
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air8101 V2xxx 版本](https://docs.openluat.com/air8101/luatos/firmware/)
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools 工具烧录内核固件和 demo 脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、正常运行情况时的日志如下:
+
+```
+[000000000.427] I/user.main PWM 001.000.000
+[000000000.434] I/user.PWM PWM 综合演示任务开始
+[000000000.434] I/user.PWM 旧风格 PWM 示例开始
+[000000000.435] I/user.PWM PWM4 通道开启成功: 信号频率 1000 Hz, 分频精度 100, 占空比 45%
+[000000001.435] I/user.PWM PWM4 通道已关闭
+[000000002.435] I/user.PWM PWM4 通道开启成功: 信号频率 500 Hz, 分频精度 100, 占空比 60%
+[000000004.436] I/user.PWM PWM4 通道已关闭
+[000000005.436] I/user.PWM PWM4 通道开启成功: 信号频率 300 Hz, 分频精度 100, 占空比 80%
+[000000008.437] I/user.PWM PWM4 通道已关闭
+[000000008.437] I/user.PWM 旧风格 PWM 示例结束
+[000000011.437] I/user.PWM 新风格 PWM 示例开始
+[000000011.438] I/user.PWM PWM4 配置成功: 信号频率 1000 Hz, 分频精度 100, 占空比 50%
+[000000011.438] I/user.PWM PWM4 启动成功
+[000000013.438] I/user.PWM PWM4 占空比更新为 25%
+[000000015.439] I/user.PWM PWM4 频率更新为 2000 Hz
+[000000017.439] I/user.PWM PWM4 停止成功
+[000000017.440] I/user.PWM 新风格 PWM 示例结束
+[000000017.440] I/user.PWM PWM 综合演示任务结束
+```
+
+5、使用逻辑分析仪或者示波器观察 PWM 输出波形是否与配置的参数一致