跳转至

开机键,PWRKEY

1、功能说明;

  • 模组工作电压范围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,否则可能会因低电压造成模组时序混乱而无法正常开机;关于这一点的详细介绍,会在“开机时序”章节进行详细介绍;

2、关于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 Ω

3、当PWRKEY接实体按键进行拉低执行开机、关机或中断输入动作检测时,实体按键键帽与底座接触时极易产生静电,因此,需要增加TVS进行保护;

推荐TVS型号如下;

样品购买链接:SIM和GPIO用,DFN1006-2封装,AR3321P1LV,应能微-淘宝网

AR3321P1LV.pdf

XESD100N-3V3 Rev. 0.1.pdf

CSLS03FBZ.pdf

PESDR3321P1.pdf

4、开机前,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;

本节适用于 Air700ECH / Air700ECP,PWRKEY 的操作方式与 Air780E 系列完全一致,代码不用改。

开机之前,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 脚(见“复位键,RESET”章节):拉低 500ms 以上真正复位芯片,但该脚只接受外部输入,软件无法操作它,且外部禁止拉高,详见“复位键,RESET” 章节;
  • 看门狗复位:脚本跑飞、死锁时的兜底,见 wdt 库说明。

RESET 是“重启”,不是“关机”,两者不要混用。

j. 固件要求:pm.shutdown() 需要 2022-12-22 之后编译的固件,更老的固件调用无效(只会打印 powerOff is not supported);量产前请用实际出货固件完整验证一次。

k. 关机不等于断电。pm.shutdown() 只是让模组进入关机态,VBAT 仍然在供电,PWRKEY 内部上拉也仍有微安级漏电。产品要求“长期存放不掉电”时,要靠外部电源开关、船运模式(带充电管理 IC 的型号)或者直接断开电池。

搜索