• 欢迎大家分享资料!前往留言板评论即可!

【小技巧】关于时间戳和rtos.tick()的一点使用心得

合宙 模组资料网 2年前 (2021-05-15) 346次浏览 0个评论 扫描二维码
文章目录[隐藏]

众所周知,os.time()输出的是时间戳,而rtos.tick()是每秒16384个tick。那么这二者有什么用途呢?

通常而言,如果是需要严格的时间认证,那么必须使用os.time(),至于说同步时钟的方法有很多,可以参考:http://oldask.openluat.com/article/30

但是,不论使用哪个方法,都会出现一个问题:同步成功前后产生巨大的差值,可能导致程序逻辑运行错误

避免错误

如何避免时钟同步前后产生的差值,导致程序错误呢?

方法一、使用rtos.tick()

之前的方式:

a=os.time()

— 时钟同步后,os.time()瞬间增加成千上万,后边的if会判断为true,并执行

if os.time()-a>20 then xxxx end

现在的方式:

a=rtos.tick()

— 时钟同步后,os.time()瞬间增加成千上万,但是并不影响rtos.tick(),后边的if逻辑不会出错,程序正常执行

if rtos.tick()-a>20*16384 then xxxx

如此一来,使用rtos就可以完美的计时,且不用担心时钟同步后导致错误了。

但是需要注意,rtos.tick(),根据底层和模块不同,脉冲次数与归零周期不同。其中非float底层,rtos.tick()默认归零时间是38小时,float底层rtos.tick()是72小时。

方法二、使用os.time()

如果程序需要稳定运行,无法接收rtos.tick()定期归零,那么有两个方法避免:

1、记录rtos.tick()归零行为,并把原值做处理

local iLstTick=0                –记录最后一次tick值,开机默认是0

local bTickReset=false    –记录刚刚是否tick重置过

sys.timerStart(function()    –timer,用于判断tick是否重置

    if rtos.tick()<25000 and iLstTick~=0 then         bTickReset=true     end     iLstTick=rtos.tick() end, 1000)

local iRecTick            –设置变量,记录tick

–判断间隔时间是否符合条件,并执行代码

if bTickReset==true then

    –需要根据底层判断最长,否则可能出错,这里用的是72小时,即4,294,967,295‬

    iRecTick = iRecTick-4294967295‬

    bTickReset=false
end

if rtos.tick()-iRecTick>30*16384 then

    –your code

end

2、记录os.time()同步前后的差值,并将它加入到运算中

local iOldTimeStamp,iLastTimeStamp=0, 0

sys.timerStart(function()

    if os.time()<1500000000 then    –如果ntp同步成功,肯定大于150000000

        iOldTimeStamp=os.time()

        iLastTimeStamp=os.time()

    else

        if iLastTimeStamp<1500000000 then iLastTimeStamp=os.time() end

    end

end, 1000)

–现在获得了同步前后的差值就是iLastTimeStamp-iOldTimeStamp

local a –假设a是标的

if a <1500000000 then a=a+iLastTimeStamp-iOldTimeStamp end    –这里加上同步前后的差值,就不会影响a的值

if os.time()-a>30 then   

    –your code

end


喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址