工控领域PLC时间转换为UNIX时间做网络同步比较
昌晖
455浏览
0评论
0点赞
2023-01-05
最近在安全行业里做读取PLC内部故障事件分析的工作,发现在PLC网络里采用NTP时间同步基本上没有,因为在工控领域PLC更多承担业务层面控制需求的实现,反而对于PLC本身的安全并没有过多的重视。
多区域内PLC时间同步就是安全设置的必要一步,因为这个会涉及PLC内部的事件和记录是否能够按照真实的时间进行提取和分析。那在不同网段读取不同厂商PLC时间进行比较和同步就成为一个比较麻烦的事情。不同厂商PLC的日期和时间比较需要用到一个INT数组数据来比较。所以才有了这需求打算采用Unix 时间来做时间对比,因为所有厂商的PLC的日期和时间都可以转成Unix时间。
什么是Unix时间?
Unix时间(英文为Unix epoch, Unix time, POSIX time或Unix timestamp)是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。UNIX时间的0按照ISO 8601规范为:1970-01-01T00:00:00Z。一个小时表示为UNIX时间格式为:3600秒;一天表示为UNIX时间为86400秒,闰秒不计算。
时间 秒
1分钟 60秒
1小时 3600秒
1天 86400秒
1周 604800秒
1月(30.44天) 2629743秒
1年(365.24天) 31556926 秒
下面将采用结构化文本的形式来开发这个PLC时间转成Unix时间,为了方便大家在其他的PLC中实现时间格式的转换。
// Convert system time to unix time
// (seconds until 1970-01-01 00:00)
// Create by jiansiting
FUNCTION Unixtime : DWORD
VAR_INPUT
END_VAR
VAR_TEMP
leapyears:INT;
days_from_1970 : DINT;
days_from_BeginOfYear : ARRAY[1..12] OF INT;
l_unixtime:DINT;
sfc1_ret_val:INT;
CDT_systemtime:DATE_AND_TIME;
systemtime AT CDT_systemtime : STRUCT
year_CDT:BYTE; // 1970 ... 2038
month_CDT:BYTE;
day_CDT:BYTE;
hour_CDT:BYTE;
minute_CDT:BYTE;
second_CDT:BYTE;
END_STRUCT;
year:INT; // 1970 ... 2038
month:INT;
day:INT;
hour:INT;
minute:INT;
second:INT;
END_VAR
leapyears:= 0;
days_from_1970 := 0;
// days of current month without leap day
days_from_BeginOfYear[1] := 0;
days_from_BeginOfYear[2] := 31;
days_from_BeginOfYear[3] := 59;
days_from_BeginOfYear[4] := 90;
days_from_BeginOfYear[5] := 120;
days_from_BeginOfYear[6] := 151;
days_from_BeginOfYear[7] := 181;
days_from_BeginOfYear[8] := 212;
days_from_BeginOfYear[9] := 243;
days_from_BeginOfYear[10] := 273;
days_from_BeginOfYear[11] := 304;
days_from_BeginOfYear[12] := 334;
// read system time
sfc1_ret_val:= READ_CLK(CDT := CDT_systemtime);
year:= BCD_TO_INT(systemtime.year_CDT) + 2000;
month:= BCD_TO_INT(systemtime.month_CDT);
day:= BCD_TO_INT(systemtime.day_CDT);
hour:= BCD_TO_INT(systemtime.hour_CDT);
minute:= BCD_TO_INT(systemtime.minute_CDT);
second:= BCD_TO_INT(systemtime.second_CDT);
// sum of leap years since 1979 (without current leap year)
leapyears := ((year-1)-1968)/4-((year-1)-1900)/100+((year-1)-1600)/400;
days_from_1970 := (year-1970)*365 + leapyears+ days_from_BeginOfYear[month] + day-1;
IF ( (month > 2) AND ((year MOD 4 = 0) AND ((year MOD 100 <> 0) OR (year MOD 400 = 0))) ) THEN
days_from_1970 := days_from_1970 + 1; // + leap day, if year is leap year
END_IF;
// OUTPUT in s
l_unixtime := second + 60 * ( minute + 60 * (hour + 24 * days_from_1970) );
// if error return 0
IF sfc1_ret_val <> 0 THEN
Unixtime := 0;
ELSE
Unixtime := DINT_TO_DWORD(l_unixtime);
END_IF;
END_FUNCTION
作者:剑思庭
声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
-
15年以上测试经验资深专家实操、案例演示、经验分享。吸波材料、绝缘材料、天线、微波和射频元器件材料等介电常数精确测量。参会赢丰厚礼品:Encok蓝牙耳机、HD3乐高、飞利浦电动牙刷、几何计数无绳跳绳、芒米雨伞、IPAD平板包、10周年冰箱贴等
- 相关技术文库
- FPGA
- 可编程
- PLC
- verilog
-
什么是模块化设计FPGA/IC设计中根据模块层次的不同有两种基本的设计方法:自下而上方法对设计进行逐次划分的过
-
在电工领域摸爬滚打了20年的你,是否也曾对控制柜里的设计感到困惑不解?
-
-
-
-
1、介绍\x26amp;nbsp; \x26amp;nbsp; \x26amp;nbsp;IBUFDS原语、OBUFDS原语以及IOBUFDS都是
-
-
一、Intel CvP 简介CvP(Configuration via Protocol)是一种通过协议实现配置的方案, Arria® V,Cyclone® V,Stratix® V,Arria® 10,Cyclone® 10 GX,Stratix® 10,Agilex™都支持这个功...
-
1、综合读写模块(无FIFO)\x26amp;nbsp; \x26amp;nbsp; \x26amp;nbsp;在前六篇SDRAM系列博文中,我们对S
-
-
本文将使用 ADI 最新的 AD9094-1000EBZ 和 Intel 的 FPGA Arria10 gx Development Kit,搭建基于 10G 的 JESD204B 测试环境。重点阐述如何搭建演示系统,相关的测试demo使用教程,以及相关...
-