init: Air780EPM 官方 LuatOS 项目代码基线

- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码
- 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等)
- 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
wangfq
2026-08-31 08:53:49 +08:00
commit 173dd6874f
813 changed files with 125484 additions and 0 deletions
@@ -0,0 +1,71 @@
--[[
@module main
@summary TM1650 数码管驱动芯片测试 Demo 入口
@version 1.0
@date 2026.07.13
@author 江访
]]
--[[
=== 演示内容 ===
本 demo 演示 exs_tm1650 扩展库的完整功能,顺序为:
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
1、数码管字符串显示([1/6]
2、按键检测轮询([2/6]
3、按键回调演示([3/6]
4、亮度调节([4/6]
5、7段/8段模式切换([5/6]
6、综合演示-日期/温度([6/6])
]]
--[[
VERSION:项目版本号,ascii string类型
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
]]
-- main.lua - 程序入口文件
PROJECT = "TM1650_Demo" -- 项目命名
VERSION = "001.999.000" -- 项目版本号
-- 在日志中打印项目名和项目版本号
log.info("main", PROJECT, VERSION)
-- 设置日志输出风格为样式2(建议调试时开启)
-- log.style(2)
-- 如果内核固件支持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)
-- 加载 tm1650_demo.lua 演示模块
require "tm1650_demo"
-- 用户代码已结束
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
@@ -0,0 +1,256 @@
# TM1650 数码管驱动芯片演示
## 一、功能模块介绍
### 1.1 核心主程序模块
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
2. **tm1650_demo.lua** - TM1650 功能演示模块,包含数码管显示、按键检测、亮度调节、模式切换、综合展示等所有功能的演示用例
### 1.2 扩展库模块
1. **exs_tm1650** - TM1650 扩展库,提供数码管段码显示、按键检测、亮度调节、模式切换等 API
## 二、演示流程介绍
本 demo 按顺序演示 exs_tm1650 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
### 2.1 功能演示项说明
1. **[1/6] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示
2. **[2/6] 按键轮询** - 通过 `get_key()` API 轮询检测按键,10 秒超时
3. **[3/6] 亮度调节** - 展示 0~7 级亮度调节效果
4. **[4/6] 按键回调** - 通过 `set_key_callback()` API 设置按键回调函数,15 秒演示窗口
5. **[5/6] 模式切换** - 8 段与 7 段模式切换演示
6. **[6/6] 综合演示** - 倒计时、HELLO 闪烁、全 8 显示、亮度渐变、日期展示、温度展示
## 三、显示效果
![](https://docs.openluat.com/cdn/image/Air780EHM_tm1650.png)
## 四、演示硬件环境
### 3.1 硬件清单
- Air780EPM 核心板 × 1
- TM1650 数码管模块(4 位数码管 + 28 个按键) × 1
demo所演示的TM1650数码管[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=894744356431&mi_id=0000-4_DHCxKAB3Xj0nlwc0YnvYkgo5-xS43MtZ8NtPojx4&ns=1&priceTId=213e00d417839211691737686e1068&skuId=5910411206496&spm=a21n57.1.hoverItem.3&utparam=%7B%22aplus_abtest%22%3A%22e04de8195726cbf718476351001570dd%22%7D&xxc=taobaoSearch)
- 母对母杜邦线 × 4
- TYPE-C 数据线 × 1
### 3.2 接线配置
#### 3.2.1 TM1650 模块接线
<table>
<tr>
<td>Air780EPM 核心板<br/></td><td>TM1650 模块<br/></td></tr>
<tr>
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
<tr>
<td>31/GPIO30<br/></td><td>DIO<br/></td></tr>
<tr>
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
<tr>
<td>GND<br/></td><td>GND<br/></td></tr>
</table>
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
## 五、演示软件环境
### 5.1 开发工具
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/) - 固件烧录和代码调试
### 5.2 内核固件
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/)demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
### 5.3 脚本文件
1. **main.lua** - 主程序入口
2. **tm1650_demo.lua** - TM1650 功能演示模块
3. **exs_tm1650** - TM1650 扩展库
## 六、演示核心步骤
### 6.1 硬件准备
1. 按照接线表将 TM1650 模块连接到核心板
2. 确保电源连接正确,通过 TYPE-C USB 口供电
3. 检查所有接线无误,避免短路
### 6.2 软件配置
`main.lua` 中加载对应的演示模块:
```lua
-- 加载 tm1650_demo.lua 演示模块
require "tm1650_demo"
```
### 6.3 软件烧录
1. 使用 Luatools 选择最新内核固件
2. 下载本项目所有脚本文件
3. 将固件和脚本一起烧录到设备
4. 烧录成功后设备自动重启后开始运行
### 6.4 功能测试
#### 6.4.1 字符串显示演示
1. 设备启动后显示 "HELLO",随后自动进入 [1/6] 字符串显示
2. 观察数码管依次显示:`1234``88.8``AbCd` → 从第 3 位显示 `1234`
3. 检查字符显示是否正确,带小数点功能是否正常
#### 6.4.2 按键检测演示
1. 自动进入 [2/6] 按键轮询演示,数码管显示 "KEY-"
2. 在 10 秒内按下 TM1650 模块上的任意按键
3. 观察数码管显示按键编码(如 "K01"、"K02" 等)
4. 若 10 秒内无按键按下,自动跳过
#### 6.4.3 亮度调节演示
1. 自动进入 [3/6] 亮度调节演示,数码管显示 "8888"
2. 观察数码管亮度从 0 级到 7 级逐级变化
3. 最终恢复到 4 级亮度
#### 6.4.4 按键回调演示
1. 自动进入 [4/6] 按键回调演示,数码管显示 "Cb-Key"
2. 在 15 秒内按下任意按键,观察数码管显示对应按键编码
3. 观察日志输出,确认回调函数 `on_key` 被正常触发
4. 15 秒后自动结束回调演示
#### 6.4.5 模式切换演示
1. 自动进入 [5/6] 模式切换演示
2. 观察数码管从 8 段模式切换到 7 段模式
3. 再切回 8 段模式,观察显示效果变化
4. 确认小数点(DP)在 7 段模式下不显示
#### 6.4.6 综合演示
1. 自动进入 [6/6] 综合演示
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
3. 观察 "HELO" 闪烁效果,重复 4 次
4. 观察全 8 显示 + 亮度渐变
5. 日期展示:显示格式 "YY-MM-DD"(如 "26-07-13"),停留 3 秒
6. 温度展示:
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
- 华氏度:77°F → 90°F 逐度变化
7. 演示结束后显示 "End" 并停留 3 秒
### 6.5 预期效果
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置
- **按键检测**:轮询模式和回调模式均能正确检测按键,编码显示正常
- **亮度调节**:0~7 级亮度逐级变化,效果明显
- **模式切换**:8 段和 7 段模式切换正常,小数点显示状态正确
- **日期/温度**:格式显示正确,°C 和 °F 符号正常显示
- **日志如下:**
```lua
[2026-07-21 10:42:14.862][000000000.178] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
[2026-07-21 10:42:14.863][000000000.178] I/main ROM Build: Jul 7 2026 20:39:17
[2026-07-21 10:42:14.865][000000000.180] W/pins /luadb/pins_air780epm.json not exist!!
[2026-07-21 10:42:14.867][000000000.182] D/main loadlibs luavm 1048568 14784 14784
[2026-07-21 10:42:14.870][000000000.182] D/main loadlibs sys 2366664 82756 89356
[2026-07-21 10:42:14.872][000000000.182] D/main loadlibs psram 2366664 82756 89356
[2026-07-21 10:42:14.874][000000000.200] I/user.main TM1650_Demo 001.000.001
[2026-07-21 10:42:14.876][000000000.213] D/user.exs_tm1650 version -> 202607161200
[2026-07-21 10:42:14.878][000000000.224] I/user.exs_tm1650 , clk=31 dio=30 =5
[2026-07-21 10:42:14.880][000000000.224] I/user.tm1650_demo TM1650 : 202607161200
[2026-07-21 10:42:15.073][000000001.230] I/user.tm1650_demo ===== [1/6] =====
[2026-07-21 10:42:15.075][000000001.231] I/user.tm1650_demo 1234
[2026-07-21 10:42:15.958][000000002.611] I/mobile sim0 sms ready
[2026-07-21 10:42:15.960][000000002.611] D/mobile cid1, state0
[2026-07-21 10:42:15.973][000000002.612] D/mobile bearer act 0, result 0
[2026-07-21 10:42:15.977][000000002.613] D/mobile NETIF_LINK_ON -> IP_READY
[2026-07-21 10:42:15.982][000000002.654] D/mobile TIME_SYNC 0 tm 1784601739
[2026-07-21 10:42:16.024][000000002.744] I/user.tm1650_demo 88.8
[2026-07-21 10:42:17.529][000000004.256] I/user.tm1650_demo AbCd
[2026-07-21 10:42:19.038][000000005.768] I/user.tm1650_demo 3 12
[2026-07-21 10:42:20.562][000000007.280] I/user.tm1650_demo HELO
[2026-07-21 10:42:22.567][000000009.297] I/user.tm1650_demo ===== [2/6] =====
[2026-07-21 10:42:22.571][000000009.298] I/user.tm1650_demo 10 TM1650 ...
[2026-07-21 10:42:24.405][000000011.130] I/user.tm1650_demo , : 1
[2026-07-21 10:42:24.515][000000011.238] I/user.tm1650_demo , : 1
[2026-07-21 10:42:25.431][000000012.155] I/user.tm1650_demo , : 2
[2026-07-21 10:42:25.540][000000012.262] I/user.tm1650_demo , : 2
[2026-07-21 10:42:26.053][000000012.774] I/user.tm1650_demo , : 3
[2026-07-21 10:42:26.161][000000012.881] I/user.tm1650_demo , : 3
[2026-07-21 10:42:26.674][000000013.394] I/user.tm1650_demo , : 4
[2026-07-21 10:42:27.389][000000014.107] I/user.tm1650_demo , : 5
[2026-07-21 10:42:27.903][000000014.620] I/user.tm1650_demo , : 6
[2026-07-21 10:42:28.308][000000015.030] I/user.tm1650_demo , : 7
[2026-07-21 10:42:28.711][000000015.440] I/user.tm1650_demo , : 8
[2026-07-21 10:42:29.333][000000016.054] I/user.tm1650_demo , : 9
[2026-07-21 10:42:29.738][000000016.465] I/user.tm1650_demo , : 10
[2026-07-21 10:42:30.250][000000016.977] I/user.tm1650_demo , : 11
[2026-07-21 10:42:30.670][000000017.387] I/user.tm1650_demo , : 12
[2026-07-21 10:42:31.278][000000018.000] I/user.tm1650_demo , : 13
[2026-07-21 10:42:31.682][000000018.413] I/user.tm1650_demo , : 14
[2026-07-21 10:42:32.103][000000018.823] I/user.tm1650_demo , : 15
[2026-07-21 10:42:32.507][000000019.233] I/user.tm1650_demo , : 16
[2026-07-21 10:42:32.817][000000019.541] I/user.tm1650_demo
[2026-07-21 10:42:32.822][000000019.541] I/user.tm1650_demo ===== [3/6] =====
[2026-07-21 10:42:32.827][000000019.542] I/user.tm1650_demo 15
[2026-07-21 10:42:33.035][000000019.755] I/user.tm1650_demo , : 17
[2026-07-21 10:42:33.581][000000020.306] I/user.tm1650_demo , : 18
[2026-07-21 10:42:34.125][000000020.855] I/user.tm1650_demo , : 19
[2026-07-21 10:42:34.529][000000021.255] I/user.tm1650_demo , : 20
[2026-07-21 10:42:35.024][000000021.755] I/user.tm1650_demo , : 21
[2026-07-21 10:42:35.428][000000022.155] I/user.tm1650_demo , : 22
[2026-07-21 10:42:35.833][000000022.556] I/user.tm1650_demo , : 23
[2026-07-21 10:42:36.175][000000022.905] I/user.tm1650_demo , : 24
[2026-07-21 10:42:36.577][000000023.305] I/user.tm1650_demo , : 25
[2026-07-21 10:42:36.981][000000023.705] I/user.tm1650_demo , : 26
[2026-07-21 10:42:37.323][000000024.055] I/user.tm1650_demo , : 27
[2026-07-21 10:42:37.730][000000024.455] I/user.tm1650_demo , : 28
[2026-07-21 10:42:47.837][000000034.556] I/user.tm1650_demo
[2026-07-21 10:42:47.841][000000034.556] I/user.tm1650_demo ===== [4/6] =====
[2026-07-21 10:42:48.350][000000035.068] I/user.tm1650_demo : 0
[2026-07-21 10:42:49.141][000000035.870] I/user.tm1650_demo : 1
[2026-07-21 10:42:49.950][000000036.672] I/user.tm1650_demo : 2
[2026-07-21 10:42:50.742][000000037.474] I/user.tm1650_demo : 3
[2026-07-21 10:42:51.550][000000038.276] I/user.tm1650_demo : 4
[2026-07-21 10:42:52.360][000000039.078] I/user.tm1650_demo : 5
[2026-07-21 10:42:53.154][000000039.880] I/user.tm1650_demo : 6
[2026-07-21 10:42:53.963][000000040.682] I/user.tm1650_demo : 7
[2026-07-21 10:42:55.268][000000041.991] I/user.tm1650_demo ===== [5/6] 7/8 =====
[2026-07-21 10:43:01.812][000000048.536] I/user.tm1650_demo ===== [6/6] =====
[2026-07-21 10:43:10.772][000000057.497] I/user.tm1650_demo : 0713
[2026-07-21 10:43:26.692][000000073.417] I/user.tm1650_demo ---- 综合演示结束 ----
[2026-07-21 10:43:29.693][000000076.423] I/user.tm1650_demo ===== [] =====
```
### 6.6 故障排除
1. **数码管无显示**
- 检查 TM1650 接线是否正确(CLK、DIO、VCC、GND
- 确认 GPIO 引脚配置与接线一致
- 检查电源电压是否稳定(3.3V
- 确认 exs_tm1650 扩展库已正常加载
2. **按键无响应**
- 检查按键接线和 TM1650 模块是否正常
- 确认扩展库初始化成功
- 查看日志确认 `setup()` 返回值为 true
3. **亮度无法调节**
- 确认调用 `set_brightness()` 时参数为 0~7
4. **显示内容错乱**
- 检查杜邦线是否过长导致通信不稳定
### 6.7 扩展功能建议
exs_tm1650 更多接口的使用可以查看 [exs_tm1650 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_tm1650/)
@@ -0,0 +1,243 @@
--[[
@module tm1650_demo
@summary TM1650 驱动芯片演示模块,包含所有功能的演示用例
@version 1.0
@date 2026.07.13
@author 江访
@usage
本文件包含 TM1650 的逐项功能演示和综合展示。
通过 exs_tm1650 扩展库的 API 逐一演示数码管显示、按键检测、亮度调节、
7段/8段模式切换等功能。
]]
-- 加载 exs_tm1650 扩展库
local exs_tm1650 = require "exs_tm1650"
-- 演示字符串显示
local function demo_string()
log.info("tm1650_demo", "===== [1/6] 字符串显示 =====")
log.info("tm1650_demo", "显示 1234")
exs_tm1650.clear()
exs_tm1650.set_display("1234")
sys.wait(1500)
log.info("tm1650_demo", "显示 88.8")
exs_tm1650.clear()
exs_tm1650.set_display("88.8")
sys.wait(1500)
log.info("tm1650_demo", "显示 AbCd")
exs_tm1650.clear()
exs_tm1650.set_display("AbCd")
sys.wait(1500)
log.info("tm1650_demo", "从第 3 位开始显示 12")
exs_tm1650.clear()
exs_tm1650.set_display("12", 3)
sys.wait(1500)
log.info("tm1650_demo", "显示 HELO")
exs_tm1650.clear()
exs_tm1650.set_display("HELO")
sys.wait(1500)
exs_tm1650.clear()
sys.wait(500)
end
-- 演示按键轮询
local function demo_keys()
log.info("tm1650_demo", "===== [2/6] 按键轮询 =====")
log.info("tm1650_demo", "请在 10 秒内按下连接到 TM1650 的按键...")
exs_tm1650.clear()
exs_tm1650.set_display("KEYS")
local timeout = 10000
local step = 100
local elapsed = 0
while elapsed < timeout do
local key = exs_tm1650.get_key()
if key then
log.info("tm1650_demo", "检测到按键, 编码:", key)
local key_str = string.format("%02d", key)
exs_tm1650.set_display(key_str)
sys.wait(100)
elapsed = elapsed + 100
else
sys.wait(step)
elapsed = elapsed + step
end
end
log.info("tm1650_demo", "按键检测超时,跳过")
end
-- 按键回调函数
local function on_key(key_code)
log.info("tm1650_demo", "按键回调触发, 编码:", key_code)
local display = string.format("%02d", key_code)
exs_tm1650.set_display(display)
end
-- 演示按键回调
local function demo_key_callback()
log.info("tm1650_demo", "===== [3/6] 按键回调 =====")
log.info("tm1650_demo", "接下来 15 秒内按按键查看回调效果")
exs_tm1650.clear()
exs_tm1650.set_display("CALL")
exs_tm1650.set_key_callback(on_key)
sys.wait(15000)
exs_tm1650.set_key_callback(nil)
log.info("tm1650_demo", "按键回调演示结束")
end
-- 演示亮度调节
local function demo_brightness()
log.info("tm1650_demo", "===== [4/6] 亮度调节 =====")
exs_tm1650.clear()
exs_tm1650.set_display("8888")
sys.wait(500)
for bright = 0, 7 do
log.info("tm1650_demo", "设置亮度:", bright)
exs_tm1650.set_brightness(bright)
sys.wait(800)
end
-- 恢复默认亮度
exs_tm1650.set_brightness(4)
exs_tm1650.clear()
sys.wait(500)
end
-- 演示 7段/8段 模式切换
local function demo_segment_mode()
log.info("tm1650_demo", "===== [5/6] 7段/8段模式切换 =====")
-- 8 段模式(含 DP 段),显示数字
exs_tm1650.clear()
exs_tm1650.set_mode(0)
exs_tm1650.set_display("8SEG")
sys.wait(2000)
-- 显示带小数点的内容(8 段模式特性)
exs_tm1650.clear()
exs_tm1650.set_display("88.8")
sys.wait(2000)
-- 切换到 7 段模式
exs_tm1650.clear()
exs_tm1650.set_mode(1)
exs_tm1650.set_display("7SEG")
sys.wait(2000)
exs_tm1650.clear()
sys.wait(500)
-- 切回 8 段模式
exs_tm1650.set_mode(0)
end
-- 综合演示
local function demo_final()
log.info("tm1650_demo", "===== [6/6] 综合演示 =====")
-- 倒计时
for i = 5, 0, -1 do
exs_tm1650.clear()
exs_tm1650.set_display(string.format("%04d", i))
sys.wait(500)
end
-- HELO 闪烁
for i = 0, 3 do
exs_tm1650.clear()
exs_tm1650.set_display("HELO")
sys.wait(500)
exs_tm1650.clear()
sys.wait(300)
end
-- 全 8 显示 + 亮度渐变
exs_tm1650.clear()
exs_tm1650.set_display("8888")
for i = 0, 7 do
exs_tm1650.set_brightness(i)
sys.wait(200)
end
sys.wait(1000)
exs_tm1650.set_brightness(4)
exs_tm1650.clear()
-- 日期展示(4 位数码管,显示月日)
log.info("tm1650_demo", "日期展示: 0713")
exs_tm1650.set_display("0713")
sys.wait(3000)
-- 温度展示(摄氏度)
exs_tm1650.clear()
sys.wait(200)
local DEGREE = "\xB0"
for temp = 25, 32 do
local cel = string.format("%02d", temp) .. DEGREE .. "C"
exs_tm1650.set_display(cel)
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
if bright < 0 then bright = 0 end
if bright > 7 then bright = 7 end
exs_tm1650.set_brightness(bright)
sys.wait(800)
end
-- 温度展示(华氏度)
for temp = 77, 90, 2 do
local fah = string.format("%02d", temp) .. DEGREE .. "F"
exs_tm1650.set_display(fah)
sys.wait(600)
end
exs_tm1650.set_brightness(5)
sys.wait(2000)
exs_tm1650.clear()
log.info("tm1650_demo", "---- 综合演示结束 ----")
end
-- 演示主函数(运行在协程中)
local function tm1650_demo_task_func()
-- 初始化
local result = exs_tm1650.setup({
clk = 31,
dio = 30,
bright = 5,
})
if not result then
log.error("tm1650_demo", "TM1650 初始化失败,请检查接线")
return
end
log.info("tm1650_demo", "TM1650 初始化成功,版本:", exs_tm1650.version())
-- HELLO 开始 → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
exs_tm1650.set_display("HELO")
sys.wait(1000)
demo_string()
demo_keys()
demo_key_callback()
demo_brightness()
demo_segment_mode()
demo_final()
exs_tm1650.set_display("End-")
sys.wait(3000)
log.info("tm1650_demo", "===== [演示完毕] =====")
end
sys.taskInit(tm1650_demo_task_func)