简介:这份资源面向工业自动化领域的电气工程师、PLC编程人员及TIA博途初学者,聚焦触摸屏(HMI)与PLC之间日期时间不同步这一常见痛点,给出通过区域指针实现同步的完整方法示例。资源包内含1个docx文档,大小约723KB,以图文步骤形式组织内容,便于对照操作。文档围绕全局数据块中DTL变量与Int返回值的定义、RD_LOC_T时钟指令的调用、OB1中每秒周期刷新、HMI连接下全局区域指针的关联配置,以及日期与时间IO域的显示设置展开,并补充了PLC本地时间东八区设置与从PG/PC获取时间的校准思路。目前已有1030人学习下载,适合需要保证生产数据与报警事件时间记录准确可靠的读者参考,可帮助快速理解区域指针在时间同步中的实际用法与排错方向。
1. 区域指针做时间同步:为什么你的触摸屏总比PLC慢几秒
在 TIA 博途里做 HMI 与 PLC 的日期时间同步,很多人第一反应是写脚本、调系统函数,或者干脆让操作员每天手动改一次。但真正在一线跑过产线的人都知道,最稳的方案往往不是最复杂的那个——区域指针就是那个被低估的“后悔药”。它不需要额外授权,不依赖 HMI 脚本引擎,也不占用通讯负载,本质上是让 HMI 直接读写 PLC 里的一块数据区,把“同步”这件事变成一次普通的数据交换。
这个方案适合谁?适合那些 HMI 和 PLC 时间总差几分钟、报警记录时间戳对不上、配方切换时间错乱的现场。尤其是用精智面板或 Unified 面板配合 S7-1200/1500 的项目,区域指针几乎是零成本落地。但要注意:它同步的是“显示时间”和“PLC 内部时间”,不是把 HMI 的系统时钟改掉——这个区别决定了你后面所有配置的方向。先把这个逻辑立住,再动手,能省掉至少两轮返工。
2. 区域指针同步的底层逻辑:谁写谁、写什么、多久写一次
2.1 区域指针不是“通讯”,是“映射”
在 TIA 博途的 HMI 连接配置里,区域指针(Area Pointer)是一组预定义的数据区映射关系。你选一个功能(比如“日期/时间”),再指定 PLC 里一个地址,HMI 就会在运行时自动读写这个地址。它走的是 HMI 与 PLC 之间的既有通讯通道,不额外建立连接,也不需要在 PLC 侧写任何通讯指令。
关键点在于方向:对于日期/时间区域指针,默认是HMI 从 PLC 读取。也就是说,PLC 是时间源,HMI 是显示端。如果你反过来想让 HMI 写时间给 PLC,那得用“日期/时间(PLC)”这个区域指针,方向是 HMI 写入 PLC。很多现场翻车就翻在这里——选错了指针类型,结果两边时间各跑各的。
2.2 数据类型必须严格对齐
区域指针指向的 PLC 地址,数据类型不是随便定的。常见做法是使用DTL(日期和时间长度 12 字节)或DATE_AND_TIME(8 字节)。在 S7-1200/1500 里,DTL是更现代的选择,结构清晰,年、月、日、时、分、秒、毫秒、星期各占一个字节或字。
如果你在 PLC 里定义的是DTL,HMI 区域指针也必须选对应的DTL格式。混用DATE_AND_TIME和DTL不会报错,但读出来的时间会变成一堆乱码——这是最隐蔽的坑之一。我一般会在 PLC 里建一个全局 DB,专门放时间变量,命名成DB_TimeSync,里面就一个DTL类型的变量CurrentTime,干净利落。
2.3 同步周期与触发方式
区域指针的刷新周期跟 HMI 的采集周期绑定。默认是 1 秒,可以在“连接”属性里改。对于时间同步,1 秒足够——除非你做的是毫秒级事件记录,那得另想办法。注意:区域指针是周期性读写,不是事件触发。也就是说,HMI 每隔一个采集周期就去读一次 PLC 的时间,然后刷新显示。
如果你希望 HMI 主动把时间写给 PLC,比如操作员在 HMI 上改了时间,那需要配合一个触发位。常见做法是:HMI 上放一个“同步”按钮,按下时置位一个 PLC 变量,PLC 检测到上升沿后把 HMI 写入的时间值复制到系统时间。但这一步已经超出区域指针本身的范围了,属于应用层逻辑。
3. 在 TIA 博途中一步步配置日期时间同步
3.1 先在 PLC 侧建好时间数据块
打开 TIA 博途,在项目树里找到 PLC,右键“添加新块”,选“数据块(DB)”,命名为DB_TimeSync。在 DB 里新建一个变量,名称CurrentTime,数据类型选DTL。取消“优化的块访问”勾选,这样你才能看到绝对地址。假设这个 DB 的起始地址是DB100,那么CurrentTime的偏移量就是0.0,绝对地址写作DB100.DBB0开始,共 12 个字节。
// 在 PLC 的 OB1 或循环中断 OB 里,把系统时间写入 DB // 假设使用 S7-1500,系统时间存储在 CPU 属性里 // 这里用 RD_SYS_T 指令读取系统时间 RD_SYS_T OUT => "DB_TimeSync".CurrentTime这段逻辑的意思是:每个扫描周期,把 CPU 的系统时间读出来,写进DB_TimeSync.CurrentTime。RD_SYS_T是读取系统时间的标准指令,输出就是DTL格式。注意:如果你在 OB1 里调用,刷新频率就是扫描周期,可能太快;更稳妥的做法是放在一个 1 秒的循环中断 OB 里,比如 OB30,这样时间更新节奏稳定。
3.2 HMI 连接里挂上区域指针
切换到 HMI 设备,打开“连接”配置,找到与 PLC 的通讯连接。在“区域指针”选项卡里,找到“日期/时间”这一行。在“PLC 地址”列,填入DB100.DBB0或者直接选DB_TimeSync.CurrentTime。数据类型选DTL。采集周期保持 1 秒。
// 这不是代码,是 HMI 区域指针配置的等效描述 // 区域指针类型:日期/时间 // PLC 地址:DB100.DBB0 // 数据类型:DTL // 采集周期:1s配置完成后,HMI 运行时会自动从DB100.DBB0读取 12 个字节,解析成日期时间并刷新所有绑定了“日期/时间”变量的控件。你不需要在 HMI 画面上做任何额外绑定——区域指针是全局生效的。只要画面上有“日期/时间”控件,它就会自动显示 PLC 的时间。
3.3 验证同步是否生效
下载 PLC 和 HMI 程序,进入在线。在 PLC 的监控表里添加DB_TimeSync.CurrentTime,观察它是否在每秒变化。然后在 HMI 画面上放一个“日期/时间”控件,看显示值是否与 PLC 监控表一致。如果一致,说明区域指针配置正确。
如果不一致,先检查三件事:第一,PLC 地址是否写对,特别是 DB 号;第二,数据类型是否两边都是DTL;第三,HMI 连接是否真的在线。我遇到过一种情况:HMI 连接配置里区域指针填了地址,但连接本身是“未激活”状态,结果时间一直停在编译时的默认值。这种问题在编译日志里不会报错,只能在线看。
3.4 让 HMI 反向写时间给 PLC
如果你需要操作员在 HMI 上修改时间并同步回 PLC,那就不能用“日期/时间”区域指针了,得用“日期/时间(PLC)”。这个指针的方向是 HMI 写入 PLC。配置方式类似,但 PLC 地址指向同一个DB_TimeSync.CurrentTime。然后在 HMI 画面上放一个“日期/时间”输入控件,绑定到这个区域指针。
// PLC 侧需要加一段逻辑:检测 HMI 写入的时间并同步到系统 // 使用 WR_SYS_T 指令把 DTL 值写回 CPU 系统时间 WR_SYS_T IN => "DB_TimeSync".CurrentTime注意:WR_SYS_T会直接修改 CPU 的系统时间,影响所有依赖系统时间的逻辑。如果产线上有基于时间的联锁或记录,改时间前一定要确认没有副作用。我一般会加一个权限等级,只有工程师级别才能操作这个按钮。
4. 避坑指南:时间同步最常见的 5 个翻车现场
4.1 现象:HMI 时间比 PLC 慢 8 小时
原因:时区偏移。PLC 的RD_SYS_T读出来的是 UTC 时间,而 HMI 显示时可能按本地时区转换了,也可能没转换。如果 PLC 在属性里设置了时区,而 HMI 没有对应设置,就会差出时区偏移量。
解决:在 PLC 的 CPU 属性里,把“时间”设置为本地时间,或者统一用 UTC 并在 HMI 侧做偏移。最稳的做法是两边都用 UTC,HMI 画面上加一个时区偏移变量,显示时手动加 8 小时。虽然土,但不会错。
4.2 现象:时间显示为 1990-01-01 或乱码
原因:数据类型不匹配。PLC 里是DTL,HMI 区域指针选了DATE_AND_TIME,或者反过来。DTL是 12 字节,DATE_AND_TIME是 8 字节,读出来的字节序完全对不上。
解决:统一用DTL。在 HMI 区域指针配置里,数据类型下拉框一定要选DTL。如果找不到DTL选项,说明 HMI 固件版本太老,升级或改用DATE_AND_TIME并确保 PLC 侧也是这个类型。
4.3 现象:时间偶尔跳变或回退
原因:PLC 程序里多处写同一个 DB 变量。比如 OB1 里调了RD_SYS_T,OB30 里又调了一次,两个周期不一致,导致 HMI 读到的值在两次写入之间跳变。
解决:只在一个地方写DB_TimeSync.CurrentTime。我一般固定在 1 秒循环中断里写,其他任何地方都不碰这个变量。如果需要在别处用时间,直接读这个 DB,不要另建时间源。
4.4 现象:HMI 上改了时间,PLC 没反应
原因:区域指针方向选错。用了“日期/时间”而不是“日期/时间(PLC)”。前者是只读,HMI 写不进去。
解决:检查区域指针类型。如果是写入方向,必须选带“(PLC)”后缀的那个。另外,HMI 输入控件的“输入完成”事件要触发一个写操作,有些面板需要手动触发,不会自动写。
4.5 现象:编译报错“区域指针地址无效”
原因:PLC 地址填了符号名而不是绝对地址,或者 DB 被优化了导致找不到偏移量。
解决:取消 DB 的“优化的块访问”,用绝对地址DB100.DBB0。如果坚持用符号名,确保 HMI 能访问该 DB,且 DB 不是“仅符号访问”模式。我一般直接填绝对地址,省去符号解析的麻烦。
5. 进阶技巧:用区域指针做时间戳对齐与报警记录
5.1 让报警记录的时间戳与 PLC 一致
HMI 的报警记录默认用 HMI 自己的系统时间。如果你已经用区域指针同步了显示时间,但报警记录还是用 HMI 本地时间,那记录里的时间戳会和画面上显示的时间差几秒。解决方法是:在 HMI 的“报警设置”里,把“时间源”改为“PLC”。这样报警触发时,HMI 会去读 PLC 的时间作为时间戳。
具体路径:HMI 设备属性 → 报警设置 → 时间源 → 选“PLC”。前提是区域指针已经配好“日期/时间”。改完之后,所有新产生的报警记录都会带 PLC 时间戳,和历史记录对齐。
5.2 用 DTL 的星期字节做排班逻辑
DTL的第 8 个字节是星期,1 到 7 对应周一到周日。你可以直接在 PLC 里读这个字节,做排班或定时任务。比如:
// 假设 CurrentTime 是 DTL 类型 // 读取星期字节,判断是否周末 // DTL 结构:年(2字节) 月(1) 日(1) 时(1) 分(1) 秒(1) 毫秒(4) 星期(1) // 星期字节偏移量为 11 L "DB_TimeSync".CurrentTime.Weekday L 6 >=I = "DB_TimeSync".IsWeekend这段逻辑的意思是:把DTL里的星期字节读出来,如果大于等于 6(周六或周日),就置位IsWeekend。注意DTL的星期字节是从 1 开始的,1 是周一,7 是周日。这个技巧在需要按工作日/周末切换配方或报警阈值的场景里很实用。
5.3 同步失败时的降级策略
如果区域指针因为通讯中断读不到时间,HMI 会保持最后一次有效值,不会跳回默认时间。但如果你希望通讯恢复后自动重新同步,可以在 HMI 的“连接”属性里勾选“重新建立连接后更新区域指针”。这个选项默认是开的,但有些老版本固件会关掉。检查一下,能省掉一次手动重启。
另外,我习惯在 PLC 里加一个心跳计数器,每秒加一,HMI 侧用脚本判断这个计数器是否在变。如果超过 3 秒没变,就在画面上显示“时间同步异常”。这个逻辑不复杂,但能让操作员第一时间知道时间不可信,而不是等到报警记录对不上才发现。
5.4 一个我踩过的坑:不要用区域指针同步“系统时钟”
区域指针同步的是数据区,不是 HMI 的操作系统时钟。也就是说,HMI 右下角那个系统时间不会变。如果你有第三方软件或脚本依赖 HMI 系统时间,区域指针帮不了你。这种情况只能写脚本调系统 API,但那个方案在精智面板上限制很多,不推荐。
我的习惯是:所有时间相关的显示、记录、判断,全部走 PLC 时间。HMI 只做展示和输入,不做时间逻辑。这样整个系统只有一个时间源,不会出现“两个时间”的玄学问题。希望帮到你。
本文还有配套的精品资源,点击获取