汇川H5U ST语言编程实战:从梯形图到结构化文本的7步进阶
2026/9/24 11:51:24 网站建设 项目流程

搞工控这些年,我最大的体会是:PLC编程的门槛从来不在“会不会写”,而在“能不能用工程思维把逻辑理清楚”。尤其是当你从梯形图转向ST语言(Structured Text,结构化文本)时,很多人会觉得不习惯,但一旦上手,就会发现ST在处理复杂算法、数据处理和结构化程序时,效率比梯形图高出一大截。

汇川H5U作为一款内置EtherCAT总线、支持CODESYS内核的中型PLC,在中小型自动化设备里用得越来越多。它的编程软件InoProShop基于CODESYS V3.5开发,支持ST、梯形图、功能块图等多种编程语言,其中最值得花时间的就是ST语言。它不仅能写逻辑,还能做数学运算、数组处理、协议解析,甚至能写自定义功能块,大大提升代码复用率。

这篇我就以自己的实际项目经验为线索,把汇川H5U的ST语言编程拆成7个步骤,从建工程到跑通一个完整的运动控制例程,每一步都讲清楚“为什么要这么做”和“实际踩过的坑”。不管你是刚接触PLC的新手,还是从三菱、西门子转过来的老手,这篇都适合。

1. 内容整体设计与思路拆解

1.1 为什么选H5U做ST语言入门

很多人问我,学ST语言为什么不直接学西门子博途,或者用CODESYS?我的回答是:H5U是一个性价比极高的入门载体。

第一,H5U硬件成本低。一台H5U-1614MTD(16点输入14点晶体管输出)的价格只有同级别西门子CPU的一半左右,但性能并不差,内置EtherCAT主站可以带32个轴,常规的伺服控制、脉冲控制、模拟量采集都能做。第二,InoProShop的ST编辑体验做得不错,有自动提示、变量交叉引用、在线监控,调试起来很直观,对新手非常友好。第三,H5U的资料和案例在国内工控圈里已经积累了很多,遇到问题容易搜到答案。

但更重要的是,ST语言本身是IEC 61131-3标准里的文本化编程语言,语法结构类似Pascal/C,学会了H5U的ST,切到汇川Easy系列、InoProShop支持的CODESYS平台,甚至西门子的SCL语言,上手成本都很低。也就是说,你花时间学的不只是H5U这一台设备,而是一套可以迁移的编程思维。

1.2 7步路线的学习逻辑

我把H5U的ST语言学习分成7步,每一步解决一个核心问题:

  1. 建工程、认识软件与ST编辑器。
  2. 理解变量类型与声明方式——这是ST的“词汇表”。
  3. 写第一条ST程序(启保停逻辑)——理解扫描周期与赋值顺序。
  4. 用IF/CASE做条件分支——这是所有设备逻辑的地基。
  5. 数据运算与转换——模拟量采集与工程量换算。
  6. 功能块封装与调用——让代码从“能跑”变成“好用”。
  7. 结合EtherCAT总线写一个完整的运动控制例程——把前面所有知识串起来。

这个路线的设计逻辑是:先建立工程概念,再掌握语法基础,然后通过小案例理解执行机制,最后直接上手一个接近实际项目的综合例程。每一步都有明确的输出物,学完就能看到自己的进步。

2. 核心细节解析与实操要点

2.1 建工程时容易忽略的几个设置

在InoProShop里新建H5U工程时,有几步关键配置直接影响后续开发:

  • 设备选型:必须选择与硬件一致的CPU型号,比如H5U-1614MTD或H5U-3214MTD,选错了会导致某些指令不可用或IO映射错乱。
  • PLC设置:H5U支持本地IO和远程EtherCAT从站,默认勾选本地IO。如果你的设备要用EtherCAT伺服,需要先在“EtherCAT配置”里扫描从站,再生成网络配置。
  • 编程语言选择:新建程序组织单元(POU)时,语言类型选择“结构化文本”(ST)。一个工程里可以混合使用梯形图和ST,但建议逻辑部分统一用ST,维护起来更清晰。
  • 扫描周期设置:默认任务周期是1ms,如果程序里做了大量浮点运算或通讯解析,建议把周期调整到2ms或5ms,避免任务超时报警。

建好工程后,强烈建议先编译一次空工程,确认软件环境和目标配置没问题,再开始写代码。这个习惯能帮你区分“软件报错”和“程序报错”,避免后面排查问题时分不清方向。

2.2 变量声明是ST语言的第一个分水岭

H5U的ST变量分三类:局部变量、全局变量和IO映射变量。很多人初学者写ST程序直接拿常量去比较、直接给输出点赋值,这在简单Demo里没问题,但一旦程序复杂起来,维护就是灾难。

我在实际项目里养成了一套自己的变量命名习惯:

  • 输入信号前缀di_(Digital Input),比如di_StartBtn
  • 输出信号前缀do_(Digital Output),比如do_MainContactor
  • 模拟量输入用ai_,模拟量输出用ao_
  • 内部中间变量用b_(Bool)或r_(Real),比如b_IsRunningr_TargetSpeed

变量类型的选用也很关键。H5U的ST支持BOOLINTDINTREALSTRINGARRAYSTRUCT等。初学者最常见的坑是:用INT存伺服位置,结果发现数值只能到32767,导致轴走到一半就报错。位置、计数这类变量,一律用DINT(32位整数)。浮点运算用REAL,但注意REAL是32位,精度有限,做高精度计算建议用LREAL

提示:ST语言里变量名大小写不敏感,但InoProShop会自动把变量名规范为首字母大写。建议写代码时统一小写加下划线风格,和工程文件命名保持一致。

2.3 扫描周期与赋值顺序的理解

ST程序的执行方式是“从上到下、从左到右”顺序扫描,在一个扫描周期内,前面的赋值结果立即影响后面的语句。这和梯形图的“左母线到右母线”逻辑本质上一致,但ST更直观,因为它就是代码。

举个经典例子,启保停逻辑:

do_MainContactor := (di_StartBtn OR do_MainContactor) AND NOT di_StopBtn;

这一行就实现了“启动优先、停止优先”的电机控制逻辑。如果换成梯形图,需要三行。但ST的坑在于:如果顺序写反了,比如先给do_MainContactor赋值,再读取它做运算,得到的结果就是上一次扫描周期的值。这在一些需要记忆功能的场合会出现“慢半拍”的问题。

解决办法有两种:一是严格在同一段逻辑里保持“先读后写”的顺序;二是用临时变量暂存,在程序末尾统一刷新输出。我写运动控制程序时,习惯把所有输出点的赋值集中在程序段末尾,这样既好查,也避免了扫描顺序带来的随机性。

2.4 任务周期与程序结构的匹配

H5U的程序任务可以是周期任务或事件任务。控制逻辑(伺服使能、运动指令)建议放在1ms或2ms的周期任务里,保证实时性;数据处理(模拟量滤波、通讯报文解析)可以放在10ms或50ms的任务里,减轻CPU负载。

InoProShop里新建任务时,需要指定调用哪个POU。我的习惯是:主程序Main放在周期任务里,子功能块在Main里通过ST指令调用,不把任务配置搞得太复杂。实际项目中,很多奇怪的“偶发故障”都是任务周期配置不合理造成的,比如在1ms任务里做了大量字符串处理,导致任务超时,CPU报错停机。

3. 实操过程与核心环节实现

3.1 第一条ST程序:启保停逻辑

打开InoProShop,新建工程,在“程序”下新建一个POU命名为Main,语言选ST,然后写这段代码:

// 电机启保停控制 b_StartCmd := di_StartBtn; b_StopCmd := di_StopBtn; IF b_StartCmd AND NOT b_StopCmd THEN do_Motor := TRUE; ELSIF b_StopCmd THEN do_Motor := FALSE; END_IF;

下载到PLC后,用导线短接di_StartBtn对应的输入端子,观察do_Motor输出点是否导通。如果没反应,先查输入点有没有接对,再看PLC是否处于运行状态(RUN灯是否常亮)。

这里要解释一下为什么用IF...ELSIF...END_IF而不是直接把di_StartBtn塞进赋值语句。实际场景里,启动条件往往不是单一按钮,而是“按钮+前门关闭+气压正常+急停未触发”的串并联组合。用IF结构可以在条件分支里任意扩展,可读性和可维护性比一行嵌套赋值好得多。

3.2 IF/CASE状态机:自动加工流程

设备里最常见的逻辑就是状态机:待机、启动、加工、完成、报警。ST语言做状态机是降维打击。比如一个简易的自动剪切流程:

CASE b_Step OF 0: // 待机,等待启动信号 IF di_Start THEN b_Step := 10; END_IF; 10: // 夹紧 do_Clamp := TRUE; IF di_ClampDone THEN b_Step := 20; END_IF; 20: // 剪切 do_Cut := TRUE; IF di_CutDone THEN b_Step := 30; END_IF; 30: // 完成,松开 do_Clamp := FALSE; do_Cut := FALSE; b_Step := 0; END_CASE;

注意CASE的步进值b_Step一定要初始化为0,而且每个分支结束前必须赋下一个状态值。如果某一步的条件永远不满足,程序就会卡在当前步。排查时用InoProShop的在线监控功能,直接看b_Step当前停在哪里,就能快速锁定问题。

我踩过一次坑:在状态10里同时给do_Clamp赋值TRUE,又在状态30里把它复位FALSE,但中间某个报警分支退出时忘了复位,导致设备即使停机了夹爪还扣着。后来我在每个状态进入时统一复位该状态下不需要的输出,才彻底解决。

3.3 数据运算:模拟量采集与工程量换算

ST的数值计算能力是梯形图无法比拟的。实际项目中,最常见的需求是读取温度传感器、压力变送器的4~20mA信号,换算成实际工程量。

假设你用H5U本地模拟量模块采集0~10V电压信号,模块分辨率是16位(0~27648),传感器量程是0~100摄氏度:

r_Raw := INT_TO_REAL(ai_TempRaw); // 原始值转浮点 r_Engineering := r_Raw / 27648.0 * 100.0; // 工程量换算

如果要做滤波,可以加一个一阶低通滤波:

r_Filtered := r_Filtered + (r_Engineering - r_Filtered) * 0.1;

这个低通滤波的系数0.1表示每次采样吸收10%的新值,系数越小滤波越强、响应越慢。我在实际项目里试过,采样周期1ms、系数0.05~0.1时,既能有效滤掉高频干扰,又不会让温度显示滞后太多。

ST语言的类型转换要特别留意。H5U不会自动做隐式类型转换,INTREAL直接运算会报错。刚开始写程序时,编译报错有一半是类型不匹配造成的。我的习惯是:统一用LREAL做浮点运算,整数类型只在计数器和索引场景使用,减少转换次数。

3.4 功能块封装:把重复代码变成库

当程序里有两台伺服、三台气缸需要做相同的动作时,复制粘贴是最差的办法。正确做法是写一个功能块(FB),实例化多次。

举个例子,做一个气缸控制功能块:

FUNCTION_BLOCK FB_Cylinder VAR_INPUT b_ExtendCmd : BOOL; // 伸出指令 b_RetractCmd : BOOL; // 缩回指令 END_VAR VAR_OUTPUT b_ExtendOut : BOOL; // 控制伸出电磁阀 b_RetractOut : BOOL; // 控制缩回电磁阀 b_InPos : BOOL; // 到位信号 END_VAR VAR b_State : INT; // 内部状态 END_VAR

然后在主程序里实例化:

FB_Cyl_A(b_ExtendCmd := di_CylAExtend, b_RetractCmd := di_CylARetract, b_ExtendOut := do_CylAExtend, b_RetractOut := do_CylARetract, b_InPos := di_CylAInPos);

这样写的好处是:气缸的电磁阀控制逻辑(比如伸出到位自动关阀,防止线圈长时间通电发热)只需要写一次,后面所有气缸都用同一个功能块。需要修改报警逻辑时,只改功能块内部,全设备生效。

H5U的InoProShop里还能把功能块导出成库文件,下次做同类设备直接引用,开发效率翻倍。我自己的工控部件库就是这么一点点积累起来的。

3.5 结合EtherCAT总线:一个完整的伺服运动控制例程

H5U内置EtherCAT主站,配置汇川SV660N伺服的过程是:在InoProShop里双击“EtherCAT”,扫描从站,自动识别伺服,然后分配站号;接着在伺服对象字典里配置运行模式(位置模式、速度模式、转矩模式),把目标位置、目标速度、控制字等映射到PLC的IO变量;最后在程序里通过轴控指令驱动。

以位置控制为例,ST里写:

// 伺服使能 do_ServoEnable := TRUE; // 绝对定位:目标位置10000脉冲,速度5000脉冲/秒 H5U_SetAbsPos_Axis0(TRUE, 10000, 5000, 0, 1000);

H5U_SetAbsPos是InoProShop提供的轴控功能块,参数含义是:脉冲数、速度、加减速时间、等待时间。使用前必须先在EtherCAT配置里建立好轴,并确认轴状态为“Standstill”(静止)或“Disabled”(未使能),否则指令不会执行。

这里有一个非常容易踩的坑:EtherCAT通讯建立需要几十到几百毫秒。程序刚上电时,如果立刻发使能和定位指令,伺服往往没反应。我的习惯是在程序中加一个延时判断:

b_EthercatReady := H5U_EtherCAT_GetStatus() = 0; // 总线状态正常 IF b_EthercatReady AND NOT b_ServoInitDone THEN // 延时500ms后使能 IF TON_ServoEnable.Q THEN do_ServoEnable := TRUE; END_IF; END_IF;

实际调试中,运动控制类的故障有一半以上和时序有关,不是逻辑错了,而是“指令发得太早”。

3.6 ST与梯形图混用时的边界

H5U允许在同一个工程里混用ST和梯形图,但混用时要清楚它们的执行顺序。我一般遵循两条原则:

第一,逻辑控制用ST,视HMI动画类简单逻辑可放梯形图,但不要倒过来。ST的代码在复杂逻辑下可读性和可维护性远胜梯形图。

第二,全局变量尽量少用。无论是ST还是梯形图,都通过POU的输入输出接口传参,避免全局变量满天飞。我在一个项目里见过200多个全局变量,查一个问题需要打开十几个页面,极其痛苦。

3.7 在线调试与监控的技巧

InoProShop里的在线监控支持ST变量的实时数值显示。调试时,我会配合“写入”(强制赋值)功能给变量强制值,测试不同逻辑分支是否正常。

常用操作:右键变量,选“写入”,输入一个值,按回车。注意强制复位输出点时要确认设备处于安全状态,特别是气缸、伺服这类执行机构,强制输出可能导致设备突然动作,非常危险。我的习惯是:先断了气源和伺服使能,再强制输出。

另外,ST程序里设置的断点功能也很有用。H5U支持在ST代码行上打断点,在线运行时会停在断点处,可以单步执行查看每个变量的变化。排查复杂状态机问题,用断点比看监控数值方便得多。

4. 常见问题与排查技巧实录

4.1 编译报错集中在哪几类

ST编程的报错绝大多数集中在三类:类型不匹配、变量未声明、语法错误。

  • 类型不匹配:比如把BOOL赋值给INT,把INTREAL直接相加。解决办法是显式转换,比如INT_TO_REAL()
  • 变量未声明:检查变量名是否拼写一致,InoProShop的变量名区分大小写不敏感,但下划线和拼写必须完全一致。
  • 语法错误:最常见的是IF忘记END_IFCASE忘记END_CASE,或者分号漏写。ST的语句以分号结尾,漏一个分号编译到下一行才报错,排查时先看报错行上方最近的几行。

4.2 PLC不通信、下载不进去怎么办

H5U网口调试时,最常见的故障是电脑IP和PLC IP不在同一网段。H5U默认IP通常为192.168.1.6(不同批次可能有差异),电脑网卡需要设成同网段,比如192.168.1.10。InoProShop右下角的通讯状态会显示是否连接成功。

如果IP对不上又不知道PLC地址,可以通过InoProShop的“搜索设备”功能扫描同网段设备。另外,用网线直连时要注意,有些电脑的网卡会自动切换成“未识别网络”,需要在Windows网卡设置里手动指定IP。

注意:下载程序到运行中的PLC会停机,务必确认设备处于安全状态再下载。

4.3 输出点不动作的排查顺序

ST程序里明明写了do_Motor := TRUE,但输出点没电。排查顺序是:先看PLC的RUN灯是否常亮(程序是否在运行),再看在线监控里do_Motor是否为TRUE,再查输出点接线和负载电源。很多时候是模块接线端子没压紧,或者负载电源没开,而不是程序问题。经验法则:程序问题用在线监控查,硬件问题用万用表量,两者不能混为一谈。

4.4 程序跑飞或者卡死的原因

ST程序本身不会“跑飞”,但存在死循环的逻辑风险。比如WHILE循环条件永远为TRUE,程序就会卡在循环里,后续逻辑全部停摆。H5U的ST里要慎用WHILE,如果非用不可,一定要有循环次数的上限保护。

i_Count := 0; WHILE b_Find AND i_Count < 1000 DO // 查找逻辑 i_Count := i_Count + 1; END_WHILE;

另外,数组越界也会导致程序异常。H5U对数组越界的处理是运行时报错,程序跳转到异常状态。所以数组索引计算时,务必加边界判断,比如:

IF i_Index >= 0 AND i_Index < 10 THEN r_Value := arr_Data[i_Index]; END_IF;

4.5 伺服轴不使能或定位不准

EtherCAT伺服最常见的坑是电子齿轮比设置错误。SV660N的电子齿轮比由Pn202Pn203参数决定(分子分母),如果设置不合理,一条定位指令发过去,实际走的距离和预期差距很大。解决办法是:在伺服调试软件里先手动点动,确认一圈脉冲数,再在PLC侧换算成实际位移单位。

定位不准的另一个常见原因是加减速时间设置过短,导致伺服过冲或跟踪误差过大报警。我的经验是:负载惯量比较大的场合,加减速时间不要小于500ms,速度曲线选择S型曲线而不是梯形曲线,能有效减少机械冲击。

5. 从能跑到好用:我的几点实在体会

做H5U的ST语言编程,最有意思的地方不是学会语法,而是你会发现编程思维变了。以前用梯形图,脑子里想的是“怎么把继电器电路翻译成逻辑图”,用了ST以后,精力集中在“工艺逻辑到底该怎么拆解”,这才是工程师的核心价值。

走完这7步之后,我还建议你做几件事:一是把常用逻辑(气缸控制、启停保护、报警复位)封装成自己的功能块库,以后做项目直接调用;二是找一台带EtherCAT伺服的设备,完整走一遍“总线配置—程序编写—带载调试”的流程,比看十篇教程都管用;三是养成随时备份代码的习惯,H5U的工程文件可以导出为.zip,我见过不少工程师电脑硬盘损坏后全部代码丢失的惨剧。

在实际项目中,我建议新人在第一台设备上用ST重写一遍以前用梯形图做过的逻辑,对比两种方式在可读性、调试效率上的差异。不用追求“强行用ST写一切”,简单的启停逻辑用梯形图更直白,涉及数据分析、状态机和运动控制的地方用ST更顺手。工具没有好坏,适合场景的才是最好的。

最后分享一个小技巧:写完ST程序后,多用InoProShop的“自动格式化”功能(快捷键Ctrl+Shift+F),让代码缩进整齐。代码的排版整洁程度,往往和逻辑严谨程度成正比。看着舒服,出错的概率也低。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询