开机键,PWRKEY

1、模组管脚:PIN7;
2、功能说明;
-
模组工作电压范围3.3V-4.35V,PWRKEY为开机键, 内部上拉至VBAT;
-
如果PWRKEY接地,芯片上电即开机;
a. PWRKEY可以直接接地,也可以串联电阻接地;
b. 串联电阻接地时,最大阻值不应该超过10K,否则有可能无法正常开机;
c. 相对于直接接地,串联电阻的作用是PWRKEY因内部上拉到VBAT而引起的漏电流可以进一步减小;
d. 开机之后,可以通过 gpio.setup(gpio.PWR_KEY, nil, gpio.PULLDOWN) 将PWEKEY设置为中断输入进一步降低待机电流,尤其是在PSM+模式下会有显著的提升,大约会节省15uA左右的待机电流;
- PWRKEY不接地时:
a. 模组关机状态下,检测到PWRKEY下降沿,模组启动上电流程;
b. 当系统在启动状态下检测到PWRKEY下降沿时触发中断,是否进入关机过程或其他动作由软件决定;
c. 模组上电开机时,需确保VBAT上电时的起始电压小于0.5V,否则可能会因低电压造成模组时序混乱而无法正常开机;关于这一点的详细介绍,会在“开机时序”章节进行详细介绍;
3、关于PWRKEY的详细参数介绍,见下表;
| 参数 | 描述 | 规格 | 单位 | ||
|---|---|---|---|---|---|
| Min | Typ. | Max | |||
| PWRKEY | |||||
| 高电平 | High-level input voltage | 1.7 | 3.6 | V | |
| 低电平 | Low-level input voltage | 1.1 | V | ||
| 低功耗模式 pm.WORK_MODE,1 | LowPower Voltage | 1.7 | 1.9 | 2.1 | V |
| PSM+模式 pm.WORK_MODE,3 | PSM+ Voltage | 1.7 | 1.9 | 2.1 | V |
| 上拉电阻 | Pull-up Resistance | 130k | 180k | 230k | Ω |
4、当PWRKEY接实体按键进行拉低执行开机、关机或中断输入动作检测时,实体按键键帽与底座接触时极易产生静电,因此,需要增加TVS进行保护;
推荐TVS型号如下;
样品购买链接:SIM和GPIO用,DFN1006-2封装,AR3321P1LV,应能微-淘宝网
开机前,PWRKEY是开机键;开机后,PWRKEY就是一个中断输入,执行什么动作取决于软件的设置;
关于PWRKEY作为中断输入的LuatOS库函数介绍,详见:21 gpio - 合宙模组资料中心;
| 常量 | 类型 | 常量取值 | 解释 | 参数示例 | 适用产品型号 |
|---|---|---|---|---|---|
| gpio.LOW | number | 0 | 低电平 | gpio.set(17, gpio.LOW) | 全支持 |
| gpio.HIGH | number | 1 | 高电平 | gpio.set(17, gpio.HIGH) | 全支持 |
| gpio.PULLUP | number | 1 | 上拉 | gpio.setup(17, nil, gpio.PULLUP) | 全支持 |
| gpio.PULLDOWN | number | 2 | 下拉 | gpio.setup(17, nil, gpio.PULLDOWN) | 全支持 |
| gpio.RISING | number | 0 | 上升沿触发 | gpio.setup(27, irqFunc, gpio.PULLUP, gpio.RISING) | 全支持 |
| gpio.FALLING | number | 1 | 下降沿触发 | gpio.setup(27, irqFunc, gpio.PULLUP, gpio.FALLING) | 全支持 |
| gpio.BOTH | number | 2 | 双向触发 | gpio.setup(27, irqFunc, gpio.PULLUP, gpio.BOTH) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP0 | number | 39 | 休眠唤醒脚0,不支持输出 | gpio.setup(gpio.WAKEUP0, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP1 | number | 40 | VBUS,USB唤醒脚,不支持输出 | gpio.setup(gpio.WAKEUP1, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP2 | number | 41 | USIM热插拔脚,不支持输出 | gpio.setup(gpio.WAKEUP2, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP3 | number | 42 | 休眠唤醒脚3,与GPIO20是同一个引脚 | gpio.setup(gpio.WAKEUP3, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP4 | number | 43 | 休眠唤醒脚4,与GPIO21是同一个引脚 | gpio.setup(gpio.WAKEUP4, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP5 | number | 44 | 休眠唤醒脚5,与GPIO22是同一个引脚 | gpio.setup(gpio.WAKEUP5, nil) | 仅Air780EXXX系列/Air8000系列支持 |
| gpio.WAKEUP6 | number | 45 | 休眠唤醒脚6,不支持输出 | gpio.setup(gpio.WAKEUP6, nil) | 仅Air8000系列支持 |
| gpio.AUDIOPA_EN | number | 22 | 音频PA使能脚,仅Air780EHV特有的引脚 | gpio.setup(gpio.AUDIOPA_EN, 0) | 仅Air780EHV支持 |
| gpio.PWR_KEY | number | 46 | 开机前:开机键,下降沿时触发; 开机后:双向触发中断,不支持输出; | gpio.setup(gpio.PWR_KEY, nil) | 仅Air780EXX系列/Air8000系列支持 |
5、POWERKEY 管脚使用 gpio.setup() 接口配置为输入模式时,在休眠状态下,如果内核固件版本是 V2026 及之前的版本,不仅有输入功能,还有唤醒功能;如果是 V2028 及之后的版本,只有输入功能,没有唤醒功能;LuatOS 代码配置如下:
-- 配置POWERKEY 脚为输入模式;
gpio.setup(gpio.PWR_KEY, nil)
6、按键关机 / 按键复位 demo;
本节以 Air780EPM / Air780EHM 为例(PWRKEY 为 PIN7),Air780EGH、Air780EHV、Air780EHN/EHU、Air780EGP 等 EC7xx 系列模组的用法完全一致。
开机之前,PWRKEY 是硬件开机键,拉低之后模组就会进入上电流程;开机之后,PWRKEY 就只是一个普通的中断输入脚,硬件不再接管它,此时按键按下既不会自动关机、也不会自动重启,具体做什么动作完全由软件决定。所以“按键关机”“按键复位”必须自己写代码实现,用到的接口只有下面三个:
a. gpio.setup(gpio.PWR_KEY, 回调函数, gpio.PULLUP, gpio.BOTH):把 PWRKEY 配置成双向中断输入,按下(下降沿)和松开(上升沿)都会进回调;回调的第一个参数是电平(0=按下,1=松开),第二个参数是管脚号;
b. pm.shutdown():软件关机。关机后模组不再响应任何软件操作,只能靠 PWRKEY 重新拉低开机,详见 pm 库说明:pm.shutdown();
c. rtos.reboot()(与 pm.reboot() 完全等价):软件重启,只重启软件,VBAT 不会掉电。
(1)demo 功能定义
| 操作 | 动作 | 说明 |
|---|---|---|
| 长按 3 秒后松开 | 关机 | 松开之后才关机,避免关机瞬间按键仍被按住 |
| 一直按住满 6 秒 | 重启 | 现场排障用,设备卡死时不用拆电池、不用断电 |
| 3 秒以内松开 | 不动作 | 防误触 |
(2)完整代码,可直接复制烧录
-- PWRKEY 按键关机 / 按键复位 demo
-- 长按 3 秒后松开 -> 关机;一直按住满 6 秒 -> 重启;3 秒以内松开 -> 不动作
PROJECT = "pwrkey_demo"
VERSION = "1.0.0"
local sys = require("sys")
local POWEROFF_MS = 3000 -- 按满 3 秒算该关机了,但到点不立即关,等松开
local REBOOT_MS = 6000 -- 一直按到 6 秒,强制重启
local t_poweroff, t_reboot
local reach_poweroff = false
-- 按键中断回调;level:0=按下,1=松开(第二个参数是管脚号,这里用不到)
local function on_pwrkey(level)
if level == 0 then
-- 按下:起两个定时器,一个只做标记,一个负责 6 秒重启
reach_poweroff = false
t_poweroff = sys.timerStart(function()
reach_poweroff = true
end, POWEROFF_MS)
t_reboot = sys.timerStart(function()
sys.publish("PWRKEY_EVT", "reboot")
end, REBOOT_MS)
else
-- 松开:不管够不够时间,先把两个定时器都停掉
if t_poweroff then
sys.timerStop(t_poweroff)
t_poweroff = nil
end
if t_reboot then
sys.timerStop(t_reboot)
t_reboot = nil
end
-- 按够了 3 秒,松开才真正关机
if reach_poweroff then
reach_poweroff = false
sys.publish("PWRKEY_EVT", "poweroff")
end
end
end
sys.taskInit(function()
-- 双向中断 + 内部上拉:按下、松开都会进回调
gpio.setup(gpio.PWR_KEY, on_pwrkey, gpio.PULLUP, gpio.BOTH)
-- 50ms 延时防抖:抖动期间电平不变才上报,避免一次按键报好几次
gpio.debounce(gpio.PWR_KEY, 50, 1)
log.info("pwrkey", "demo 启动:长按3秒松开关机,长按6秒重启")
end)
-- 关机/重启放到独立任务里执行,方便先保存数据、把日志打出去
sys.taskInit(function()
while true do
local _, evt = sys.waitUntil("PWRKEY_EVT")
if evt == "poweroff" then
log.info("pwrkey", "长按 3 秒,执行关机")
-- TODO: 在这里保存数据、断开 socket、关闭外设
sys.wait(100)
pm.shutdown()
elseif evt == "reboot" then
log.info("pwrkey", "长按 6 秒,执行重启")
sys.wait(100)
rtos.reboot()
end
end
end)
sys.run()
(3)验证现象
a. 按下 1 秒左右松开:串口打印“按下 / 3 秒内松开,不动作”,模组继续运行;
b. 按住 3 秒以上再松开:串口打印“长按 3 秒,执行关机”,随后模组关机,VDD_EXT 掉电(用万用表测 VDD_EXT 就能确认是不是真的关了);
c. 一直按住到 6 秒:串口打印“长按 6 秒,执行重启”,模组重启,脚本从头跑一遍;
d. 关机后松开按键,再按一次(拉低 1 秒以上):模组重新开机。
(4)只保留一个功能
只要长按关机时,把 REBOOT_MS 那个定时器整段删掉即可;只要长按重启时,把 POWEROFF_MS 分支删掉、松开回调里直接 sys.publish("PWRKEY_EVT", "reboot") 即可。
7、注意事项(重要,请逐条确认);
下面每一条都是实际踩过的坑,尤其第 a、b、c、d 条,不满足时轻则误关机,重则关机后再也开不了机。
a. 只适用于 PWRKEY 由按键(或 MOS/三极管)引出的硬件设计。如果 PWRKEY 直接接地、或者串 10K 以内电阻接地(做成上电自动开机),pm.shutdown() 关机之后就不会再有新的下降沿,模组永远无法再开机,只能彻底断电重上电;这类设计严禁使用本文的关机代码。
b. 绝对不要“按下即关机”。机械按键抖动、静电、结构误触都会造成“碰一下就关机”。必须同时做到三点:gpio.debounce() 防抖、用定时器判长按、到点后复查电平(或者采用本文“松开时才关机”的写法)。
c. pm.shutdown() 不会替你收尾。从源码看,它只做“关看门狗 → 进入关机流程”两件事,不会等 socket 关闭、不会等文件落盘、不会帮外设断电。调用之前请自己保存数据、断开网络、关闭外设,并留 100ms 左右把日志打出去。
d. 关机之后只能按键开机,软件无法唤醒。另外,关机那一瞬间如果按键还按着,部分硬件会立刻重新上电,表现为“关不掉 / 关机后又自己开机”——本文 demo 特意做成“松开才关机”就是为了规避这个现象;如果改回“到点立即关机”,务必在产品说明书里提示用户松手。
e. 中断回调里不要做耗时操作。gpio 回调运行在 sys 任务上下文,长时间阻塞会拖慢其它任务;关机、重启这类动作建议用 sys.publish 交给独立任务执行(本文即如此)。
f. 休眠状态下有额外限制。PWRKEY 配置为输入后,V2026 及之前的内核固件在休眠时既有输入功能、也有唤醒功能;V2028 及之后的固件只有输入功能、没有唤醒功能。也就是说,深度休眠(pm.WORK_MODE,1)尤其是 PSM+(pm.WORK_MODE,3)状态下,按键中断可能根本进不了回调,长按关机不会生效。需要在休眠中也能关机时,只能用 pm.dtimerStart() 周期性唤醒,醒来后主动 gpio.get(gpio.PWR_KEY) 判断电平。另外 gpio.debounce() 只影响“上报”,不影响“唤醒”,低功耗下按键一触发就会把模组唤醒。
g. PWRKEY 只能做输入,不能做输出。gpio.PWR_KEY 不支持 gpio.set() 输出电平;也不要在外部给它加上拉电阻,模块内部已经上拉到 VBAT,外部上拉会影响开机稳定性(详见“开机电路介绍”)。
h. 硬件配套别省:PWRKEY 接实体按键时,按键两端建议并 TVS(键帽与底座接触极易产生静电);走线尽量短,必要时靠近模组加 100pF 对地滤波;如果为了减小内部上拉漏电而串联电阻接地,阻值不要超过 10K,否则可能无法正常开机。
i. “按键复位”有三种,不要混为一谈:
- rtos.reboot() / pm.reboot():软件重启,最快,但 VBAT 不掉电,屏、摄像头、外置 Flash 等由 VBAT 直接供电的外设不会被复位,需要自己重新初始化;
- 硬件 RESET 脚(Air780EPM / Air780EHM 为 PIN15):拉低 500ms 以上真正复位芯片,但该脚只接受外部输入,软件无法操作它,且外部禁止拉高,详见“复位键,RESET” 章节;
- 看门狗复位:脚本跑飞、死锁时的兜底,见 wdt 库说明。
RESET 是“重启”,不是“关机”,两者不要混用。
j. 固件要求:pm.shutdown() 需要 2022-12-22 之后编译的固件,更老的固件调用无效(只会打印 powerOff is not supported);量产前请用实际出货固件完整验证一次。
k. 关机不等于断电。pm.shutdown() 只是让模组进入关机态,VBAT 仍然在供电,PWRKEY 内部上拉也仍有微安级漏电。产品要求“长期存放不掉电”时,要靠外部电源开关、船运模式(带充电管理 IC 的型号)或者直接断开电池。