0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

时间戳使用技巧

玩转单片机 来源:玩转单片机 2023-12-18 09:17 次阅读

好久前写过一篇相关的推文,当时也是第一次接触和使用,由于没有深入的了解和研究, 这段时间一直存在疑惑,趁着这段时间就回顾一下和解决疑惑.

|疑惑

很多知识其实是自学的, 有些知识虽然学了, 但是并没有认真深入了解. 时间戳的实现往往是使用u32类型的变量在1ms定时中自加,那么:

u32极限值:4294967295
约等于4294967秒
约等于71582分
约等于1193小时
约等于49.7天

从结果就可以看出49.7天后就会溢出, 由此就可以看出时间戳并不能保证唯一性,这就是时间戳最明显的bug,导致项目不敢使用这个技巧,后来发现好像不对劲, 为啥这么多大佬在用不会出问题,所以就抽空深入研究一下.

|解惑

时间戳: 简单可以理解为某一时刻的时间点, 并不是常规计算机理解的时间戳(时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数)!

持续时间:持续时间是指时间间隔的长度,即定义间隔开始和结束的时刻之间的时间距离。

要明确区分常规的概念和特定场景下的概念, 高级语言是可以通过时间戳相减获取时间间隔与持续时间做对比, 而本文说的时间戳并不是唯一的, 所以直接使用时间戳相减意义并不是很大. 通过观察可以发现,一个数有最大值, 并且时间间隔又是固定的, 那是不是意味着有规律可循, 由于u32的数太大, 就直接使用u8的数来验证猜想:

#include"stdio.h"
#include"stdint.h"

intmain()
{
uint8_ttick_now=0;//当前的时间戳
uint8_ttick_old=0;//过去的时间戳
uint8_twait=3;//等待的时间
uint8_tdiff=0;//时间差
uint32_tj=0;
printf("tick_old:%d,j:%d
",tick_old,j);
for(uint32_ti=0;i< 2000; i++)
    {
        tick_now = tick_now + 1;
        diff = tick_now - tick_old;
        if(diff == wait)
        {
            j++;
            tick_old = tick_old + wait;
            printf("tick_old:%d,j:%d
", tick_old, j);
        }
    }
    return 0 ;
}

结果输出:

tick_old:0,j:0
tick_old:3,j:1
tick_old:6,j:2
tick_old:9,j:3
tick_old:12,j:4
tick_old:15,j:5
tick_old:18,j:6
tick_old:21,j:7
tick_old:24,j:8
tick_old:27,j:9
tick_old:30,j:10
tick_old:33,j:11
tick_old:36,j:12
tick_old:39,j:13
tick_old:42,j:14
tick_old:45,j:15
tick_old:48,j:16
tick_old:51,j:17
tick_old:54,j:18
tick_old:57,j:19
tick_old:60,j:20
tick_old:63,j:21
tick_old:66,j:22
tick_old:69,j:23
tick_old:72,j:24
tick_old:75,j:25
tick_old:78,j:26
tick_old:81,j:27
tick_old:84,j:28
tick_old:87,j:29
tick_old:90,j:30
tick_old:93,j:31
tick_old:96,j:32
tick_old:99,j:33
tick_old:102,j:34
tick_old:105,j:35
tick_old:108,j:36
tick_old:111,j:37
tick_old:114,j:38
tick_old:117,j:39
tick_old:120,j:40
tick_old:123,j:41
tick_old:126,j:42
tick_old:129,j:43
tick_old:132,j:44
tick_old:135,j:45
tick_old:138,j:46
tick_old:141,j:47
tick_old:144,j:48
tick_old:147,j:49
tick_old:150,j:50
tick_old:153,j:51
tick_old:156,j:52
tick_old:159,j:53
tick_old:162,j:54
tick_old:165,j:55
tick_old:168,j:56
tick_old:171,j:57
tick_old:174,j:58
tick_old:177,j:59
tick_old:180,j:60
tick_old:183,j:61
tick_old:186,j:62
tick_old:189,j:63
tick_old:192,j:64
tick_old:195,j:65
tick_old:198,j:66
tick_old:201,j:67
tick_old:204,j:68
tick_old:207,j:69
tick_old:210,j:70
tick_old:213,j:71
tick_old:216,j:72
tick_old:219,j:73
tick_old:222,j:74
tick_old:225,j:75
tick_old:228,j:76
tick_old:231,j:77
tick_old:234,j:78
tick_old:237,j:79
tick_old:240,j:80
tick_old:243,j:81
tick_old:246,j:82
tick_old:249,j:83
tick_old:252,j:84
tick_old:255,j:85

寻找规律:

//刚开始
tick_old:0,j:0
//第一次溢出
tick_old:255,j:85
tick_old:2,j:86
//第二次溢出
tick_old:254,j:170
tick_old:1,j:171
//第三次溢出
tick_old:253,j:255
tick_old:0,j:256
//第四次溢出
tick_old:255,j:341
tick_old:2,j:342
//第五次溢出
tick_old:254,j:426
tick_old:1,j:427
//第六次溢出
tick_old:253,j:511
tick_old:0,j:512
...

通过观察可以发现等待的时间的设定和溢出多少次后再次回到0值是有关系的, 上面设定的等待时间为3就意味着溢出三次就进入下一个循环,同时可以看到每次触发的时间间隔都是3, 并不会因为溢出而导致出现问题.

4757ee6a-9d39-11ee-8b88-92fbcf53809c.png

注意: 时间间隔只有保证在49.7天内才会正常使用!

所以规避时间溢出BUG 的方法就是对时间戳做减法,直接使用时间戳就必然需要解决时间溢出的BUG!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机
    +关注

    关注

    19

    文章

    6649

    浏览量

    84522
  • 时间戳
    +关注

    关注

    0

    文章

    15

    浏览量

    2536

原文标题:技巧|时间戳

文章出处:【微信号:玩转单片机,微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32L051同时开启RTC时间和秒唤醒后,使用GPIO引脚无法触发时间中断如何解决?

    STM32L051同时开启RTC时间和秒唤醒后,使用GPIO引脚无法触发时间中断。但使用一个3.3V的电源接到PC13能够触发RTC时间
    发表于 04-01 06:37

    时间同步获取时间

    新手一枚,对单片机原理还不是很清楚,求教:TinyOS中的时间同步首先要获取本地时间,getStartTime(),想知道它是怎么获取时间
    发表于 03-20 10:37

    如何查询时间

    有的时候,我们破解的某些软件,需要修改时间,比如Mybase这款笔记软件,破解的时候主要是修改时间。查询方法一:假如我使用的是python,>>> import time>
    发表于 02-15 16:54

    时间字段的格式是什么

    我们有来自benchvue的日志(hdf5),我们将其导入到matlab中。有人可以告诉我们时间字段的格式是什么 - 它似乎不是标准的unix格式。我们可以使用benchvue将这些日志转换
    发表于 10-15 11:18

    uCOSIII的时间出现错误

    想关掉时间简单地进行下移植但已经关掉却没作用还是出现下面这种错误
    发表于 03-28 06:35

    请教:Labview生成Unix时间

    请教:Labview生成Unix时间,如何处理!直接数值转换的值不匹配!
    发表于 05-24 23:18

    ERTC 时间的使用

    示例目的演示AT32F415以及AT32F421 ERTC时间的使用。支持型号:AT32F415xxAT32F421xx主要使用外设:ERTC1.快速使用方法1.1 硬件资源1
    发表于 08-18 19:55

    什么是Unix时间

    1.什么是Unix时间Unix时间是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 [1]Unix时间
    发表于 01-12 08:30

    时间的简介与实现

    时间时间简介时间的实现时间
    发表于 02-28 06:23

    ulog里现在默认的时间是从哪里获取的呢?

    我现在用的外部RTC,想在ulog里的时间显示外部RTC的时间,ulog里现在默认的时间是从哪里获取的呢?多谢了。。。
    发表于 11-14 14:22

    如何在tilebox上获取时间

    你好我知道 tilebox 有一个 RTC 模块,所以我意识到获取当前时间来为数据生成时间是可行的。可以这样做吗?在给定的项目示例中是否有任何实现?谢谢
    发表于 01-05 08:59

    如何配置SJA1105Q的时间功能?

    你好 : 我正在配置 SJA1105Q 的时间功能,我想知道下面的寄存器可以在运行时更改吗?由于建议将它们作为入口和入口时间的来源,因此应将其更改为固定域区域的主要
    发表于 05-06 06:57

    ulog里用的时间是从哪里取的?

    我现在用的外部RTC,想在ulog里的时间显示外部RTC的时间,ulog里现在默认的时间是从哪里获取的呢?多谢了。。。
    发表于 05-11 09:56

    LittleFS时间与Windows时间不兼容要怎么处理?

    上次更新的文件时间。但是,这似乎与 Windows 时间不兼容,因此: 1. 如果我使用 LittleFS 编辑文件然后显示 Last Write,它会按预期显示最近的日期/
    发表于 06-01 08:18

    AT32F415 AT32F421 ERTC时间的使用

    AT32F415 AT32F421 ERTC 时间的使用演示AT32F415以及AT32F421 ERTC时间的使用。
    发表于 10-26 06:01