GPIO基础
概述
GPIO(通用输入输出)是嵌入式开发最基础的外设。本章以 01 - LED闪烁 例程为例,展示如何使用 LuatOS 控制板载 LED,同时学习 LuatOS 的核心编程模式:协程任务 和 面向对象模块封装。
技术栈
- 运行环境:LuatOS(合宙 Air8000W 模组)
- 核心 API:
gpio.setup()/gpio.set()/sys.taskInit()/sys.wait() - LED 引脚:GPIO153(黄色/通信灯)、GPIO147(绿色/用户灯)
程序流程
main.lua
│
├─ 1. require("Led") → 加载 LED 驱动模块
│
├─ 2. wdt.init(9000) → 初始化看门狗(9秒超时,3秒喂狗)
│
├─ 3. Led:new() ×2 → 创建通信灯 + 用户灯实例
├─ 4. Led:init(pin,0) → 初始化 GPIO 为输出
│
├─ 5. sys.taskInit() → 启动协程1:通信灯慢闪(亮500ms / 灭1500ms)
├─ 6. sys.taskInit() → 启动协程2:用户灯快闪(亮200ms / 灭200ms)
│
└─ 7. sys.run() → 启动系统调度,协程开始并发执行
项目结构
01 - LED闪烁/
├── main.lua # 主程序入口
└── Led.lua # LED 驱动模块
核心代码详解
1. LuatOS 协程任务
LuatOS 使用协程实现并发,每个 sys.taskInit() 启动一个独立任务,通过 sys.wait() 让出 CPU 实现非阻塞延时:
-- 协程任务:LED 慢闪循环
sys.taskInit(function()
comm_led:set_status(2) -- 设置状态为慢闪
while true do
comm_led:control() -- 执行一次闪烁周期(亮500ms → 灭1500ms)
end
end)
sys.run() -- 启动系统调度器,所有协程开始执行
2. GPIO 控制 API
LuatOS 提供简洁的 GPIO 操作接口:
-- 初始化 GPIO 为输出,初始值为低电平
gpio.setup(pin, 0)
-- 设置 GPIO 高/低电平
gpio.set(pin, 1) -- 高电平(LED 亮)
gpio.set(pin, 0) -- 低电平(LED 灭)
3. LED 模块封装(面向对象)
Led.lua 通过 Lua 的元表机制实现轻量级面向对象,封装了四种 LED 模式:
| 状态值 | 模式 | 时序 | 典型场景 |
|---|---|---|---|
| 0 | 熄灭 | - | 正常待机 |
| 1 | 常亮 | - | 配网中 / 连接中 |
| 2 | 慢闪 | 亮 500ms → 灭 1500ms | 网络正常 |
| 3 | 快闪 | 亮 200ms → 灭 200ms | 网络异常 / 告警 |
-- 创建并初始化 LED
local led = Led:new()
led:init(pin, 0, "名称") -- init(引脚, 初值, 名称)
led:set_status(2) -- 设置为慢闪模式
led:control() -- 执行一次闪烁周期(需在循环中调用)
4. 看门狗
if wdt then
wdt.init(9000) -- 初始化看门狗,超时 9 秒
sys.timerLoopStart(wdt.feed, 3000) -- 每 3 秒喂狗
end
全部代码
Led.lua
Led.lua
-- 红灯(GPIOxx): 电源灯,上电常亮
-- 黄灯(GPIO153): 通信灯,指示网络通信状态
-- 绿灯(GPIO147): 用户灯,用户自定义状态
Led = {}
-- 创建LED实例对象
function Led:new()
-- 对象属性初始化
local obj = {
gpio_pin = nil, -- GPIO引脚编号
led_status = 0, -- LED当前状态(0-3)
led_name = "LED" -- LED名称标识
}
-- 设置元表,实现面向对象继承
setmetatable(obj, self)
self.__index = self
return obj
end
-- 初始化LED引脚
function Led:init(gpio_pin, initial_value, name)
self.gpio_pin = gpio_pin -- 保存GPIO引脚
self.led_status = initial_value or 0 -- 设置初始状态,默认为0(熄灭)
self.led_name = name or "LED" -- 设置LED名称,便于调试和识别
gpio.setup(self.gpio_pin, self.led_status) -- 配置GPIO为输出模式
end
-- 设置LED状态 0: 熄灭 1: 常亮 2: 慢闪 3: 快闪
function Led:set_status(status)
self.led_status = status
end
-- 控制LED执行对应状态动作
function Led:control()
if self.led_status == 0 then
-- 状态0:熄灭LED
gpio.set(self.gpio_pin, 0)
elseif self.led_status == 1 then
-- 状态1:LED常亮
gpio.set(self.gpio_pin, 1)
elseif self.led_status == 2 then
-- 状态2:慢闪模式(亮500ms,熄灭1500ms)
gpio.set(self.gpio_pin, 1) -- LED点亮
sys.wait(500) -- 保持亮500毫秒
gpio.set(self.gpio_pin, 0) -- LED熄灭
sys.wait(1500) -- 保持熄灭1500毫秒
elseif self.led_status == 3 then
-- 状态3:快闪模式(亮200ms,灭200ms)
gpio.set(self.gpio_pin, 1) -- LED点亮
sys.wait(200) -- 保持亮200毫秒
gpio.set(self.gpio_pin, 0) -- LED熄灭
sys.wait(200) -- 保持熄灭200毫秒
end
end
return Led
main.lua
main.lua
PROJECT = "LED"
VERSION = "1.0.0"
Led = require("Led")
if wdt then
wdt.init(9000)
sys.timerLoopStart(wdt.feed, 3000)
end
-- LED分配说明
-- 黄色灯(GPIO153):通信灯 - 用于指示网络通信状态
-- 绿色灯(GPIO147):用户灯 - 用于指示用户自定义状态
local comm_led = Led:new()
local user_led = Led:new()
comm_led:init(153, 0, "通信灯")
user_led:init(147, 0, "用户灯")
-- 通信灯任务(慢闪:亮500ms,熄灭1500ms)
sys.taskInit(function()
log.info("LED", "通信灯开始慢闪模式")
comm_led:set_status(2)
while true do
comm_led:control()
end
end)
-- 用户灯任务(快闪:亮200ms,灭200ms)
sys.taskInit(function()
log.info("LED", "用户灯开始快闪模式")
user_led:set_status(3)
while true do
user_led:control()
end
end)
sys.run()