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

目录

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

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

一、前言

  上一篇博文我们讲到了将GPIO初始化为输出功能用来驱动LED或者其他外设,这篇博文我们来继续讲讲GPIO剩下的另外一个功能——输入功能
  既然是智能设备,那就需要和外界交互信息。获取外界消息的方法有很多。
  通过互联网访问是一种获取信息的方式。
在这里插入图片描述
  还有是通过自身的传感器或者按钮开关,获取传感信息,也是一种获取信息的方式,它们输出的信号是开关量
在这里插入图片描述在这里插入图片描述
  通过互联网获取信息,我们后面的博客在讲,先不急。
  我们今天来讲一讲,怎么利用GPIO的输入功能来获取外界的开关信号。

二、编写程序

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

1、查询法

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

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输入中断的使用方法如下

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开发板

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

--必须在这个位置定义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库函数

  • pins.setup(28, GPIO_Exti_cb, pio.PULLUP)–将GPIO28初始化为输入上拉,并且启用中断回调
  • pins.setup(27, nil, pio.PULLUP)–将GPIO27初始化为输入上拉

2、两种使用方法的环境

  • 查询法适用于普通场景,对事件敏感度不高的情况,查询不建议太过于频繁,一般按钮的话500ms查询一次,速度都还可以接收,
  • 中断法适用于强实时性场所,比如某些设备的急停按钮这就不能用查询法了,这类按钮对事件要求比较严格,用中断可以满足要求

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇雪长安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值