跳到主要内容

GPIO基础

概述

GPIO(通用输入输出)是嵌入式开发最基础的外设。本章以 01 - LED闪烁 例程为例,展示如何使用 LuatOS 控制板载 LED,同时学习 LuatOS 的核心编程模式:协程任务面向对象模块封装

技术栈
  • 运行环境:LuatOS(合宙 Air8000W 模组)
  • 核心 APIgpio.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()