简介:「欧姆龙ST编程中文手册」面向PLC初学者与现场调试人员,帮助读者理解结构化文本的编程思路与功能块使用规范。内容围绕欧姆龙CX-Programmer 6.1展开:先介绍功能块的基本概念,以及基本与高级两类功能块的划分;再讲解变量声明、赋值、条件与循环语句等语法要点;并延伸到将功能块转换为库文件、技术规格与功能块限制等工程细节;最后单列安全注意事项与应用注意事项,提示电路防护、设备选型与调试中的常见风险。
压缩包内有1个PDF文件,约2.26MB,可直接在电脑或移动端按章节查阅检索。目前已有7329人学习下载,接受度较高。
读者可借此理清ST语言与梯形图的差异,掌握功能块定义、变量使用与程序结构的组织方式,并对照手册中的规格限制与注意事项,排查实际项目中的配置问题,适合作为入门通读与日常查阅的参考。
1. 装 CX-Programmer 6.1 之前:先把版本对清楚
某条产线调试,对方拿着一份《欧姆龙ST编程中文手册》W447-CN5-02,说功能块照着写完了,编译零错误,一下载 CPU 就报非法指令。查了两个小时,硬件是 2.0 版的 CS1-H——功能块这套东西要 3.0 版以上的 CS/CJ,或者 CP1H 全系才认。手册第一页就写着适用范围,只是没人往后翻。
这类翻车在 ST 编程环境里太常见:软件装上了、工程建起来了、语法也写对了,最后卡在软件版本和 CPU 单元版本的匹配上。这套环境适合手上已经有 CP1H、CS1-H、CJ1-H、CJ1M 的现场调试人员,也适合第一次碰功能块和结构化文本、准备把梯形图逻辑往 ST 上迁的人。下面按我实际装机的顺序走一遍。
2. 装 CX-Programmer 6.1:软件、系统与串口的版本对照
2.1 三张版本表先对上,别急着点下一步
装之前我会把三样东西摊在桌面上对:编程软件版本、CPU 单元型号与版本、手头这本手册的编号。手册 W447-CN5-02 是 2006 年 06 月修订的,对应 CX-Programmer 6.1 版,软件型号 WS02-CXPC1-E-V61。它讲的是功能块部分,跟功能块无关的常规操作要看 W437 那本操作手册,两边不能混着查,否则会找不到对应的菜单。
| 对象 | 版本要求 | 说明 |
|---|---|---|
| CX-Programmer | 6.1(WS02-CXPC1-E-V61) | 手册对应的就是这个版本,6.0 的部分行为有差异 |
| CP1H 系列 | 全系列支持功能块 | CP1H-X、CP1H-XA、CP1H-Y 均在列 |
| CS1-H / CJ1-H / CJ1M | 3.0 版及以上 | 2.0 版及以下不支持功能块 |
| NSJ / FQM1 | 手册明确列入适用范围 | 控制器与运动单元各有自己的手册 |
这张表里最要命的是第三行。含功能块的用户程序一旦下到 2.0 版或更低的 CS/CJ 单元里,所有实例都会被当成非法指令,程序既不能编辑也不能执行。它不是报个警告让你继续,是直接废掉。所以接活第一件事:在线连上去看 CPU 单元的实际版本,而不是看设备铭牌上的订货号猜。
配套手册也顺手备齐:CS 系列看 W339,CJ 系列看 W393,编程方法看 W394,指令参考看 W340。功能块里调指令时操作数限制、指令支持范围,都得回 W340 查,光靠 W447 这一本是查不全的。
2.2 装在哪台机器上:系统版本、路径和那个老生常谈的中文目录
6.1 那个年代的安装包是 32 位程序。我的习惯是给它一台干净的 32 位系统,物理机或者虚拟机都行,虚拟机更省事——装坏了直接回快照,比事后卸载重装干净得多。64 位系统上能装上、也能打开,但串口和 USB 转串口驱动的兼容问题会一个接一个,现场排障时很难分清是软件问题还是线的问题。
安装路径不要带中文、不要带空格,直接C:\OMRON\CX-One这种。中文路径在当年那些组件注册、库文件引用上出问题的概率不低,而且报错信息往往指向别处,排查成本远高于改个路径。
另外,手册的应用注意事项里专门提了一条:启动 CX-Programmer 之前要退掉所有不直接相关的程序,尤其是屏幕保护、病毒检查、邮件客户端、调度程序这类会定期启动或自动启动的东西。这条不是客套话。屏幕保护一起来,串口通信就可能中断,表现出来就是"在线监视突然掉线",你会以为是 PLC 的问题。
提示:虚拟机里装的话,把虚拟机的串口直通配好再装软件,顺序反了容易在设备管理器里留下辨不清的幽灵设备,后面每次插拔都要重新认一遍。
2.3 串口和 USB 转串口先理干净,再谈安装
这一步最容易被跳过,也最容易在后面咬人。笔记本的 RS-232C 端口默认可能被分到调制解调器或红外线路上,你得按机器文档把它启用成正常串行口。还有省电设定——Windows 的电源方案和 BIOS 里各有一套,两套都得关掉对串口的省电控制,否则电压不够,通信时断时续。
装完驱动后先用系统命令确认端口号,别在软件里瞎试:
# 列出当前系统识别到的串口设备,确认 USB 转串口被认成 COMx Get-WmiObject Win32_SerialPort | Select-Object DeviceID, Description, MaxBaudRate # 顺带看一眼有没有被占用的端口,排除虚拟串口软件干扰 Get-WmiObject Win32_SerialPort | Format-Table DeviceID, Description -AutoSize第一段输出里DeviceID那一列就是 COM 口号,安装时要在 CX-Programmer 的通信设置里填一致。MaxBaudRate用来确认这根线能不能跑到你要的波特率——有些廉价转换线标称支持 38400,实际跑起来丢包。第二段是排除项:机器上装过虚拟串口工具的,会多出一堆 COM 口,认错一个就连不上。
注意:手册里明确写了,不要在 CX-Programmer 与 PLC 在线时关掉 PLC 电源或拔连接电缆,否则计算机可能出故障。这条我在现场见过两次,一次是笔记本蓝屏,一次是 USB 转串口驱动直接挂掉,得重装。
2.4 安装过程与第一次启动要确认的三件事
安装本身没什么花活:运行安装介质,按提示走,许可信息用随介质提供的那份填进去,组件选择里 CX-Programmer 是必选的,其他按现场需要勾。装完重启一次,这一步别省——串口驱动和组件注册都要重启后才彻底生效。
第一次启动后别急着建工程,先确认三件事:软件版本号显示是否为 6.1;菜单里功能块相关的项是否可见(不可见多半是安装组件没勾全);通信端口列表里能否看到 2.3 里查到的那个 COM 口。
版本号可以在帮助菜单的关于里看,注意别把 CX-One 套件的版本和 CX-Programmer 的版本搞混,两个号不一定一样。功能块菜单是否可见这一点,在 6.1 里跟 CPU 型号选择有关——你新建工程时如果选了个不支持功能块的机型,相关菜单项会灰掉或者干脆不出现,这是正常行为,不是装坏了。
如果装完打不开、或者打开报组件缺失,先别重装。把安装日志翻出来看最后失败的是哪个组件,通常是某个运行库没装上,单独补一下比重装整个套件快得多。实在不行回虚拟机快照,这也是我坚持用虚拟机的原因之一。
3. 新建工程与目标机型配置:CPU 型号、通信参数、功能块区域
3.1 新建工程时选错机型,后面全是白工
新建工程的第一步是选设备类型和 CPU 型号,这一步选错了,后面写的功能块可能根本编译不过,或者编译过了下不进去。选型要跟现场那台单元严格一致:CP1H-X 和 CP1H-XA 在模拟量处理上不是一回事,CJ1M 和 CJ1H 的功能块容量也不一样。
具体做法是先在线上把 CPU 型号和版本读出来。用自动在线连接,让软件自己去识别,识别完再回头看工程属性里落的是哪个型号,跟实际设备对一遍。手动在下拉框里选,很容易选到相邻型号上去——字母差一个,编译能过,下载报错。
工程建好之后,先别写程序,把 PLC 属性里的几项确认掉:
| 属性项 | 我一般怎么设 | 原因 |
|---|---|---|
| 设备类型 | 与实际单元一致 | 决定可用指令集和功能块容量 |
| CPU 型号 | 含版本号,如 CS1H-CPU67H | 版本决定是否支持功能块 |
| 功能块区大小 | 按实际 FB 数量留余量 | 超了编译或下载会失败 |
| 程序容量 | 按步骤数估算后留 20% | 功能块实例会额外占步骤 |
功能块区这一项,手册第 2 章的技术规格里有明确的容量限制和实例数量限制,不同类型的 CPU 单元数字不一样。我一般的做法是先按实际需求的两倍留,因为调试过程中功能块数量和内部变量很容易涨上去,中途改容量要重新分配内存,麻烦。
3.2 通信参数:网络类型、波特率和那三个容易配反的位
CX-Programmer 连 PLC 有几种网络类型,现场最常用的是 SYSMAC WAY(上位链路)和 Toolbus,以太网机型走 EtherNet/IP 或者 FINS/TCP。串口连接下,默认常见的是 9600bps、7 数据位、2 停止位、偶校验——但这只是默认值,实际以 CPU 单元侧 DIP 开关和 PLC 系统设定里的通信参数为准,两边必须完全一致。
| 参数 | 常见取值 | 配错时的现象 |
|---|---|---|
| 波特率 | 9600 / 19200 / 38400 | 完全连不上,或连上就断 |
| 数据位 | 7 或 8 | 能连上但读写数据错乱 |
| 停止位 | 1 或 2 | 偶发通信超时 |
| 校验 | 偶校验 / 无 | 长报文出错,短报文正常 |
| 响应超时 | 默认值先别动 | 改小了在网络慢时误报离线 |
配完点一下在线连接测试,能读到 CPU 型号和运行模式才算通。读不到先查线序和端口号,再查两边参数,最后才怀疑软件。我见过有人把 RS-232C 的交叉线和直连线搞混,折腾一下午。
3.3 功能块能不能用,取决于这几项设定
功能块不是装上软件就自动可用的,它依赖 CPU 单元侧的内存分配。在 PLC 属性的内存设置里,功能块区需要单独划出来,划多大取决于你要放多少个功能块定义、多少个实例。手册第 2 章给了功能块规格、实例规格和各类 CPU 单元的功能块规格,还有"功能块程序步骤数和实例执行时间"这张表——后者很关键,实例一多,扫描周期会被拖长。
我一般的顺序是:先把功能块区按预估划好,写完全部功能块定义和实例之后再回来看实际占用,如果接近上限就及时扩,不要等到下载报错才改。扩容要重新分配内存,涉及已有程序区的搬移,能早做就早做。
提示:功能块程序步骤数和实例执行时间在手册第 2 章有表可查。周期时间紧的场合,下程序之前先按实例数量估一遍,比下载完在现场看扫描时间报警强。
3.4 工程文件和备份:别只留一份在本地
工程存盘之后,我习惯在同一个目录建一个backup子目录,每次大的改动前手动复制一份带日期的工程文件。CX-Programmer 的工程文件包含程序、PLC 属性设定和功能块定义,一旦属性被改乱,回退比重新配快得多。
还有一点:含功能块的任务无法在任务单元中下载(上传是可以的)。这意味着如果你习惯按任务分别下载,含功能块的那个任务会被挡住。要么整机下载,要么把功能块拆到能下载的单元里去——手册里写得很清楚,但第一次遇到时那个报错信息不会告诉你原因。
4. 创建功能块与 ST 编程:变量方向、AT 设定、数组长度
4.1 变量分四类,方向错了编译就过不去
功能块里的变量按方向分四类:输入变量、输出变量、内部变量、外部变量。输入变量是调用时从外面传进来的,输出变量是算完往外送的,内部变量只在功能块内部可见,外部变量用来跟功能块外的地址打交道。
输入变量有个坑:算法执行之前,数值是成批地经过输入参数到达输入变量的,不是执行到哪条指令就实时取哪个值。所以如果你需要在功能块算法执行过程中让数值实时流进来,得用内部变量或者外部变量,不能用输入变量。输出变量写回参数也是同样的时序,成批写,不是逐条写。
AT 设定是用来把变量钉到具体地址上的。多字数据的首地址、末地址这类场合,必须用带 AT 设定的变量或者外部变量,否则编译直接报错。变量表大概长这样:
| 变量名 | 数据类型 | 方向 | AT 设定 | 用途 |
|---|---|---|---|---|
| In | REAL | 输入 | 无 | 模拟量输入值 |
| HH | REAL | 输入 | 无 | 上限设定 |
| LL | REAL | 输入 | 无 | 下限设定 |
| HiAlm | BOOL | 输出 | 无 | 上限报警 |
| Buf | WORD[10] | 内部 | D100 | 连续 10 字缓冲区 |
| Ret | INT | 内部 | 无 | 内部返回值 |
Buf这一行就是带 AT 的数组内部变量,指向 D100 开始的 10 个字。这种写法在处理多字指令时是标准做法——输入变量不能带 AT 去指定多字首地址,只能用内部变量。
注意:基本 I/O 单元、特殊 I/O 单元、CPU 总线单元的地址不能注册为全局符号,也就不能指定为外部变量。这类地址的数据可能不稳定,硬要这么用,读上来的值会跳。
4.2 ST 算法:能写的和不能写的
ST 是结构化文本,写法接近 Pascal,支持赋值、IF、CASE、FOR、WHILE 这些结构。在 CX-Programmer 6.1 里,功能块的算法可以用梯形图写,也可以用 ST 写,两者可以混在一个工程里。
一个上下限报警的功能块,用 IF 写是这样:
(* 功能块 FB_Alarm2:模拟量上下限报警 *) (* In/HH/LL 为输入变量,HiAlm/LoAlm 为输出变量 *) IF In >= HH THEN HiAlm := TRUE; (* 超上限,置位上限报警 *) LoAlm := FALSE; ELSIF In <= LL THEN LoAlm := TRUE; (* 低于下限,置位下限报警 *) HiAlm := FALSE; ELSE HiAlm := FALSE; (* 回到正常区间,双报警复位 *) LoAlm := FALSE; END_IF;这段的逻辑是三分支:超上限、低于下限、正常区间。注意 ELSE 分支里两个报警都复位,这样从报警状态回到正常时不会残留。:=是赋值,(* *)是注释,分号结尾不能漏——ST 对分号比梯形图严格得多。
同样的逻辑也可以写成布尔表达式,编译出来步骤数更少:
(* 等价写法:直接对布尔输出赋值,省掉分支 *) HiAlm := (In >= HH); LoAlm := (In <= LL) AND NOT HiAlm; (* 上限优先,避免两点重叠时双报警 *)第二种写法里NOT HiAlm是用来做互斥的。如果 HH 和 LL 参数被人为设成同一个值,第一种写法会走上限分支,第二种写法也是上限优先,行为一致。这种边界情况在实际项目里真会出现,参数是从触摸屏下发的,操作工手一抖就设重了。
循环用 FOR,遍历数组的时候必须注意下标:
(* 对 Buf 数组的前 8 个字做累加,结果放 Sum *) Sum := 0; FOR i := 0 TO 7 DO Sum := Sum + WORD_TO_INT(Buf[i]); END_FOR;WORD_TO_INT是类型转换,ST 不做隐式转换,WORD 和 INT 之间必须显式转。Buf[i]的下标不能越界——数组声明了 10 个元素,循环只能到 9,这里取 8 个是留了两个字的余量。越界在编译期不一定报错,运行起来会读到数组外的内存,那部分内存可能正被别的指令用着。
CASE 语句适合做状态机,写法是CASE Step OF 0: ... 1: ... ELSE ... END_CASE;,每个分支后不用加分号分隔,但分支内的语句要加分号。这块手册附录 B 讲得比较细,第一次写建议照着抄结构,别自己发挥。
4.3 实例化与库文件:定义一次,多处复用
功能块定义本身不是程序,得实例化之后才会真正执行。一个定义可以生成多个实例,每个实例有自己的内部变量副本,互不干扰。实例名在调用处指定,数据类型就是那个功能块的名字。
实例化的时候要留意实例数量。手册里明确写了实例规格和功能块限制,每个实例都占内存、占步骤、占执行时间。我一般会在功能块定义里把内部变量压到最少,能在调用侧算的就不放进去,这样实例一多也不会把扫描周期拖垮。
功能块定义写完之后可以转成库文件,格式是库,不是普通工程文件。转成库的好处是多个工程共用同一套功能块,改一处、处处生效——但反过来说,改库会影响所有引用它的工程,改之前得确认没有别的项目在用。我的做法是库文件带版本号后缀,新版本另存,老工程继续指老的库,升级一个一个来。
4.4 编译、下载和那个不能断电的 BKUP 灯
编译前先看一眼有没有警告。CX-Programmer 在数组长度不匹配这类问题上,有时候只给警告不给错误。手册里写得很明白:如果指令操作数指定的长度不固定,而实际数组元素数量小于这个长度,编译不报错,只出一条警告;运行时指令会对超出元素数的那部分照常读写,也就是踩到数组后面的内存上。这些内存如果正被别的指令用着,就会出现莫名其妙的动作。
所以我的习惯是编译结果里警告也要清零,不能只盯错误数。
下载的时候注意两件事。第一,含功能块的任务不能按任务单元单独下载,要整机下载或者调整下载范围。第二,在线编辑之后,CS1-H、CJ1-H、CJ1M、CP1H 这些单元会把用户程序和参数区数据备份到内置闪存里,备份期间 CPU 单元前面的 BKUP 灯是亮的,这时候绝对不能关电源——一关数据就不备份了。要看备份状态,可以在 PLC 属性里打开存储器备份状态显示,从查看菜单里调出来。
5. 常见问题与排查:五条踩过的坑
5.1 编译零错误,下载后全部变非法指令
现象:程序编译通过,下载也提示成功,CPU 一运行就报非法指令,所有功能块实例都不执行。
原因:目标 CPU 是 2.0 版或以下的 CS/CJ 系列,不支持功能块。软件端不会因为你选了个老型号就拦住你,它只管编译。
解决:在线读 CPU 单元的实际版本,确认在 3.0 以上或者换 CP1H。已经下进去的程序要先清掉再重新下,别在老程序上直接覆盖。
5.2 输入参数里写了 20,结果读的是 CIO 区的 0020
现象:功能块传入一个数值参数,运行结果跟预期完全不对,像是读了个地址。
原因:输入变量不是布尔格式时,参数里只写纯数字会被当成 CIO 区地址解析,20被理解成0020那个地址里的值,而不是数值 20 本身。
解决:数值前加前缀。&20表示十进制常数,#20表示十六进制,正负号也要带上。这个规则手册的应用注意事项里写了,但第一次用的人几乎都会中招。
5.3 数组长度比指令要求的短,编译只给警告
现象:编译结果里错误 0、警告若干,程序能下进去,运行一段时间后别的逻辑开始出现无规律动作。
原因:数组元素数量小于指令操作数指定的长度,编译期只警告不报错,运行时指令照样按指定长度读写,越界部分踩到了相邻变量。
解决:数组元素数量必须大于等于指令处理长度。长度是常量时编译会直接报错,反倒安全;长度是变量时只警告,得自己盯。我一般把数组长度统一按最大可能长度声明,宁可浪费几个字。
5.4 在线监视时突然掉线,重连还连不上
现象:在线监视跑着跑着断开,重新连接提示端口被占用或者通信超时。
原因:常见的是笔记本的屏幕保护或者省电设定把串口给挂起了,其次是病毒检查软件在扫串口。手册里专门提过要退出屏幕保护、病毒检查、邮件和调度程序。
解决:关掉屏幕保护和所有省电设定(Windows 电源方案和 BIOS 两处都要关),退出杀毒和邮件客户端。如果还是掉,换一根质量好点的 USB 转串口线,廉价线在 38400 下丢包是常态。
5.5 全局符号注册了 I/O 单元地址,数据一直在跳
现象:把基本 I/O 单元或者特殊 I/O 单元的地址注册成全局符号,当外部变量用,读上来的值不稳定。
原因:这类地址不能注册为全局符号,注册了也不能指定为外部变量,数据本身就不保证稳定。
解决:改用带 AT 设定的内部变量去访问这些地址。要读多字数据的首地址或末地址,也是同样的做法——输入变量不能拿来当多字指令的操作数,必须走内部数组变量。
6. 装完怎么验证跑通:三步自检和一个改不掉的习惯
环境装完、程序写完,怎么算真的通了?我一般走三步,每步都有明确的判据,不靠"看起来正常"。
第一步,编译结果清零。错误 0、警告 0,两个数都要看。警告里最常见的就是数组长度不匹配,这类警告放过去,运行时的表现是随机的,事后极难定位。编译完顺手看一眼功能块和实例的实际占用,跟 PLC 属性里划的功能块区对一下,余量不到两成我就回去扩。
第二步,在线监视看实例。连上之后进在线监视,把功能块的实例展开,逐个看输入输出变量的实时值。做法是人为给输入变量赋几个边界值:正常区间、正好等于上限、正好等于下限、超过上限、低于下限。看输出是不是按预期翻转。这一步能抓出大部分逻辑错误,也能验证变量方向和 AT 设定有没有写错。监视的时候注意,梯形图部分窗口和观察窗口里的强制设置、强制复位操作要格外小心,按错一个快捷键就可能把输出置起来,接着输出单元上的设备就动作了,跟 CPU 在什么模式下没关系。
第三步,下载后等 BKUP 灯灭。在线编辑或者下载完成后,CPU 会把程序和参数备份到内置闪存,BKUP 灯亮着的时候不能断电。等灯灭了再断电重启,然后重新连上去读一次程序,确认下载的内容跟工程里的一致。
最后一步是核对执行时间。手册第 2 章有"功能块程序步骤数和实例执行时间"的对照表,按你实际用的实例数量估算一下,跟在线监视里看到的扫描周期比。差得太多说明实例数量或者功能块内部逻辑需要优化,别等到现场报周期超时才回头改。
| 验证项 | 通过判据 | 不通过先查什么 |
|---|---|---|
| 编译 | 错误 0、警告 0 | 数组长度、AT 设定、类型转换 |
| 在线监视 | 边界值下输出翻转正确 | 变量方向、参数前缀、实例绑定 |
| 下载完整性 | BKUP 灯灭后重启读回一致 | 是否按任务下载、功能块区容量 |
| 执行时间 | 实测与手册估算同量级 | 实例数量、功能块内循环 |
这套流程我现在已经形成条件反射了:不管多急,编译警告不清零就不下载。前几年赶一个改造项目,警告里那条数组长度不匹配被我跳过去了,跑了三天之后现场随机停机,查了两天才回到那条警告上。从那以后我每次下载前都强制走一遍这三步,一条警告都不放过。
希望帮到你。
本文还有配套的精品资源,点击获取