300_400PLC的DATE_AND_TIME类型(DT)
设置时间日期
- 在编辑器页面,选择
PLC
,选择Set Time of Day
,可以把PC的时间同步给PLC。(除了此方法外,也可以在硬件组态界面把时间同步给PLC;或者通过SFC0分配系统时间给PLC。)
从OB1获取Date_And_Time
- 如下,OB1的临时变量
P#L12.0 BYTE 8
可以获得时间日期:
直接用DATE_AND_TIME类型和用基础类型获得时间日期的区别
- 在共享DB里面建立一个名为“loc_data_time”的变量,变量类型为“DATE_AND_TIME”,发现该变量占字节数为8。
- 建立一个UDT,内容为时间日期格式的拆分,总占用字节数也为8(此处不需要用到“星期”,需要用到“星期”的话占用字节数则为9)。
- 分别把OB1中的临时变量分配给共享DB里的两个类型,程序如下:
//GET DATA AND TIME BY DT FORMAT
L P##OB1_DATE_TIME
LAR1
L D [AR1,P#0.0]
T DB1001.DBD 0
L D [AR1,P#4.0]
T DB1001.DBD 4
//GET DATA AND TIME BY UDT
L P##OB1_DATE_TIME
LAR1
L B [AR1,P#0.0]
BTI
T "_GlobalRecordsDB".loc_dt.year
L B [AR1,P#1.0]
BTI
T "_GlobalRecordsDB".loc_dt.month
L B [AR1,P#2.0]
BTI
T "_GlobalRecordsDB".loc_dt.day
L B [AR1,P#3.0]
BTI
T "_GlobalRecordsDB".loc_dt.hour
L B [AR1,P#4.0]
BTI
T "_GlobalRecordsDB".loc_dt.minute
L B [AR1,P#5.0]
BTI
T "_GlobalRecordsDB".loc_dt.second
L W [AR1,P#6.0]
SRW 4
BTI
T "_GlobalRecordsDB".loc_dt.Millisecond
- 在线监控程序如下:
- 从共享DB处监控的在线数据如下:
- 把"P#DB1001.DBX0.0 BYTE 8"拆分成基本数据类型,在监控表中在线监控。如下:
- 结论:
- 通过上述在线值对比,发现监控复杂数据类型如DATE_AND_TIME时,监控不能被抓取到,但是当把该复杂数据类型拆分成基本数据类型监控时,数据监控状态则变为正常状态。
- 用UDT手动建立的时间日期则可以完全自由的显示。
虽然本人暂时也没探明白为什么会出现这样的现象,但总结出一点:在300和400PLC使用上,显示时间日期格式时尽量自己组合。这类问题在1200和1500上不存在(在博图的加持下,1200/1500可以直接使用DTL格式)。
DATE_AND_TIME类型上一些其他的细节
BTI
是什么意思,为什么要把BCD码转成int数:
如图,左边是
BTI
转换后的在线值,右边是直接获取的在线值。区别在于如果不经过BTI转换,显示的16进制数值内容直观的反映成时间日期“2502241440..”;转换后需要把该16进制数变成10进制数,数值内容才会和“2502241440..”一致。
- 星期如何得到:
如果需要得到星期,最好单独用一个BYTE来存星期信息。(即原来的8Byte在解析时存为9Byte)。
- 为什么不可以直接把"#OB1_DATE_TIME"赋值给一个"DATE_AND_TIME"类型:
L
是把一个数存入ACCU1,最多存储长度是32位,当放入一个复杂类型(大于32位),当然会出错。T
同理。
不管是STL,还是LAD(使用MOV指令),这种现象都是存在的。甚至在这里使用BLKMOV
都不行,因为source和Target都不是Any
类型的。这种情况在1200/1500上得到了好转,因为Variant
类型的出现才使得真正的引用(引用本身不占内存)成为现实。