5、合宙Air模块Luat开发:GPIO输入常见的两种使用方法及其优劣性

目录

点击这里查看所有博文

本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。

先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获
我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!

一、前言

上一篇博文我们讲到了将GPIO初始化为输出功能用来驱动LED或者其他外设,这篇博文我们来继续讲讲GPIO剩下的另外一个功能——输入功能

既然是智能设备,那就需要和外界交互信息。获取外界消息的方法有很多。
通过互联网访问是一种获取信息的方式。
在这里插入图片描述
还有是通过自身的传感器或者按钮开关,获取传感信息,也是一种获取信息的方式,它们输出的信号是开关量
在这里插入图片描述在这里插入图片描述
通过互联网获取信息,我们后面的博客在讲,先不急。
我们今天来讲一讲,怎么利用GPIO的输入功能来获取外界的开关信号。

二、编写程序

利用GPIO的输入功能获取开关信号有两种方法,一种是查询法,另外一种是中断法,我们依次讲解

1、查询法

顾名思义,查询法就是不停的查询GPIO的状态,不管开关有没有按下,我都去查询,查询到什么就是什么,我没有查询的时候,你按了也没有用,这种方法的实时性比较低。
具体使用方法如下

1
2
3
4
5
6
7
8
9
10
11
12
local function GPIO_Input_init()
local KEY1 = pins.setup(27, nil, pio.PULLUP)--将GPIO27初始化为输入上拉
local LED1 = pins.setup(64, 0)--将GPIO64初始化为输出
while true do
if KEY1() == 0 then--如果KEY1被接地,那么就点亮LED1
LED1(1)
else
LED1(0)--否则熄灭LED1
end
sys.wait(1000)--一秒查询一次
end
end

查询法用起来比较简单需要不停的去查询
假如延时过短,就会出现任务切换频繁,执行效率低,cpu一直在忙着查询。
延时时间过长就会出现实时性低,比如我上面的代码key1接通后运气不好的时候需要等一秒钟才会有反应,不建议在对事件敏感的时候使用

2、中断法

中断我对它的理解是,他的优先级高于普通函数,可以打断正在执行的低优先级中断,和普通任务。
有打断的意思,只要正在执行的任务优先级比它低,当中断来临时就可以被打断,转而去执行中断函数。
中断的原则是快进快出,不能在里面执行复杂的事情,否则会影响其他任务执行。相对普通任务实时性较高,适用于对事件敏感的情况
在Air720SL中GPIO输入中断的使用方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
local LED2
function GPIO_Exti_cb(msg)--中断回调函数
if msg == cpu.INT_GPIO_POSEDGE then--如果当前中断是上升沿触发
LED2(0)--熄灭LED2
else
LED2(1)--否则点亮LED2
end
end

local function GPIO_Exti_init()
local KEY2 = pins.setup(28, GPIO_Exti_cb, pio.PULLUP)--将GPIO28初始化为输入上拉,并且启用中断回调
LED2 = pins.setup(65, 0)--将GPIO65初始化为输出
end

中断的使用方法相比查询到要显得麻烦一下,需要多写一个函数,代码量比较多,但是好处就是实时性高。

三、下载完整的代码到Air720Sl开发板

这里我们直接贴出全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
--必须在这个位置定义PROJECT和VERSION变量
--PROJECT:ascii string类型,可以随便定义,只要不使用,就行
--VERSION:ascii string类型,如果使用Luat物联云平台固件升级的功能,必须按照"X.X.X"定义,X表示1位数字;否则可随便定义
PROJECT = "LED"
VERSION = "0.0.1"
require "sys"
--加载日志功能模块,并且设置日志输出等级
--如果关闭调用log模块接口输出的日志,等级设置为log.LOG_SILENT即可
require "log"
LOG_LEVEL = log.LOGLEVEL_TRACE



require "pins"

local function GPIO_Input_init()
local KEY1 = pins.setup(27, nil, pio.PULLUP)--将GPIO27初始化为输入上拉
local LED1 = pins.setup(64, 0)--将GPIO64初始化为输出
while true do
if KEY1() == 0 then--如果KEY1被接地,那么就点亮LED1
LED1(1)
else
LED1(0)--否则熄灭LED1
end
sys.wait(1000)--一秒查询一次
end
end

local LED2
function GPIO_Exti_cb(msg)--中断回调函数
if msg == cpu.INT_GPIO_POSEDGE then--如果当前中断是上升沿触发
LED2(0)--熄灭LED2
else
LED2(1)--否则点亮LED2
end
end

local function GPIO_Exti_init()
local KEY2 = pins.setup(28, GPIO_Exti_cb, pio.PULLUP)--将GPIO28初始化为输入上拉,并且启用中断回调
LED2 = pins.setup(65, 0)--将GPIO65初始化为输出
end

local function user_main()
sys.wait(10000)
sys.taskInit(GPIO_Input_init)
sys.taskInit(GPIO_Exti_init)
end

--启动系统框架
sys.taskInit(user_main)
sys.init(0, 0)
sys.run()


下载程序后运行结果如下,GPIO27控制LED1,GPIO28控制LED2.
GPIO27使用一秒查询一次,反应速度感觉明显有卡顿
GPIO28采用中断,几乎感觉不出来有延时
在这里插入图片描述

四、总结

1、官方的pins库函数

2、两种使用方法的环境

不会下载的点击这里,进去查看我的第二篇博文2、Air720SL模块Luat开发:第一个Luat的Hello World里面讲了怎么下载
这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束

上次更新 2021-01-28