Luat_休眠控制示例

使用724开发板测试pm(休眠管理)功能

简介

我们在使用模块时,经常会关注到模块的功耗,这篇示例教大家如何使用724开发板来测试模块的休眠管理功能

材料准备

  1. EVB_Air724UG_A13开发板一套,包括直流电源,USB线,串口线,杜邦线
  2. 一台电脑,串口调试工具(这里使用的是sscom 5.13.1),Luatools_2.1.5
  3. luat开发环境:环境搭建方法
    image.png

pm功能介绍

这里是功耗管理的传送门,请点我

API说明

这里是pm接口介绍的传送门,请点我

步骤

我们在这里做两个演示,第一个是看模块休眠时的电流(这个是唯一可以判断模块是否休眠的方法),第二个是看休眠对模块功能的影响

我手上所使用的开发板已经拆除了影响功耗的外围器件,如led灯,串口芯片
image.png

第一个示例

使用拆除外围器件的开发板烧录pm的demo,利用精密电源来测试模块正常联网后,休眠与唤醒时5分钟的平均功耗

将其余代码都注释掉
image.png

  • 模块休眠时的功耗

    烧录脚本模块启动后,等待一段时间(时间不确定),模块会自动进入休眠
    可以看到图中显示,休眠后五分钟内平均功耗为2.23mA
    image.png

    image.png

  • 模块保持唤醒状态的功耗

    在testPm.lua内最后一行再加上pm.wake(tag)即可使模块保持唤醒状态

    pm.wake("TEST")
    

    image.png

    5分钟内平均功耗为13.57mA
    image.png

image.png

第二个示例

这个示例用以演示:休眠与唤醒对模块功能的影响,以及pm.wake(tag)与pm.sleep(tag)的应用

这里是第二个示例用到的脚本,请点我下载

此demo的总体功能为:当模块的GPIO_9检测到高电平中断时,使模块唤醒,低电平中断时,使模块休眠。串口是常用到与外设进行通讯的通道,是一个会受到休眠影响的功能使用串口调试工具向模块的串口2发送含有固定字符的字符串,来控制开发板上3个led灯,观察模块休眠与唤醒时led灯的状态

因为此demo只是为了演示休眠与唤醒对模块功能的影响,所以不使用第一个示例所用的拆除外围耗电器件的开发板。使用正常的开发板进行测试

先说我们可以通过本示例观察到的现象:模块保持唤醒时,led灯循环规律亮灭;模块休眠时,led灯不定时亮灭

测试前的准备
  • 设置GPIO

    将GPIO_9设置为中断,GPIO_1,GPIO_4,GPIO5初始化,这三个GPIO分别对应开发板上的绿灯,蓝灯,红灯

    pmd.ldoset(2,pmd.LDO_VLCD)			--开启VLCD电压域,给GPIO_1与GPIO_4供电
    local level = 1
    local gpio_1 = pins.setup(pio.P0_1, 1)
    local gpio_4 = pins.setup(pio.P0_4, 1)
    local gpio_5 = pins.setup(pio.P0_5, 1)
    function gpioInt_9(msg)			         --GPIO_9的中断处理函数
        if msg == cpu.INT_GPIO_POSEDGE then				--高电平中断时唤醒
            log.warn("使用了pm.wake()来使系统唤醒")
            pm.wake("TEST")								
        else											--低电平中断时休眠
            log.warn("使用了pm.slepp()来使系统休眠")
            pm.sleep("TEST")
        end
    end
    pin9 = pins.setup(pio.P0_9, gpioInt_9)				--将GPIO_9设置为中断
    
    sys.timerStart(	--因为是中断,所以开机要检测一次GPIO_9的状态,如果是高就保持唤醒
        function()	        --如果是低则不做处理,因为模块联网后底层会自动进入休眠
            if pin9() == 1 then
                pm.wake("TEST")
            end
        end
    , 500)   
    
  • 设置串口

    使用串口二来进行读取任务,当匹配到相应字符串后,去控制LED灯的状态

    local UART_ID = 2          										--串口2
    local function read()   										--串口收到数据时的读取函数
        while true do
            local data = uart.read(UART_ID, "*l")
            if not data or string.len(data) ==  0 then break end
            if string.match(data, "GPIO_TEST") then   --如果在数据中匹配到"GPIO_TEST"字符串
                level = level == 1 and 0 or 1		     --则控制三个led灯的亮灭
                gpio_1(level)
                gpio_4(level)
                gpio_5(level)
            end
        end
    end
    
    uart.on(UART_ID, "receive", read)								--当串口收到数据时执行read
    uart.setup(UART_ID, 115200, 8, uart.PAR_NONE, uart.STOP_1)		--打开串口
    

image-20210331143940039.png

开始测试

使用Luatools烧录脚本,勾选“串口1打印trace”,烧录完脚本后,将USB从开发板拔出(模块在USB接入时不会休眠),使用直流电源供电,接到模块的UART2上,串口线接到UART1,如图所示image-20210331114635578.png

  • 将GPIO_9与1V8短接,产生高电平中断,调用pm.wake(tag)来唤醒模块

    • 用串口调试工具向UART2发送带有"GPIO_TEST"的数据,可以观察到led灯在循环规律亮灭,同时我们可以观察此刻直流电源所显示的瞬时电流
  • 每秒发四次数据,可以看到开发板上的led灯一秒内亮灭两次image-20210331115255995.png

  • 保持此唤醒状态,观察5分钟的平均电流
    image.png

    image.png

  • 将1v8与GPIO_9断开,产生低电平中断,调用了pm.sleep(“TEST”)使模块休眠,串口调试助手保持1秒发送4次数据的频率

    • 观察开发板上的led灯,可以看到:灯会不规律地亮灭,之所以这样,是因为模块休眠使串口接收不到或很难接收到数据
  • 再保持此休眠状态,观察5分钟的平均电流,会发现相较于唤醒时的电流是很低的
    image.png

    image.png
    当我们需要用串口来传输数据时,提前调用pm.wake(tag)唤醒模块,以保证串口能够正常收发数据;数据传输完毕后,为了省电,再调用pm.sleep(tag)来使模块休眠

  • 在使用过程中,我们可以使用pm.isSleep(tag)/pm.isSleep()来查询脚本或tag的休眠状态

    sys.taskInit(
        function()
            while true do 
                print("\"TEST\"的休眠状态:",pm.isSleep("TEST"),"全局的休眠状态:",pm.isSleep()))
            	sys.wait(1000)
            end
        end
    )
    
    • 将GPIO_9与1v8短接后,脚本内调用了pm.wake(“TEST”)

      日志会循环打印:"TEST"的休眠状态: false 全局的休眠状态: false

    • 将GPIO_9与1v8断开后,脚本内调用了pm.sleep(“TEST”)

      日志会循环打印:"TEST"的休眠状态: true 全局的休眠状态: true

  • 如果有存在多个pm.wake(tag),模块的休眠状态是怎样的

    • 例如,存在如下几个pm.wake(tag)

      pm.wake("TEST_1") pm.wake("TEST_2") pm.wake("TEST_3") pm.wake("TEST_4")
      

      这时候去使用如下代码去查询脚本的休眠状态,会得到如下返回值

      print(pm.isSleep("TEST_1"))			--false
      print(pm.isSleep("TEST_2")) 		--false
      print(pm.isSleep("TEST_3")) 		--false
      print(pm.isSleep("TEST_4"))			--false
      print(pm.isSleep())					--false
      

      模块保持唤醒状态,没有休眠,现在用pm.sleep(“TEST_4”)与pm.sleep(“TEST_2”)来标记TEST_4与TEST_2已经工作完毕,可以休眠,然后再次查询tag与脚本的休眠状态

      pm.wake("TEST_1") pm.wake("TEST_2") pm.wake("TEST_3") pm.wake("TEST_4")
      
      pm.sleep("TEST_2")
      pm.sleep("TEST_4")
      
      print(pm.isSleep("TEST_1")) 		--false
      print(pm.isSleep("TEST_2")) 		--true
      print(pm.isSleep("TEST_3")) 		--false
      print(pm.isSleep("TEST_4"))			--true
      print(pm.isSleep())					--false
      

      通过如上返回值我们会发现,TEST_2与TEST_4已经是休眠状态了,但是TEST_1与TEST_3不是休眠状态,所以脚本全局没有进行休眠,这时候想让模块休眠就需要使用pm.sleep()来使所有的tag进行休眠,模块才会真正地进入休眠

      pm.wake("TEST_1") pm.wake("TEST_2") pm.wake("TEST_3") pm.wake("TEST_4")
      
      print(pm.isSleep("TEST_1")) 		--false
      print(pm.isSleep("TEST_2"))			--false
      print(pm.isSleep("TEST_3"))			--false
      print(pm.isSleep("TEST_4"))			--false
      print(pm.isSleep())					--false
      
      pm.sleep("TEST_1")
      pm.sleep("TEST_2")
      pm.sleep("TEST_3")
      pm.sleep("TEST_4")
      
      print(pm.isSleep("TEST_1"))			--true
      print(pm.isSleep("TEST_2"))			--true
      print(pm.isSleep("TEST_3"))			--true
      print(pm.isSleep("TEST_4"))			--true
      print(pm.isSleep())					--true
      

常见问题

为什么模块无法进入休眠

1. 查看模块是否插入USB,USB连接的状态下模块保持唤醒,无法休眠
2. 使用开发板和自己的板子烧录adc的demo进行对比,看模块是否能够进行休眠
3. 使用pm.isSleep()接口查询脚本休眠状态,看是否是调用了pm.wake(tag)后没有去调用pm.sleep(tag)
4. 屏蔽代码,看是由哪部分代码使模块无法休眠

为什么串口1在休眠状态下也能正常收发数据

uart1在core中做了特殊处理,可以实现休眠状态下接收数据不丢失
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值