字节转换算法应用_读取本地时间

文章目录


前言

西门子博途编程平台中,可以使用RD_LOC_T指令读取本地时间。调用该指令时,其输出的变量可选择DTL或Date_And_Time数据类型。

本文将对RD_LOC_T指令的使用方法进行阐述,并详细对比DTL和Date_And_Time数据类型在程序处理中的区别,同时对字节和整型数据类型之间的转换方法进行讲解。


一、功能概述

  1. 读取本地时间;
  2. 读取DTL类型变量中的年、月、日、星期、时、分、秒等数据;
  3. 读取Date_And_Time类型变量中的年、月、日、星期、时、分、秒等数据。

二、程序编写

1. 组态

打开设备视图,选择CPU的属性-时间,将时区改为(UTC+08:00)北京时间。

2. 新建FB块"FB617_SYSTIME"

本程序仅作为实验验证,用于阐述DTL和Date_And_Time数据类型在编程上的区别。

建立如下引脚变量:

图1

其中,变量"SystemTimeByte"仅作为"SystemTimeDT"的拆分,不占用存储空间。使用AT指令,将其拆分为8个字节,用于读取不同字节的数据。AT指令的使用方法,详见文章《十二、SCL核心应用课项目实战_运行设备累计功能实现》

"TempByte"作为"SystemTimeByte"数组的映射,仅用于DB块监控。

3. 编程

1. DTL类型

图2

首先使用DTL类型变量,下载程序,打开自动生成的背景数据块并监控,如图3所示。

图3

可以看到,DTL类型的变量占用12个字节,输出的值包含以下数据。若想使用某个数据,直接在程序中调用对应变量即可。

c 复制代码
 Year: WORD;     // 年 (1-9999)
 Month: BYTE;    // 月 (1-12)
 Day: BYTE;      // 日 (1-31)
 Weekday: BYTE;  // 星期 (1=周日, 7=周六)
 Hour: BYTE;     // 时 (0-23)
 Minute: BYTE;   // 分 (0-59)
 Second: BYTE;   // 秒 (0-59)
 Nanosecond: DWORD; // 纳秒 (0-999,999,999)

2. Date_And_Time类型

同理,将DTL类型变量替换为Date_And_Time类型变量,再次下载程序,监控DB块数据,如图5所示。

图4

图5

可以看到,DT类型的变量占用8个字节,其中每个字节都以 BCD 码形式存储日期时间的各个部分。相较于DTL类型变量,无法直接读取相应的年、月、日、星期、时、分、秒等数据,需要通过编写程序进行拆分。

3. Date_And_Time类型变量拆分

如图1所示,我们已将Date_And_Time类型变量拆分成了8个Byte类型变量组成的数组。对应字节存储以下信息:

c 复制代码
字节0-1: 年(后两位,范围1990-2089)
字节2: 月
字节3: 日
字节4: 小时
字节5: 分钟
字节6: 秒
字节7: 星期(高4位为0,低4位表示星期几,其中1表示周日,2表示周一,...,7表示周六)

已知,星期数据存储在最后一个字节(即第 8 个字节,索引为 7)的低4位中,而对于其他字节(比如年份、月份等),每个字节存储两个BCD数字(高4位和低4位各代表一个数字)。故数据提取思路如下:

  1. 将DT转换为字节数组,以便访问每个字节,使用AT指令实现;
  2. 对于星期数据,将#SystemTimeByte[7]与16#0F进行"与"运算;
  3. 具体原理:16#0F是十六进制数,转换为二进制是0000 1111,当用一个字节(8位)的数据和16#0F进行AND运算时,高4位会与0000相与,结果一定是0;低4位与1111相与,结果保持原来的值,故可以得到存储星期信息的低4位字节数据;
  4. 而对于其它数据,需要分别提取高4位和低4位,然后组合起来;
  5. 具体方法:对于每个字节,拆分为高4位和低4位,高4位定义为字节为0,低4位定义为字节1,分别提取字节0和字节1的低4位数据(与16#0F进行AND操作);
  6. 其中,高4位数据,使用"右移位"指令将其移至低4位,然后与16#0F进行AND操作;
  7. 最后,将字节0的低4位乘以10,加上字节1的低4位,得到实际的两位数数据;
  8. 注意:年数据只有年份信息,没有世纪信息,如果要加上世纪信息,需要进一步编程处理,具体方法见代码。

代码如下:

c 复制代码
REGION 提取年份
    
    // Date_And_Time只支持1990-2089年
    // 如果提取的两位数≥90:年份 = 1900 + 两位数
    // 如果提取的两位数<90:年份 = 2000 + 两位数
    
    #TempTens := (SHR(IN := #SystemTimeByte[0], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[0] AND 16#0F;
    #Year := (#TempTens * 10) + #TempOnes;
    
    IF #Year >= 90 THEN
        #Year := 1900 + #Year;
    ELSE
        #Year := 2000 + #Year;
    END_IF;
    
END_REGION

REGION 提取月份
    
    #TempTens := (SHR(IN := #SystemTimeByte[1], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[1] AND 16#0F;
    #Month := (#TempTens * 10) + #TempOnes;
    
END_REGION

REGION 提取日期
    
    #TempTens := (SHR(IN := #SystemTimeByte[2], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[2] AND 16#0F;
    #Day := (#TempTens * 10) + #TempOnes;
    
END_REGION

REGION 提取小时
    
    #TempTens := (SHR(IN := #SystemTimeByte[3], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[3] AND 16#0F;
    #Hour := (#TempTens * 10) + #TempOnes;
    
END_REGION

REGION 提取分钟
    
    #TempTens := (SHR(IN := #SystemTimeByte[4], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[4] AND 16#0F;
    #Minute := (#TempTens * 10) + #TempOnes;
    
END_REGION

REGION 提取秒钟
    
    #TempTens := (SHR(IN := #SystemTimeByte[5], N := 4)) AND 16#0F;
    #TempOnes := #SystemTimeByte[5] AND 16#0F;
    #Second := (#TempTens * 10) + #TempOnes;
    
END_REGION

REGION 提取星期
    
    // 星期信息存储在最后一个字节(即第 8 个字节,索引为 7)的低4位中
    // 1表示周日,2表示周一,...,7表示周六
    #Weekday := BYTE_TO_INT(#SystemTimeByte[7] AND 16#0F);
    
END_REGION

三、数据类型对比

特性 DTL Date_And_Time(DT)
适用版本 S7-1200/1500 新数据类 S7-300/400 传统类型
字节大小 12字节 8字节
时间精度 纳秒
日期范围 1-01-01 到 9999-12-31 1990-01-01 到 2089-12-31
存储方式 结构化数据 BCD编码的紧凑格式
兼容性 仅S7-1200/1500 S7-300/400/1200/1500

总的来说,DTL类型适用于:

  1. S7-1200/1500新项目;

  2. 需要高精度时间戳;

  3. 需要大范围日期(跨越世纪);

  4. 需要结构化访问日期时间各部分。
    Date_And_Time类型适用于:

  5. 兼容旧项目(S7-300/400);

  6. 与旧系统通信;

  7. 只需要秒级精度;

  8. 节省存储空间。


总结

本文主要对博途RD_LOC_T指令的使用方法进行了讲解,同时详细对比分析了DTL和Date_And_Time数据类型的优缺点。其中,Date_And_Time类型读取时间信息时涉及到的字节转换算法,需要格外注意。

相关推荐
leiming62 小时前
c++ string 容器
开发语言·c++·算法
wljun7393 小时前
六、OrcaSlicer 切片之区域
算法·切片软件 orcaslicer
2401_841495643 小时前
【LeetCode刷题】跳跃游戏Ⅱ
数据结构·python·算法·leetcode·数组·贪心策略·跳跃游戏
leaves falling3 小时前
动态规划讲解
算法·动态规划
钓鱼的肝3 小时前
GESP系列(3级)小杨的储蓄
开发语言·数据结构·c++·笔记·算法·gesp
MicroTech20253 小时前
MLGO微算法科技推出人工智能与量子计算融合新成果:基于QLSS与LCHS的量子DPM算法技术
人工智能·科技·算法
AndrewHZ4 小时前
【图像处理基石】[特殊字符]圣诞特辑:10+经典图像处理算法,让你的图片充满节日氛围感!
图像处理·人工智能·opencv·算法·计算机视觉·stable diffusion·节日氛围感
艾醒4 小时前
大模型原理剖析——矩阵吸收优化:LLM推理加速的核心原理与实践
算法
艾醒4 小时前
大模型原理剖析——多头并行 + 潜变量协同:原理、应用与部署优化
算法