KEYPAD
一、简介
在电路设计中,通常需要较多的外部输入,如果每个按键都单独去占用一个 IO 接口,就会非常浪费资源,为了减少 I/O 口的占用,通常将按键排列成矩阵形式,即矩阵键盘。
特性
- KEYIN0。扫描键盘输入 0,与 UBOOT 复用,此管脚在模块开机动作完成之前不能进行拉高,电压域为 V_GLOBAL_1V8。
- KEYIN1。扫描键盘输入 1,此管脚在模块开机动作完成之前不能进行拉高,电压域为 V_GLOBAL_1V8。
- KEYIN2、KEYIN3、KEYIN4、KEYIN5。扫描键盘输入管脚,电压域为 V_GLOBAL_1V8。
- KEYOUT0、KEYOUT1、KEYOUT2、KEYOUT3。扫描键盘输出管脚,电压域为 V_GLOBAL_1V8。
- KEYOUT4 。扫描键盘输出管脚 4,与 UART3_RXD 复用,电压域为 V_GLOBAL_1V8。
- KEYOUT5 。扫描键盘输出管脚 5,与 UART3_TXD 复用,电压域为 V_GLOBAL_1V8。
键盘接口的所有管脚不能复用为 GPIO
二、演示功能概述
本教程教你如何使用开发板的矩阵键盘获取输入信息。
三、准备硬件环境
3.1 开发板准备
使用 EVB_Air724 开发板,如下图所示:
淘宝购买链接:Air724UG-NFM 开发板淘宝购买链接 ;
此开发板的详细使用说明参考:Air724UG 产品手册 中的《EVB_Air724UG_AXX 开发板使用说明》,写这篇文章时最新版本的使用说明为:《EVB_Air724UG_A14 开发板使用说明》;开发板使用过程中遇到任何问题,可以直接参考这份使用说明文档。
api:https://ask.openluat.com/wiki/21?wiki_page_id=2288
3.2 数据通信线
USB 数据线一根(micro USB)。
3.3 PC 电脑
WIN7 以及以上版本的 WINDOWS 系统。
3.4 矩阵键盘
4x4 矩阵键盘
3.5 组装硬件环境
USB 数据线插入 USB 口,另一端与电脑相连,拨码开关全部拨到 ON,串口切换开关选择 UART1,USB 供电的 4V 对应开关拨至 ON 档,连接矩阵键盘,把键盘阵列软排线接口插入开发板相对印引脚,keyin2 keyin3 keyin4 keyin5 keyout0 keyout1 keyout2 keyout3,如下图所示。
四、准备软件环境
4.1 下载调试工具
使用说明参考:Luatools 下载和详细使用
4.2 源码及固件
1. 底层 core 下载
下载底层固件,并解压
链接:https://docs.openluat.com/air724ug/luatos/firmware/
如下图所示,红框的是我们要使用到的
2. 本教程使用的 demo 见附件:
https://gitee.com/openLuat/LuatOS-Air724UG/tree/master/script_LuaTask/demo/keypad
4.3 下载固件和脚本到开发板中
打开 Luatools,开发板上电开机,如开机成功 Luatools 会打印如下信息。
点击项目管理测试选项。
进入管理界面,如下图所示。
- 点击选择文件,选择底层固件,我的文件放在 D:\luatOS\Air724 路径中
- 点击增加脚本或资源文件,选择之前下载的程序源码,如下图所示。
- 点击下载底层和脚本,下载完成如下图所示。
五、代码示例介绍
5.1 API 说明
本文用到的接口函数不做详细介绍,可通过点击右侧链接查看具体介绍:powerKey API
5.1.1 创建一个 tKeypad 表,储存所有按键值(16 个键盘元素 +1 个开关机键元素)
--每个元素的索引为行列值拼接而成的字符串,值为按键名的字符串
--例如:按键名为"1"的行值为 5,列值为 3,则["53"] = "1"
local tKeypad =
{
["53"] = "1",["52"] = "2",["51"] = "3",["50"] = "A",
["43"] = "4",["42"] = "5",["41"] = "6",["40"] = "B",
["33"] = "7",["32"] = "8",["31"] = "9",["30"] = "C",
["23"] = "*",["22"] = "0",["21"] = "#",["20"] = "D",
["255255"] = "开关机"
}
5.1.2 定义某个 keyName 按键的长按下消息处理函数
local function keyLongPressTimerCb(keyName)
log.info("keypad.keyLongPressTimerCb",keyName)
5.1.3 定义一个按键消息处理函数
按键消息处理函数
local function keyMsg(msg)
--保存按键名
--msg.key_matrix_row:行索引
--msg.key_matrix_col:列索引
local keyName = tKeypad[msg.key_matrix_row..msg.key_matrix_col]
log.info("keyMsg",msg.key_matrix_row,msg.key_matrix_col,msg.pressed,keyName)
if msg.pressed then --第一个参数:keyName按键的长按消息处理函数
--第二个参数:超时时间为3秒
--第三个参数:按键名
sys.timerStart(keyLongPressTimerCb,3000,keyName)
end
end
5.1.4 注册按键消息处理函数
rtos.on(rtos.MSG_KEYPAD,keyMsg)
5.1.5 初始化键盘阵列
--第一个参数:固定为rtos.MOD_KEYPAD,表示键盘
--第二个参数:目前无意义,固定为0
--第三个参数:键盘阵列keyin标记,例如使用了keyin2、keyin3、keyin4、keyin5,则第三个参数为1<<2|1<<3|1<<4|1<<5 = 0x3C 行
--第四个参数:键盘阵列keyout标记,例如使用了keyout0、keyout1、keyout2、keyout3,则第四个参数为1<<0|1<<1|1<<2|1<<3 = 0x0F 列
rtos.init_module(rtos.MOD_KEYPAD,0,0x3c,0x0F)
5.2 testKeypad.lua 代码
注册按键消息处理函数 rtos.on(rtos.MSG_KEYPAD,keyMsg),初始化键盘阵列 rtos.init_module(rtos.MOD_KEYPAD,0,0x0F,0x0F),当有键盘按下或抬起时按键消息处理函数会打印出对应的行列值。
--- 模块功能:矩阵键盘测试
-- @module powerKey
-- @author openLuat
-- @license MIT
-- @copyright openLuat
-- @release 2018.06.13
require"sys"
module(..., package.seeall)
local function keyMsg(msg)
--msg.key_matrix_row:行
--msg.key_matrix_col:列
--msg.pressed:true表示按下,false表示弹起
log.info("keyMsg",msg.key_matrix_row,msg.key_matrix_col,msg.pressed)
end
--注册按键消息处理函数
rtos.on(rtos.MSG_KEYPAD,keyMsg)
--初始化键盘阵列
--第一个参数:固定为rtos.MOD_KEYPAD,表示键盘
--第二个参数:目前无意义,固定为0
--第三个参数:表示键盘阵列keyin标记,例如使用了keyin0、keyin1、keyin2、keyin3,则第三个参数为1<<0|1<<1|1<<2|1<<3 = 0x0F
--第四个参数:表示键盘阵列keyout标记,例如使用了keyout0、keyout1、keyout2、keyout3,则第四个参数为1<<0|1<<1|1<<2|1<<3 = 0x0F
rtos.init_module(rtos.MOD_KEYPAD,0,0x0F,0x0F)
5.3 main.lua 代码
本代码为主程序脚本,系统启动后首先会对 4G 网络进行配置,等待网络连接成功,然后加载矩阵键盘测试模块。
--必须在这个位置定义PROJECT和VERSION变量
--PROJECT:ascii string类型,可以随便定义,只要不使用,就行
--VERSION:ascii string类型,如果使用Luat物联云平台固件升级的功能,必须按照"X.X.X"定义,X表示1位数字;否则可随便定义
PROJECT = "GPIO_SINGLE"
VERSION = "2.0.0"
--加载日志功能模块,并且设置日志输出等级
--如果关闭调用log模块接口输出的日志,等级设置为log.LOG_SILENT即可
require "log"
LOG_LEVEL = log.LOGLEVEL_TRACE
--[[
如果使用UART输出日志,打开这行注释的代码"--log.openTrace(true,1,115200)"即可,根据自己的需求修改此接口的参数
如果要彻底关闭脚本中的输出日志(包括调用log模块接口和Lua标准print接口输出的日志),执行log.openTrace(false,第二个参数跟调用openTrace接口打开日志的第二个参数相同),例如:
1、没有调用过sys.opntrace配置日志输出端口或者最后一次是调用log.openTrace(true,nil,921600)配置日志输出端口,此时要关闭输出日志,直接调用log.openTrace(false)即可
2、最后一次是调用log.openTrace(true,1,115200)配置日志输出端口,此时要关闭输出日志,直接调用log.openTrace(false,1)即可
]]
--log.openTrace(true,1,115200)
require "sys"
require "net"
--每1分钟查询一次GSM信号强度
--每1分钟查询一次基站信息
net.startQueryAll(60000, 60000)
--此处关闭RNDIS网卡功能
--否则,模块通过USB连接电脑后,会在电脑的网络适配器中枚举一个RNDIS网卡,电脑默认使用此网卡上网,导致模块使用的sim卡流量流失
--如果项目中需要打开此功能,把ril.request("AT+RNDISCALL=0,1")修改为ril.request("AT+RNDISCALL=1,1")即可
--注意:core固件:V0030以及之后的版本、V3028以及之后的版本,才以稳定地支持此功能
ril.request("AT+RNDISCALL=0,1")
--[[
sys.timerLoopStart(function()
log.info("net.getCellInfoExt",net.getCellInfoExt())
end,1000)]]
--加载控制台调试功能模块(此处代码配置的是uart2,波特率115200)
--此功能模块不是必须的,根据项目需求决定是否加载
--使用时注意:控制台使用的uart不要和其他功能使用的uart冲突
--使用说明参考demo/console下的《console功能使用说明.docx》
--require "console"
--console.setup(2, 115200)
--加载网络指示灯和LTE指示灯功能模块
--根据自己的项目需求和硬件配置决定:1、是否加载此功能模块;2、配置指示灯引脚
--合宙官方出售的Air720U开发板上的网络指示灯引脚为pio.P0_1,LTE指示灯引脚为pio.P0_4
require "netLed"
pmd.ldoset(2,pmd.LDO_VLCD)
netLed.setup(true,pio.P0_1,pio.P0_4)
--网络指示灯功能模块中,默认配置了各种工作状态下指示灯的闪烁规律,参考netLed.lua中ledBlinkTime配置的默认值
--如果默认值满足不了需求,此处调用netLed.updateBlinkTime去配置闪烁时长
--LTE指示灯功能模块中,配置的是注册上4G网络,灯就常亮,其余任何状态灯都会熄灭
--加载错误日志管理功能模块【强烈建议打开此功能】
--如下2行代码,只是简单的演示如何使用errDump功能,详情参考errDump的api
require "errDump"
errDump.request("udp://dev_msg1.openluat.com:12425", nil, true)
--加载远程升级功能模块【强烈建议打开此功能,如果使用了阿里云的OTA功能,可以不打开此功能】
--如下3行代码,只是简单的演示如何使用update功能,详情参考update的api以及demo/update
--PRODUCT_KEY = "v32xEAKsGTIEQxtqgwCldp5aPlcnPs3K"
--require "update"
--update.request()
require "testKeypad"
--启动系统框架
sys.init(0, 0)
sys.run()
六、开机调试
6.1 开发板开机
连接好硬件并下载固件后,启动 Luatools 软件,系统运行信息将显示在界面中。红框中为开发板连接到 PC 机后正常打印的信息,如下图所示。
6.2 键盘调试
键盘按下或抬起时按键消息处理函数会打印出对应的行列
,true 为按键按下,false 为按键抬起。
七、常见问题
7.1 为什么 KEYIN0 的按键在开机时被按下后就会不开机。
答:因为 KEYIN0 信号复用为是 USB_BOOT,如果被按下就会进入下载模式,就进入不了开机流程。只需重新断电开机就能恢复
7.2 为什么按下按键时没反应?
1.看下按键引脚是否与模块引脚是否接对?键盘是不是 ok?
2.是不是引用了 powerKey.lua ,关机按键默认行列是(255,255)不需另外配置。