【重要】CODESYS V3编程指南

Download as pdf or txt
Download as pdf or txt
You are on page 1of 423

[Type text] 第一章 概述 [Type text]

PLC 综合开发利器
— CODESYS 基础编程及应用指南
[Type text] 第一章 概述 [Type text]

目录

PLC 综合开发利器 ................................... 1 3.1.1 字符集 ....................................... 70


——CoDeSys 基础编程及应用指南 ........ 1 3.1.2 分界符 ....................................... 70
第0章 前言 ......................................... 5 3.1.3 关键字 ....................................... 71
第1章 概述 ......................................... 6 3.1.4 句法颜色 ................................... 72
1.1 IEC 61131-3 标准 ............................... 6 3.1.5 空格和注释 ............................... 73
1.1.1 IEC 61131 简介 ........................... 6 3.2 常数 ................................................... 76
1.1.2 PLCopen 组织概况 ..................... 7 3.2.1 常数的表示方法 ....................... 76
1.1.3 IEC 61131-3 编程语言................ 7 第4章 变量........................................ 79
1.1.4 IEC 61131-3 标准语言的特点 .... 8 4.1 变量的表示和声明 ........................... 79
1.2 软 PLC-CoDeSys ................................ 9 4.1.1 变量 ........................................... 79
1.2.1 软 PLC 控制方案 ...................... 10 4.1.2 标识符 ....................................... 79
1.2.2 软 PLC 的发展方向 .................. 11 4.1.3 变量声明 ................................... 79
1.3 CoDeSys 概述 ................................... 11 4.2 数据类型 ........................................... 81
1.3.1 CoDeSys 自动化解决方案 ....... 12 4.2.1 标准数据类型 ........................... 81
1.3.2 CoDeSys 实时核 ....................... 14 4.2.2 标准的扩展数据类型................ 86
1.4 软件的安装....................................... 15 4.2.3 自定义数据类型 ....................... 92
1.4.1 安装所需的软硬件要求 ........... 16 4.3 变量命名建议 ................................. 104
1.4.2 安装 ........................................... 16 4.3.1 匈牙利命名法 ......................... 104
1.4.3 启动编程软件 ........................... 16 4.4 变量的类型和初始化 ..................... 105
1.4.4 帮助 ........................................... 16 4.4.1 变量的类型 ............................. 105
1.4.5 CoDeSys 开发系统 ................... 17 4.4.2 变量的初始化 ......................... 107
1.5 获取资料、插件和技术论坛 ........... 20 4.5 变量声明编辑器中的 Pragma 指令 108
第2章 软件模型 ............................... 21 4.5.1 字段 Pragma ............................ 108
2.1 软件模型........................................... 21 第5章 编程语言.............................. 110
2.1.1 软件模型的特点 ....................... 22 5.1 指令表(IL) ................................. 111
2.2 设备................................................... 22 5.1.1 指令表语言结构 ..................... 111
2.2.1 添加设备 ................................... 22 5.1.2 连接元素 ................................. 112
2.2.2 设备编辑器 ............................... 25 5.2 梯形图(LD) ................................ 115
2.3 应用................................................... 26 5.2.1 简介 ......................................... 115
2.3.1 任务 ........................................... 26 5.2.2 梯形图程序执行顺序.............. 115
2.3.2 库文件 ....................................... 35 5.2.3 组成元素 ................................. 117
2.3.3 全局变量和局部变量 ............... 45 5.2.4 赋值指令 ................................. 121
2.3.4 访问路径 ................................... 46 5.3 功能块图(FBD) ......................... 122
2.4 程序组织单元 ................................... 47 5.3.1 简介 ......................................... 122
2.4.1 程序组织单元结构 ................... 47 5.3.2 连接元素 ................................. 122
2.4.2 函数 ........................................... 49 5.3.3 组态 ......................................... 125
2.4.3 功能块 ....................................... 52 5.4 结构化文本(ST) ........................ 126
2.4.4 程序 ........................................... 56 5.4.1 简介 ......................................... 126
2.4.5 创建的原则 ............................... 58 5.4.2 结构化文本程序执行顺序...... 126
2.5 应用对象........................................... 58 5.4.3 语句 ......................................... 128
2.5.1 采样跟踪 ................................... 58 5.5 顺序流程图(SFC) ...................... 138
2.5.2 持续变量 ................................... 65 5.5.1 SFC 顺序流程图...................... 138
2.5.3 数据单元类型 ........................... 67 5.5.2 SFC 的结构.............................. 140
2.5.4 全局网络变量 ........................... 67 5.5.3 SFC 的编程元素...................... 154
2.5.5 配方管理器 ............................... 68 5.5.4 SFC 元素的属性...................... 155
第3章 公用元素 ............................... 70 5.6 连续功能图(CFC)...................... 157
3.1 公用元素........................................... 70 5.6.1 简介 ......................................... 157
[Type text] 第一章 概述 [Type text]

5.6.2 程序执行顺序 ......................... 157 9.2.4 删除工具 ................................. 240


5.6.3 连接元素 ................................. 159 9.3 工具 ................................................. 240
5.6.4 CFC 的组态 ............................. 166 9.3.1 基本工具 ................................. 240
第6章 指令系统 ............................. 169 9.3.2 通用控制工具 ......................... 245
6.1 位逻辑指令..................................... 169 9.3.3 测量控制 ................................. 257
6.1.1 基本逻辑指令 ......................... 169 9.3.4 灯/开关/位图 ........................... 262
6.1.2 置位优先与复位优先触发器指令 9.3.5 特殊控制 ................................. 264
173 9.3.6 报警管理 ................................. 273
6.1.3 边沿检测指令 ......................... 175 9.4 视图的建立及编辑 ......................... 280
6.2 定时器指令..................................... 177 9.4.1 应用举例 ................................. 280
6.2.1 定时器 ..................................... 177 第 10 章 常用库函数介绍? .............. 292
6.3 计数器指令..................................... 181 第 11 章 控制系统工程实例 .............. 293
6.3.1 计数器简介 ............................. 181 11.1.1 圆盘 180°正反转控制 ............. 293
6.3.2 计数器指令 ............................. 181 11.1.2 火警报警系统 ......................... 294
6.4 数据处理指令 ................................. 185 11.1.3 抢答控制系统 ......................... 297
6.4.1 选择操作指令 ......................... 185 11.1.4 交通灯信号控制程序.............. 299
6.4.2 比较指令 ................................. 188 11.1.5 停车场管理 ............................. 304
6.4.3 移位指令 ................................. 189 11.1.6 恒压变频供水控制系统.......... 305
6.5 运算指令......................................... 194 第 12 章 CoDeSys 通信网络 .............. 310
6.5.1 赋值指令 ................................. 194 12.1 通信基础 ..................................... 310
6.5.2 算术运算指令 ......................... 194 12.1.1 数据传送方式 ......................... 310
6.5.3 数学运算指令 ......................... 197 12.1.2 串口通讯接口标准.................. 318
6.5.4 地址运算指令 ......................... 201 12.2 现场工业总线网络基础 ............. 321
6.6 数据转换指令 ................................. 203 12.2.1 总线数据通讯模式.................. 322
6.6.1 数据类型转换指令 ................. 203 12.2.2 工业控制网络的拓扑结构...... 322
第7章 程序结构 ............................. 211 12.2.3 工业通信协议基础.................. 329
7.1 系统程序和用户程序 ..................... 211 12.2.4 CoDeSys 支持的通信协议...... 330
7.2 用户程序结构 ................................. 211 12.2.5 工业以太网线缆 ..................... 331
7.2.1 常用的编程方法 ..................... 211 12.3 CANopen 通讯 ................................ 333
第8章 基础编程 ............................. 215 12.3.1 拓扑结构 ................................. 333
8.1 基本编程操作 ................................. 215 12.3.2 运行原理 ................................. 333
8.1.1 启动 CoDeSys ......................... 215 12.3.3 电缆和接头 ............................. 339
8.1.2 PLC 程序文件的建立 ............. 216 12.3.4 PDO 通讯示例......................... 340
8.2 定义资源对象 ................................. 218 12.3.5 SDO 通信示例......................... 347
8.2.1 启动 Gateway Server 和 PLC . 218 12.4 Modbus 网络基础 ........................... 351
8.3 程序下载......................................... 220 12.4.1 协议描述 ................................. 351
8.3.1 编译 ......................................... 220 12.4.2 Modbus 串口协议描述 ........... 352
8.3.2 登入下载 ................................. 221 12.4.3 Modbus TCP 协议描述 ........... 354
8.3.3 在线监控 ................................. 224 12.4.4 运行原理 ................................. 355
8.4 程序调试......................................... 228 12.4.5 电缆和接头 ............................. 362
8.4.1 复位 ......................................... 228 12.4.6 Modbus 串口的通讯组态 ....... 365
8.4.2 程序调试 ................................. 229 12.4.7 Modbus TCP 的通讯组态 ....... 368
8.5 仿真................................................. 232 12.5 EtherCAT 网络基础........................ 373
8.5.1 离线仿真 ................................. 232 12.5.1 EtherCAT 拓扑结构及媒介 .... 373
8.5.2 仿真示例 ................................. 233 12.5.2 EtherCAT 运行原理 ................ 374
8.6 PLC 脚本功能 ................................ 235 12.5.3 EtherCAT 硬件设定 ................ 378
第9章 可视化界面建立及应用 ..... 237 12.5.4 EtherCAT 网络设计 ................ 379
9.1 CoDeSys 可视化界面 ..................... 238 12.5.5 主从站通讯配置示例.............. 380
9.2 基本操作......................................... 239 12.6 PROFINET 网络基础 ..................... 386
9.2.1 创建可视化界面 ..................... 239 12.6.1 PROFINET 拓扑结构及媒介 .. 386
9.2.2 添加工具 ................................. 239 12.6.2 PROFINET 运行原理 ............. 388
9.2.3 对齐工具 ................................. 240 12.6.3 PROFINET 协议架构.............. 391
[Type text] 第一章 概述 [Type text]

12.6.4 PROFINET 主从站通讯配置 . 394 13.1.3 用户管理及访问限制.............. 418


12.7 EtherNet/IP 网络基础 ..................... 405 13.2 诊断及常见故障处理 ................. 418
12.7.1 EtherNet/IP 拓扑结构及媒介 . 405 13.2.1 下载出错 ................................. 418
12.7.2 EtherNet/IP 运行原理 ............. 408 13.2.2 添加隐含检查功能.................. 419
12.7.3 EtherNet/IP 通讯配置 ............. 412 第 14 章 附录...................................... 421
第 13 章 附加功能 ............................. 418 14.1 快捷键 ......................................... 421
13.1 程序安全 ..................................... 418 14.1.1 快捷输入 ................................. 421
13.1.1 工程文件加密 ......................... 418 14.1.2 切换窗口 ................................. 422
13.1.2 库文件加密 ............................. 418 第 15 章 参考文献.............................. 423
第0章 前言
CoDeSys 是德国 3S 公司的 PLC 编程软件,本书以这些编程软件所支持的 PLC 作为基础,向读
者说明 PLC 的使用环境。在逐步了解了软件后,使读者一步一步的掌握和精通 CoDeSys 系统的项
目开发、程序编制、网络通讯及可视化编程界面的制作等。
如今,全球有近 350 家知名的自动化产品和方案供应商是 3S 公司的合作伙伴,这其中较著名
的有 ABB 的 Control builder、Schneider Electric 的 SoMachine、BECKHOFF 的 TwinCAT、EATON
的 XSoft、Bosch-Rexroth 的 IndraWorks Engineering、易福门、德国控创、法国阿尔斯通、路斯特、
伦茨,科比 ,科控,SEW,丹佛斯、费斯托、日立、三菱电机自动化、欧姆龙、和利时、中控集
团,步科等业界巨头。
CoDeSys 的相关解决方案已经广泛应用于能源、交通、市政、冶金、化工、制药、食品、纺织、
包装、印刷、橡塑、机床和军工等行业,为用户使用基于 IEC 61131-3 国际标准编程语言进行项目
开发提供了一种技术先进、功能强大的开放式全集成化的编程开发环境。
本书的主要目的是要帮助广大 CoDeSys 产品使用者正确,快速的使用产品,书中比较详细的
介绍的软件的功能,对每个常用参数给予了详细的解释。
本书主要读者是针对产品的技术支持人员、项目开发、调试人员、现场设备维护人员,同时也
是和大专院校本科生、硕士生项目研发时作为参考资料。针对初学者的特点,全面细致的讲解了使
用 CoDeSys 编 程 软件进行 编程和 项目开发 的各种 技术, 是零基础 学者必 备的图 书。主要 以
CoDeSys V3.x 开发环境为基础进行说明。
本书主要内容分四大部分进行讲解:
第一部分以 CoDeSys 基础介绍为主。针对 IEC 61131-3 标准的概念及背景、CoDeSys 软件的主
体结构(内部实时核及项目开发软件)及针对编程人员所使用的项目开发软件框架说明这三部分进
行讲解,让读者了解 CoDeSys 的基本概念、整体结构以及在实际工程项目中,CoDeSys 能实现的
具体功能。
第二部分以 CoDeSys 编程语言的语法介绍为主,也是本书的重点。分别对公共元素、数值表
示、数据类型及 6 种不同的编程语言的语句语法这四大部分进行详细说明,结合实际工程样例程序
让读者能更快,更好的掌握此部分的内容。
第三部分以 CoDeSys 人机界面(HMI)的制作介绍为主。分别对控件介绍及使用及变量映射两
部分进行讲解,让读者通过学习能够独立完成简单的画面制作项目。
第四部分以讲解完整的项目程序为主。由程序调试及常用技巧、仿真功能及项目程序讲解四部
分组成。通过这部分的学习,让读者能掌握从项目开发到程序调试及最终的项目完成这整个过程所
应具备的知识点,最终使读者具有较强的项目开发能力。
本文所有样例程序均基于 CoDeSys V3.5 SP4 Patch1 版本进行编写。
为了便于读者学习和查阅相关技术参数和内容,本书附有 5 个附录,附录 A...
由于编者水平有限,书中难免有错误和不妥之处,尽情广大读者批评指正。
作者 E-Mail:[email protected]
编者
2015 年 7 月
第1章 概述
本章主要知识点
 IEC 61131-3 简介
 什么是软 PLC
 CoDeSys 简介

1.1 IEC 61131-3 标准


由于 CoDeSys 是完全基于 IEC 61131 -3 标准所开发,所以在此需要引入 IEC 61131-3 的概念。
IEC 61131-3 编程语言标准是第一个为工业控制系统提供标准化编程语言的国际标准。该标准针对
工业控制系统所阐述的软件设计概念、模型等,适应当今世界软件、工业控制系统的发展方向,是
一种非常先进的设计技术。他极大的推动了工业控制系统软件设计的发展,对现场总线设备的软件
也产生了很大的影响。

1.1.1 IEC 61131 简介

1993 年 3 月由国际电工委员会 IEC(International Electro-technical Commission)正式颁布可编


程控制器的国际标准 IEC 1131(1131 前面添加 6 后作为国际标准的编号,即 IEC 61131)。
IEC61131 标准将信息技术领域的先进思想和技术(如软件工程、结构化编程、模块化编程、面向
对象的思想及网络通信技术等)引入工业控制领域,弥补并克服了传统 PLC、DCS 等控制系统的
弱点(如开放性差、兼容性差、应用软件可维护性差以及可再用性差等特点)。目前 IEC 61131 标
准已经在欧美发达国家得到广泛应用,但在我国还尚处于起步阶段,由于近几年我国的工业水平也
在飞速的发展,在此过程中也会引入大量欧美国家的先进技术,相信不久的将来 IEC 61131 标准在
国内也会得到广泛应用。
IEC 61131 标准共有 8 个部分组成,各部分最新内容简介如下,
1) IEC 61131-1 通用信息(2003-V2.0)。 定义可编程控制器及外围设备,如编程和调试工具
(PADA)、人机界面(HMI)等相关术语。
2) IEC 61131-2 设备特性(2007-V3.0)。规定适用于可编程控制器及相关外围设备的工作环
境及条件,结构特性、安全性及试验的一般要求、试验方法和步骤等。
3) IEC 61131-3 编程语言(2013-V3.0)。规定可编程控制器编程语言的语法和语义,规定了 5
种编程语言,并通过形式定义、语法和(部分地)语义描述以及示例,定义了基本的软件模型。
4) IEC 61131-4 用户导则(2004-V2.0)。规定了如系统分析、装置选择、系统维护等系统应
用中其他方面的参考
5) IEC 61131-5 通信服务规范(2000-V1.0)。规定了可编程控制器的通讯范围。包括关于不
同制造商的 PLC 彼此之间以及 PLC 和其他设备之间的通讯。
6) IEC 61131-6 功能安全(2012-V1.0)。规定了用于 E/E/PE 安全相关系统的可编程控制器和
相关外围部件的要求。
7) IEC 61131-7 模糊控制编程(2000-V1.0)。将编程语言与模糊控制的应用相结合。
8) IEC 61131-8 编程语言应用和实现导则(2003-V2.0)。为了实现可编程控制器系统机器程
序支持的环境下编程语言的应用提供导则,为可编程控制器系统应用提供编程、组态、安装和维护
指南。
在我国,从 1995 年也颁布了 GB/T15969.1~GB/T15969.5、GB/T15969.7 和 GB/T15969.8 等 7
个可编程控制器的国家标准(功能安全部分还没有发布),以完成的国家标准等同于 IEC 61131-
1~IEC 61131-8 所对应的标准。
1.1.2 PLCopen 组织概况

PLCopen 国际组织成立于 1992 年,是独立于制造商和产品的国际组织。在欧洲以及国际上已


有不少 PLC 制造商、软件公司和独立的研究机构成为了国际组织的会员。
PLCopen 中国组织作为国际组织世界范围内的第三支区域性的推广机构(PC5)承担着该项标
准在中国区域的推广工作,旨在搭建工业控制领域交流平台,成为技术标准与行业发展趋势的信息
纽带,在供应商与最终用户之间搭建互通桥梁,现已有 30 余家国内外知名企业、高校成为了组织
的骨干。
PLCopen 的宗旨是促进 PLC 兼容软件的开发和使用。PLCopen 并不是另一个标准化委员会,
而是一个具有共同利益的集团,这个集团希望现有的标准获得国际上的接受能提供一些帮助。其结
构如图 1.1 所示。
一般会议

管理委员会

理事会

技术委员会 促进委员会

1.标准委员会 1.促进活动委员会

2.功能委员会 2.培训委员会

3.资质委员会 3.北美促进委员会

4.通讯委员会 4.日本促进委员会

5.软件安全委员会

图 1.1 PLCOpen 组织结构图

1.1.3 IEC 61131-3 编程语言

IEC 61131 是第一个关于 PLC 编程技术的国际标准,其中的 IEC 61131-3 是建立统一的 PLC 编


程语言的基础,是实现软 PLC 技术的重要条件。
该标准共分四章,第一章为概述,包括标准范围,参照标准,属于定义,标准概览和要求,以
及如何声明 PLC 系统,使 PLC 程序符合该标准。
第二章规定了 PLC 文本和图形编程语言的公共元素.公共元素包括字符的使用(含字符集、标
志符与关键字的规定、空格的使用、以及如何使用注释等)、数据(数、字符串、时间)的外部表
示类型、数据类型、变量、程序组织单元(函数、功能块、程序)以及软件模型(配置、资源、任
务、存取路径、全局变量等概念),图 1.2 描述了他们之间的关系。
配置

软件模型 资源

任务
编程模型

存取路径
数据外部表

公用元素 全局变量

变量
函数

程序组织单
元 功能块

程序

图 1.2 公共元素结构
第三,第四章分别定义了两大类共五种编程语言编程语言:文本化编程语言和图形化编程语言。
文本化编程语言包括指令表编程语言(Instruction List,IL)和结构化文本编程语言(Structured
Text,ST),图形化编程语言包括梯形图编程语言(Ladder Diagram,LD)和功能块图编程语言
(Function Block Diagram)。在标准中定义的顺序功能表图(Sequence Function Chart,SFC)即没
有归入文本化编程语言,也没有归入图形化编程语言,本书中,暂先将其定义为图形化编程语言,
图 1.3 分别将这五种语言进行了分类。
文本化编程语
图形化语言

指令表 梯形图
(IL) (LD)

结构化文 功能块图
本(ST) (FBD)

顺序功能流
程图(SFC)

图 1.3 编程语言

1.1.4 IEC 61131-3 标准语言的特点

 多样性
拥有 5 种不同的编程语言,分别于图形编程语言及文本编程语言两大类。尤其是在应对大型项
目时,用户可以根据实际需求,在一个项目中结合多种编程语言并使其融合,实现了程序设计的优
化,也为可编程控制器的应用提供了良好的操作环境。
 兼容性
由于采用了国际标准的编程语言规范,所以它能适用于可编程控制器、分散控制系统、现场总
线控制系统、数据采集和视觉系统、运动控制系统等。且该软件模型能适用于各种不同的行业、不
同结构的工业应用。因此,该标准编程语言更体现了与所使用的硬件无关这一重要特点,对用户而
言,对指定的硬件供应商的依赖也越来越少。
 开放性
编程语言的标准化同时也会带来另一个好处,即系统成为了开放系统。任何一个供应商生产的
产品,如果符合标准编程语言,则能使用标准编程语言进行编程,从根本上切断了软件和特定硬件
的依赖关系。但是目前,要做到软件完全不修改还有困难,比如不同的可编程控制器的外部端子对
应的 I/O 地址可能会不同,移植时需要重新输入对应的地址定义。
 可读性
编程语言中大量语言的表达方式与常用计算机编程语言的表达方式类似。如 IF 和 CASE 选择
等语句,FOR,WHILE 和 REPEAT 等循环语句都与计算机编程语言类似,大大方便了用户对标准
语言用法的理解,提高了程序的可读性。
 易操作性和安全性
通常而言,易操作性和安全性两者是矛盾的,但在 IEC 61131-3 中,两者被有机的结合。标准
编程语言是常用计算机编程语言的沿用、改进和扩展,因此它保留了这些编程语言的优点,克服了
缺点,使其操作更为简便;同时因为这些语言是标准的,因此出错的概率已被控制到了最低,使编
程语言变得更为安全。

1.2 软 PLC-CoDeSys
PLC 的实现分为硬 PLC 和软 PLC。 所谓硬 PLC 从严格意义上来说是由硬件或者一块专用的
ASIC 芯片来实现 PLC 指令的执行.而软 PLC(SoftPLC,也称为软逻辑 SoftLogic),是使用 PC
机或嵌入式控制器作为硬件支撑平台,利用软件实现硬 PLC 的基本功能。或者说,将 PLC 的控制
功能封装在软件内,运行于 PC 或嵌入式控制器的环境中。
随着二十世纪计算机技术的快速发展,硬 PLC 的通用性及兼容性差等弊端愈来愈明显。而计
算机标准化的通信协议和成熟的局域网技术使组网十分简便,还可以通过 Intemet 与外界相连。一
个具有开放性的系统可以和任何遵守相同标准的其它设备或系统相连。那么能不能将 PC 开放性和
PLC 的可靠性等优点结合在一起呢?国际电工委员会于在 IEC61131-3 的标准中提到,充分利用工
业控制计算机(IPC)或嵌入式控制器(EPC)的硬件和软件资源,全部用软件来实现硬 PLC 能实
现的功能。这就是国际上出现的高新技术一软 PLC 技术。
软件 PLC 综合了计算机和 PLC 的开关量控制、模拟量控制、数学运算、数值处理、网络通信、
PID 调节等功能,通过一个多任务控制内核,提供强大的指令集、快速而准确的扫描周期、可靠的
操作和可连接各种 I/O 系统及网络的开放式结构。所以,软件 PLC 提供了与硬 PLC 同样的功能,
同时又提供了 PC 环境。软 PLC 与硬 PLC 相比,还具有如下的优点:
1) 具有开放的体系结构。软 PLC 具有多种 I/O 端口和各种现场总线接口,可在不同的硬件环
境下使用,突破传统 PLC 对硬件的高度依赖,解决了传统 PLC 互不兼容的问题。
2) 开发方便,可维护性强。软 PLC 是用软件形式实现硬 PLC 的功能,软 PLC 可以开发更为
丰富的指令集,以方便实际工业的应用;并且软 PLC 遵循国际工业标准,支持多种编程语言,开
发更加规范方便,维护更简单。
3) 能充分利用 PC 机的资源。现代 PC 机的强大的运算能力和飞速的处理速度,使得软 PLC 能
对外界响应能迅速作出反应,在短时间内处理大量的数据。利用 PC 机的软件平台,软 PLC 能处理
一些比较复杂的数据和数据结构,如浮点数和字符串等。PC 机大容量的内存,使得开发几千个 I/O
端口简单方便。
4) 降低对使用者的要求,方便用户使用。由于各厂商推出的传统 PLC 的编程方法差别很大,
并且控制功能的完成需要依赖具体的硬件,工程人员必须经过专业的培训,掌握各个产品的内部接
线和指令的使用。软 PLC 不依赖具体硬件,编程界面简洁友好,降低了使用者的入门门槛,节约
培训费用。
5) 打破了几大家垄断的局面。有利于降低成本,促进软 PLC 技术的发展。
1.2.1 软 PLC 控制方案

要实现软 PLC 控制功能,必须具有三个主要部分,即开发系统、对象控制器系统及 I/O 模块。


开发系统主要负责编写程序,对软件进行开发。对象控制器及 I/O 模块是软 PLC 的核心,主要负责
对采集的 I/O 信号进行处理,逻辑控制及信号输出的功能。
1. 开发系统
软 PLC 开发系统实际上就是带有调试和编译功能的 PLC 编程软件,此部分具备如下功能:编
程语言标准化,遵循 IEC61131-3 标准,支持多语言编程(共有 5 种编程方式:IL,ST,LD,FBD
和 SFC),编程语言之间可以相互转换;丰富的控制模块,支持多种 PID 算法(如常规 PID 控制算
法、自适应 PID 控制算法、模糊 PID 控制算法、智能 PID 控制算法等),还包括目前流行的一些控
制算法,如神经网络控制;开放的控制算法接口,支持用户嵌入自己的控制算法模块;仿真运行,
实时在线监控,在线修改程序和编译;网络功能。支持基于 TCP/IP 网络,通过网络实现 PLC 远程
监控, 远程程序修改等。
2. 对象控制器系统及 I/O 模块
这两部分是软 PLC 的核心,完成输入处理、程序执行、输出处理等工作。通常由 I/O 接口、通
信接口,系统管理器、错误管理器、调试内核和编译器组成:I/O 接口,可与任何 I/O 信号连接,
包括本地 I/O 和远程 I/O,远程 IO 主要通过现场总 InterBus,ProfiBus,CAN 等实现;通信接口。
通过此接口使运行系统可以和开发系统或 HMI 按照各种协议进行通信,如下载 PLC 程序或进行数
据交换;系统管理器,处理不同任务和协调程序的执行;错误管理器,检测和处理程序执行期间发
生的各种错误;调试内核,提供多个调试函数,如强制变量、设置断点等;编译器,通常开发系统
将编写的 PLC 源程序编译为中间代码,然后运行系统的编译器将中间代码翻译为与硬件平台相关
的机器码存入控制器。
3. 综合控制方案

软 PLC 开发系统

串口/以太网

现场总线/以太网

嵌入式控制器 I/O 信号
软 PLC 实时核运行系统

图 1.4 嵌入式软 PLC 控制系统


软 PLC 控制器的硬件平台主要可以分为如下三部分:
1) 基于嵌入式控制器的控制系统 嵌入式控制器是一种超小型计算机系统,一般没有显示器,
软件平台是嵌入式操作系统(如 Win CE,VxWorks 和 QNX 等)。软 PLC 的实时控制核被安装到
嵌入式控制系统中,以保证软 PLC 的实时性,开发完的系统通过串口或以太网将转换后的二进制
码写入到对象控制器中,如图 1.4 所示。
2) 基于工控机(IPC)或嵌入式控制器(EPC)的控制系统 该方案的软件平台可以采用
Windows 操作系统(Windows XP Embedded,Windows 7 等),通用 I/O 总线卡负责将远程采集的
I/O 信号传至控制器进行处理,软 PLC 可以充当开发系统的角色及对象控制器的角色。目前市场上
越来越多的用户更倾向于直接使用面板型工控机进行控制的方案,这样的方案直接集成了 HMI,开
发系统及对象控制器的功能,大大降低了成本,其控制方案如图 1.5 所示。
开发系统/对象控制器
Windows 操作系统
I/O 信号

现场总线/
以太网

图 1.5 工控机或嵌入式计算机的控制系统
3) 基于传统硬 PLC 的控制系统 此方案中,PLC 开发系统一般在普通 PC 机上运行,而传统硬
PLC 只是作为一个硬件平台,将软 PLC 的实时核安装在传统硬 PLC 中,将开发系统编写的系统程
序下载到硬 PLC 中,其控制系统图如图 1.3 所示,区别是将图中的嵌入式控制器替换成传统硬 PLC。

1.2.2 软 PLC 的发展方向

1. 硬件/系统平台
软 PLC 采用开放式结构的软件控制技术,将一台标准的工业控制计算机改变为一个具有 PLC
全部功能的过程控制器。可以想象,微处理等硬件的快速发展(如 Intel 等处理器生产厂家)和操
作系统等软件的快速发展(如 Microsoft 操作系统提供商等)势必也会带动软 PLC 的快速发展,并
使其技术和产品日趋完善。
当 IEC 61131-3 编程标准问世及在其影响下的开放式结构,使得通用 PC 或嵌入式系统有可能
代替传统 PLC,成为新型 PLC 一软 PLC。其典型的系统结构是工控机或嵌入式系统+I/O 接口+软
PLC 软件包。软 PLC 产品是基于 PC 或嵌入式系统开放结构的控制装置,它具有硬 PLC 在功能、
可靠性、速度等方面的特点,利用软件技术可将标准的工业 PC 或嵌入式系统转换成全功能的 PLC
过程控制。
2. 编程语言
以往各个 PLC 生产厂家的产品不仅硬件各异,其编程方法也是五花八门,如三菱,西门子,
欧姆龙等都有自己独立的编程软件,其 I/O 映射的方法也有所不同,用户每使用一种 PLC 时,不但
要重新了解其硬件结构,此外还需要重新学习编程方法及其规定。为减轻用户学习负担,也为了统
一行业内的编程规范,IEC 于 1993 年发布了 IEC 61131-3 有关可编程序控制器编程的标准。以往各
个 PLC 生产厂家的产品互不开放,要将几个 PLC 厂家的产品连接在同一个网络里是很困难的,而
以通用的 PC 或嵌入式控制器取代各制造厂专用 PLC,可使系统从封闭走向开放。

1.3 CoDeSys 概述
CoDeSys 软件商由德国 Smart software solution GmbH 公司所开发,该公司位于德国巴伐利亚州
肯普腾市。
CoDeSys 是可编程逻辑控制 PLC 的完整开发环境(CoDeSys 是 Controlled Developement System
的缩写),在 PLC 程序员编程时,CoDeSys 为强大的 IEC 语言提供了一个简单的方法,系统的编
辑器和调试器的功能是建立在高级编程语言的基础上(如 Visual C++)。
现在国内 PLC 用户使用的版本多为 CoDeSys V2.3, 最新的版本是 CoDeSys V3。V3 在软件架
构上有了很大的改善,朝安全软件的方向发展,目前已获取 TUV 关于 EN 61508 的安全 PLC 认证,
用户可以在基于 CoDeSys 平台上开发属于自己的 SIL2 及 SIL3 安全 PLC。
CoDeSys 是一款软件,并不依赖特定硬件如 ABB、Bachmann、IFM 易福门、EPEC 派芬、
HOLLYSYS 和利时,intercontrol 的 PROSYD1131、赫思曼公司 iFlex 系列、力士乐的 RC 系列、TT
control 公司 TTC 系列控制器等 PLC 厂家都是使用 CoDeSys 平台开发自己的编程软件的。国内首家
采用 CoDeSys 平台的国产 PLC 和声 HSC C3 系列控制器也已大批量产业应用。
同 时 , 也 有 运 动 控 制 厂家 如 : Scheider Electric 、BECKHOFF、 GoogolTech 等 也 都 在 使 用
CoDeSys 平台开发自己的编程软件。

1.3.1 CoDeSys 自动化解决方案

CoDeSys 以自动化软件开发平台 CoDeSys Automation Development Suite(工具包套件)为核心,


向全球用户提供开发灵活的解决方案。CoDeSys 自动化解决方案示意图如图 1.6 所示。

图 1.6 CoDeSys 自动化解决方案示意图


CoDeSys 包括 PLC 编程、可视化 HMI、安全 PLC、控制器实时核、现场总线及运动控制,是
一个完整的自动化软件。
CoDeSys 是可编程逻辑控制 PLC 的开发环境 Controlled Developement System 的缩写,它为 IEC
语言提供了一个简单的方法,系统的编辑器和调试器的功能是建立在高级编程语言的基础上。其功
能强大,易于开发,可靠性高,开放性好并且集成了 PLC、可视化、运动控制及安全 PLC 的组件。
它从架构上基本上可以分为三层,应用开发层,通信层和设备层。CoDeSys 结构示意图如图 1.7 所
示。
开发层 IEC 61131-3 硬件/现场 可视化界 运动控制
编辑器/编译器 总线配置器 面编程 模块

CoDeSys 应用层开发系统

通讯层 CoDeSys
OPC 服务器

CoDeSys 网关服务器

设备层
CoDeSys 实时核系统

IEC 61131-3
应用程序

图 1.7 CoDeSys 架构示意图


1. 应用开发层
PLC 编程系统,PLC Development System CoDeSys(具有完善的在线编程和离线编程功能)、
编译器及其配件组件、可视化界面编程组件等,同时供用户可选的运动控制模块可使其功能更加完
整和强大。
 IEC61131-3 编辑器。CoDeSys 提供了所有 IEC61131-3 所以定义的五种编程语言:如结构化
文本(ST)、顺序功能图(SFC)、功能块图(FBD)、梯形图(LD)和指令表,此外还支持连
续功能图(CFC)的编程语言。
 编译器。负责将 CoDeSys 中的应用程序转换为机器代码并且优化可编程控制器的性能。当
用户输入了错误的应用程序代码时,立刻会接收到编译器发出的语法错误警告及错误信息,让编程
人员可以迅速做出相应纠正。
 硬件/现场总线配置器。针对不同制造商的硬件设备及不同现场总线协议,该部分负责在
CoDeSys 中对相应参数进行设定。
 可视化界面编程。直接在 CoDeSys 中即可实现可视化编程(人机界面 HMI),系统已经集
成了可视化编辑器。
 运动控制模块。运动控制功能已经集成在 CoDeSys 中,形成了 SoftMotion(CNC)软件包。
基于 PLCopen 的工具包可以实现单轴、多轴运动;电子凸轮传动;电子齿轮传动;复杂多轴 CNC
控制等。
2. 通信层
应用开发层和设备层之间的通讯是由 CoDeSys 中的网关服务器来实现的,CoDeSys 网关服务器中
安装了 OPC 服务器。
 CoDeSys 网关服务器。作用在应用开发层和硬件设备层之间,可以使用 TCP/IP 协议或通过
CAN 等总线实现远程访问,是 CoDeSys 开发工具包不可分割的一部分。
 CoDeSys OPC 服务器。对基于 CoDeSys 进行编程的控制器,无需考虑所使用的硬件 CPU,
已经集成并实现了 OPC V2.0 规范的多客户端功能,且能同时访问多个控制器。
3. 设备层
使用基于 IEC 61131-3 标准的编辑开发工具 CoDeSys 对一个硬件设备进行操作前,硬件供应商必须
要在设备层预先安装 CoDeSys 的实时核。
 CoDeSys 实时核系统。关于实时核的会在下节中会有详细介绍。
 IEC 61131-3 应用程序。用户在开发层写完的程序通过以太网或串口下载至设备层中,最终
该应用程序中的文件已经被转为二进制存放在目标设备中,根据用户设定的执行方式循环执行对应
程序。
1.3.2 CoDeSys 实时核

PLC 是一种实时计算机控制系统,软 PLC 也不例外。其中的执行程序部分对实时性有着很高


的要求。如果不能在系统要求的时间内完成 PLC 程序的执行,会影响数据的采集和输出,无法完
成控制任务。另外,作为工业控制系统,PLC 系统必须对工业现场的突发情况作出及时有效的响应,
否则可能危机人身和设备安全。PLC 工作过程中,需要对各个元件的实时状态进行监控,所以 PLC
系统运行在实时平台上。
CoDeSys 的实时核可以运行在各种主流 CPU 上(如 ARM、X86、PowerPC、TriCore 、DSP
等),并支持 Windows XP、Windows CE、Windows XP Embedded、Windows 7、Linux、VxWorks 、
QNX 等操作系统中。本节以 Windows 系统举例,对其系统的实时性进行详细分析。
1. Windows 实时性分析
由于 Windows 本身不是实时系统,故不能直接作为软 PLC 的载体,具体分析如下,
1) Windows 无法提供高精度的定时器,故不能保证程序运行的实时性;
2) Windows 所有线程都是该系统的普通现场横,不能提供实时服务;。
3) 系统事件存在延迟。;
4) Windows 对分页内存的访问时间不可预知。
2. Windows 实时性扩展技术
为了使 Windows 能用于实时控制系统,需要解决实时性问题,目前采用的解决方案主要有两
种:1. 插卡方案(Windows 系统+硬件板卡);2. 实时扩展方案(Windows 系统+实时扩展),其原理图
如图 1.8 所示,CoDeSys 采用的是实时扩展的方案。通过软件的方式对 Windows 进行实时性能的改
造,使其具有实时性。系统的实时任务和非实时任务都由软件完成,硬件板卡只实现简单的输入输
出功能,因此只需廉价的通用的 I/O 板卡,脉冲板卡,大大减少了软 PLC 系统的成本。
非实时功能部分 非实时功能部分
操作系统

操作系统
实时功能部分

实时扩展
实时功能部分
现场数据输入/输出和采
硬件板卡 集 现场数据输入输出和采
集 硬件板卡

a)插卡型 a)实时扩展型

图 1.8 插卡型和实时扩展型控制方案

3.Windows 实时性问题的解决方案
CoDeSys RTE 即实现了这样的技术,它对 Windows 的内核进行了恰当了实时性改造,使其保
证具有微妙级抖动量的确定性,且不需增加其他硬件。最终实现“硬实时”的功能。
通过实时核进行任务的管理和调度,降低了实时控制系统的设计和难度,提高了实时性和可维
护性,当使用 PC 实现软 PLC 时,使用 CoDeSys 实时核,其内部结构如图 1.9 所示。
EtherNet
串口输入设备

显示器 存储设备 以太网 串口

Windows 应用程序平台/SCADA CoDeSys 开发系统


应用层

Windows 内核与设备驱动 CoDeSys SP 内核层


RTE

I/O 映射

CANopen Profibus DeviceNet EtherCAT Sercos 。。。

图 1.9 Windows PC 设备实时核系统结构


故只要在 PC 机上安装软 PLC CoDeSys RTE 软件,那么根据 PC 机的功能,他就会变成一台先
进的高性能可编程控制器。PLC CoDeSys RTE 可以运行在装有 Windows NT、Windows2000 或
Windows XP/7 等操作系统的标准工业 PC 上。
此外,CoDeSys 也能针对其他非 Windows 操作系统安装实时核,如嵌入式控制器,其结构如
图 1.10 所示。嵌入式控制器也能进行 I/O 扩展,现场总线扩展等功能,只需要在 CoDeSys 开发平
台中相应设置即能实现扩展功能。CoDeSys 实时核被预先安装在嵌入式控制器内,只需要在上位
CoDeSys 开发系统中将事先写完的程序直接下载到设备中,CoDeSys 就已将用户代码转换为二进制
代码存入嵌入式控制器内,实现实时控制。

上位开发
CoDeSys 开发系统

设备

CoDeSys 嵌入式实时核

图 1.10 嵌入式控制器实时核系统结构

1.4 软件的安装
CoDeSys 编程软件是标准的 Windows 界面,支持编程、调试及配置,可与 PLC 控制器进行多
种方式的通讯,如串口、USB 及以太网等。
1.4.1 安装所需的软硬件要求

1. 硬件及软件的基本要求
由于 CoDeSys V3.5 软件比较大,处理信息也较多,对 PC 的硬件及软件有一定要求,其要求的
最低配置及推荐配置如表 1-1 所示。
描述 最低配置 推荐配置
操作系统 Windows 2000 (Windows XP / Windows Windows XP / Windows 7
Vista/Windows 7)
内存 512MB 1GB
硬盘空间 200MB 1GB
处理器 Pentium V, Centrino > 1,8 GHz, Pentium Pentium V, Centrino > 3,0 GHz, Pentium M >
M > 1,0GHz 1,5GHz

1.4.2 安装

1. 安装
直接双击运行 Setup_CODESYSV<Version>.exe 安装文件即可进入安装,整个安装过程中安装
助手都会引导用户进行安装。
2. 卸载
CoDeSys 编程软件的卸载可以通过 Windows 的控制面板的添加和删除程序来完成。打开“控
制面板”-->“添加/删除程序”,选中“CoDeSys”,单击删除按钮,根据提示完成卸载。
3. 版本管理
在 CoDeSys 中可以同时安装一个组件的多个版本,并且可以组合使用这些版本,编译器也可
以安装和使用多个版本,而且无需更新整个版本就可以新增独立的功能。

1.4.3 启动编程软件

进入开始菜单,找到默认路径,程序—>3S CODESYS—>CODESYS—>CODESYS V<version>,

或者,当安装完成后,可以直接在桌面找到 CoDeSys 图标 ,双击运行打开。

1.4.4 帮助

用户在打开 CoDeSys 应用程序后,可以找到帮助菜单,点击“目录”即可打开在线帮助。用


户可以根据索引或者搜索关键字快速找到所需要的内容,如图 1.11 所示。
图 1.11 帮助文档

1.4.5 CoDeSys 开发系统

PLC Development System CoDeSys 是整个自动化开发平台的核心(以下简称为 CoDeSys),它几


乎包含了一个先进的自动化开发工具所应具有的所有功能。 本书所有的样例程序均使用的是
CoDeSys V3.x 版本,图 1.12 为 CoDeSys V3.x 开发系统的界面,标准组件主要有菜单栏、工具栏、
编辑窗口、设备窗口、POU 窗口、监视窗口、消息窗口、在线模式、位置信息等。下面对用户开
发环境做详细的介绍。
在 CoDeSys V3.x 中,所有的窗口及视图都不是固定的,用户可以根据自己的习惯将窗口和视
图通过鼠标拖拽的方式移动到目标位置,将窗口和视图进行重新排列。
图 1.12 CoDeSys V3.x 用户界面示例

4. 菜单栏
在 CoDeSys 中,菜单栏是使用最为频繁的操作选项,所有的项目新建及保存,程序编译,登
入及下载,调试时的设置断点及强制写入等功能都需要菜单栏里的功能来实现,在 CoDeSys V3.x
中,能实现的具体内容如表 1-2 所示。

表 1-2 菜单栏功能列表
菜单名 内容
文件 对工程文件进行操作 (打开、关闭、保存、打印、页面设置、下载/上载源代码等)。
编辑 编辑器(如语言编辑器、声明编辑器)操作。
视图 激活特定的标准视图,例如:在用户界面中的某个窗口中显示视图。与窗口菜单功能类似。
工程 编辑工程对象和工程基本信息、拷贝工程、合并工程、导出工程、配置库及用户管理。
编译 编译工程,例如:1)包含语法检查的预编译运行;2)当采用在线修改和离线代码生成的方法时,可
以删除上一次的编译信息(清空)。
在线 登入退出控制器,加载控制器上的工程和复位。
调试菜单 控制运行在控制器上的程序(启动,停止)和调试操作(断点,单步,写入,强制)。
工具 该菜单包含的命令可以打开工具,这些工具用来配置工程的操作环境(例如:库和设备的安装、用户
界面自定义、编辑器选项、加载和保存等)。
窗口 操作用户界面中的各个窗口(如排列、打开、关闭等命令)。与视图菜单功能类似。
帮助 打开在线帮助,获取系统帮助信息。
5. 工具栏
通过在一个符号上点击鼠标,用户可以更快的选择一个命令。可以选择的符号将自动的与激活
的窗口相适应。仅当鼠标在符号上点击然后释放时,才能执行命令。如果用户将鼠标指针短时停留
在工具栏上的一个符号时,则会在工具提示中显示该符号的名称。菜单栏如图 1.13 所示。
图 1.13 工具栏
当用户选择不同的对象时,工具栏里的内容会略微发生改变,如使用梯形图(LD)的 POU 时,
工具栏里会有触点,线圈等功能,而当选用功能块图(FBD)时,则会出现添加功能块等选项。工
具栏的按钮也不是固定的,用户可以根据自己的使用习惯自定义其中的内容。
6. 编辑窗口
用于在相应的编辑器中创建特定的对象。 语言编辑器(例如 ST-编辑器,CFC-编辑器)一般
是语言编辑器和声明编辑器的组合 ,通常在下部是语言编辑器,上部是声明编辑器。 在其他编辑
器中,还可以提供对话框 (例如:任务的编辑器,设备编辑器)。POU 或资源对象的名称始终显
示在窗口的标题栏中。在离线或在线模式下通过 “编辑对象” 命令可以在编辑器窗口中打开对象。
7. 设备窗口
以树形结构管理工程中的资源对象。在项目中,数据分层结构中以对象的形式进行保存。
8. POU 窗口
以树形结构管理工程中的编程单元。
9. 监视窗口
显示一个 POU 的监视视图,当程序登入后,可以用来监视 POU 中任意的表达式。
10. 消息提示栏
消息窗包含显示预编译,编译,生成器,下载和程序检查信息。如果你用鼠标双击消息窗内的
一条消息或按 <转移到源代码处>,编辑器就会打开所选择行的对象。通过右键鼠标→“后一个消息”
(F4 功能键)以及“前一个消息”(Shift+F4 组合功能键),你可以在各个错误消息之间快速跳转。
消息窗的显示是移动的,消息窗口详见图 1.14 所示。

图 1.14 消息提示框
1) 在线模式信息
具体状态信息如表 1-2 所示。

表 1-2 在线模式状态描述
状态 描述
程序正在运行。

程序已经停止。

程序停止于断点。

CoDeSys 目前正处于无硬件仿真模式。

程序已下装到设备上。
设备上的程序与编程系统中的相符。

设备上的程序与编程系统中的不同,需要在线更改。

2) 位置信息
位置信息如图 1.15 所示,
图 1.15 位置信息
行:光标所指位置的行号。
列:光标所指位置的列号。
字:光标所指位置的字符数,字符可以是单个字符或数字也可以是一个制表符。

1.5 获取资料、插件和技术论坛
可以在 3S 的官方主页 http://www.codesys.com 下载相关软 PLC 资料。进入网站主页后点击
“Download”页面,就可以进入各种版本的 CoDeSys 软件下载页面。点击“Categories”中的
“Documentation”可以下载软件相关使用说明。
http://store.codesys.com/为 CoDeSs 商店的地址,用户可以登入下载一些常用的样例程序及小插
件。
另外可以在主页中的“Support & Training”中点击“CODESYS Forum”中获得各种产品的技
术支持,包括常见问题的解答等。
第2章 软件模型
本章主要知识点
 CoDeSys 软件模型
 任务配置
 程序组织单元(POU)
 应用对象

2.1 软件模型
CoDeSys 的软件模型用分层结构表示。每一层隐含其下面层的许多特性。软件模型描述基本的
软件元素及其相互关系。这些软件元素包含:设备、应用、任务、全局变量、访问路径和应用对象,
他们是现代软 PLC 的软件基础,其内部结构如图 2.1 所示,该软件模型与 IEC 61131-3 标准的软件
模型保持一致。

图 2.1 软件模型结构
该软件模型从原理上描述了如何将一个复杂程序分解为若干小的可管理部分,并在各分解部分
之间有清晰和规范的接口方法。软件模型描述了一台可编程控制器如何实现多个独立程序的同时运
行,如何实现对程序执行的完全控制等。
1. 设备
在模型的最上层是“设备”,CoDeSys V3 之前的版本将其称之为“配置”。 “设备”可以等
效于一个 PLC 所需的所有软件。针对大型复杂的应用系统,如整个产品线的自动化,可能需要多
个 PLC 联机通讯,需要将一个 PLC 与其他多个设备接口实现总线通信。这时,可以将“设备”理
解为一个特定类型的控制系统,它包括硬件装置、处理资源、I/O 地址映射和系统内存存储的能力,
即等同于一个 PLC。
2. 应用
在 PLC 系统中,设备将所有“应用”结合成组,为“应用”提供数据交换的手段。在每一个
设备中,有一个或多个“应用”,应用位于软件模型的第二层,在 CoDeSys V2 的版本内称之为
“资源”。“应用”不仅为运行程序提供了一个支持系统,而且它反映了 PLC 的物理结构,在程
序和 PLC 物理 I/O 通道之间提供了一个接口。
应用被分配在一个 PLC 的 CPU 中,因此,可将应用理解为一个 PLC 中的微处理器单元。在应
用内定义的全局变量在该应用内部是有效的。应用的主要成员包括全局变量、任务和程序组织单元
(POU)等,在 2.3 节会详细对这些应用对象进行介绍。
3. 访问路径
访问路径的主要功能是将全局变量、直接表示变量和程序组织单元的输入/输出变量联系起来,
实现信息的存储。它提供在不同应用之间交换数据和信息的方法,每一个应用内的变量可通过其他
远程配置来存取。
4. 通讯功能
提供与其他系统、如其他可编程控制器系统、机器人控制器、计算机等装置的通讯,用于实现
程序传输、数据文件传输、监视、诊断等。通常采用符合国际标准的通讯方式(如 RS232、RS485)
或工业现场总线如 CANopen、Profibus、EtherCAT、Modbus、Ethernet/IP、DeviceNet 等。

2.1.1 软件模型的特点

该软件模型具有如下特点:
 在一台 PLC 中能同时装载、启动和执行多个独立的程序。
 实现对程序执行的完全控制能力:标准的任务机制,保证了 PLC 系统对程序执行的完全
控制能力。传统 PLC 程序只能顺序扫描执行程序,对某一段程序不能按用户的实际要求
定时执行,而该软件模型中任务的机制允许程序的不同部分在不同的时间、以不同的比率
并行执行,这大大地扩大了 PLC 的应用范围。
 该软件模型能够适应不同的 PLC 结构:该软件模型是一个国际标准的软件模型,它不是
针对具体的 PLC 系统,而是具有很强的适用性。既能适合小型的 PLC 系统,也可适合较
大的分散系统。
 支持程序组织单元的重用特性:软件的重用性是 CoDeSys 的重要优点。
 支持分层设计:一个复杂的软件通常可以通过一层层的分解,最终分解为可管理的程序单
元。

2.2 设备
设备位于 CoDeSys 软件模型的最上层,设备代表了一个具体的目标,即硬件对象。该硬件对
象可以是控制器,现场总线站点,总线耦合器,驱动器,输入/输出模块或是触摸屏等。每一个设
备由一个“设备描述”文件定义,该设备描述文件安装在 CoDeSys 本机系统中,以供插入到设备
树下(这里用“设备树”表示设备窗口中的树状列表) 。该设备描述文件确定了设备的相关配置、
可编程性、和其他设备的互联性。设备是结构元素,它位于软件模型的最上层,在软件内部是大型
的语言元素。

2.2.1 添加设备

新建一个工程时,系统会自动弹出对话框,如图 2.x 所示。用户可以在模板选项中选择新建一


个空工程或标准工程,在选择标准工程时,需要用户选择实际连接的硬件设备。
图 2.2 目标设备选择
点击“确定”后,在项目中可以看到如图 2.2 中所示的设备树。

图 2.X 设备树
在 CoDeSys V2 的版本中“PLC 配置”和“任务配置”列表都是独立窗口,而在 V3 中都整合
在设备树中。当需要进行“PLC 配置”和“任务配置”时,会弹出相应的对话框,供用户进行具体
的参数设置。在设备树中,通过各类“设备”对象表示了工程的硬件设备系统,这样可以组建一个
包含多种控制器和总线结构的复杂系统。每个在设备树的节点都有名字,名字是可编辑的;还有设
备类型来描述该设备。
一个设备的类型决定了其在资源树中的位置和哪些资源能配备给该设备。可供“设备”有如下
两种,
 可编程设备
 参数型设备
“可编程设备”,会自动在该设备的节点下插入一个额外的虚节点: “ PLC 逻辑“这样来
表示它是可编程的。在这个“PLC 逻辑“节点下,您可以插入对该设备编程所需要的对象(如应用
程序,文本列表等),以及其他的功能对象(如参数管理器等)。对“参数型设备”不能分配编程
对象(如应用程序),而是在该设备的编辑对话框中设置它的参数。请注意,如果一个设备的属性
允许的话,它是可以直接在这两种类型中切换的,而不需要把该设备删除后再重新插入到设备树中。
设备的通讯、输入/输出映射等参数在设备对话框(即设备编辑器)中设置,用户可以双击设
备树中该设备的节点打开这个对话框。
1. 包管理器
所有的“设备”必须事先在“包管理器”中进行安装,包管理器在“工具”菜单中可以选择,
用户可以对其进行添加或删除包。
针对不同的硬件设备,需要不同的硬件配置参数,其中必须配置的参数有:代码生成器,内存
管理,PLC 功能,I/O 模块配置,另外,必须链接库,网关驱动程序以及用于错误消息的 ini-files 和
PLC 浏览器的相关信息。此外包中整合了特殊功能,包含了相应的库文件,设备描述文件等。
启动 CoDeSys V3.x 后,在“工具”选项中选择“包管理器”进行安装目标支撑软件包(TSP),
安装程序是 Codesys-Setup 的一部分。目标支撑软件包(TSP)包含对于用 Codesys 建立的程序控制一
个标准平台所必需的所有文件和配置信息。TSP 的核心组成部分是一个以上的目标文件。目标文件
管理那些配置目标系统所必须的附加文件。几个目标文件可以共享这些附加的文件。目标文件的默
认扩展名是*.trg,格式是二进制的。若干附加定义连接到在目标文件中的条目上,它们决定用户是
否能看见和编辑在 Codesys 对话框中设置。在 TSP 安装期间,每个目标的目标文件被放入一个 0 单
独的目录中并且注册了它的路径。根据文件*.package 的信息,把相联系的文件拷贝到计算上。目
标目录的名称与目标的名称一样。当启动 CoDeSys 时,读入用 TSP 安装的文件。用项目保存在
Codesys 对话框中完成的目标设置。

图 2.X 包管理器
如果没安装目标之称软件包,只能选择“None”,这意味着在仿真模式下工作。
2. 设备库
设备库是当用户添加或删除硬件设备信息时所需要做的操作,设备库是设备的数据库,安装后
的所有数据被导入至用户本地系统中,供 CoDeSys 开发使用。设备库对话框如图 2.x 所示。

图 2.X 设备管理对话框
设备库可用于添加所有的硬件设备,通过在该选项中导入相应文件后,使对应数据在本地系统
内生成,方便工程中调用。可添加的设备有供应商的 PLC,SoftMotion 运动控制设备(编码器,驱
动器等)、现场总线及专用接口等设备,关于现场总线可添加的文件一般也为设备供应商所提供的
相应设备描述文件,可分为如 CANopen 的 EDS 和 DCF 文件,EtherCAT 的 XML 文件、IO-Link 的
IODD 和 Profibus DP 的 GSD 文件等。图 2.x 中具体选项的含义详见表 2-x 所示:

表 2-x 设备库
名称 说明
路径 选中的列表提供了当前可用的路径。“系统库”是 CoDeSys 默认安装的。
安装的设备描述 当前已安装的设备以树形结构列出,每一个显示了名称,供应商名称和设备版
本。设备目录也可以用类别的方式显示,如按“PLCs”和"Miscellaneous"显示。
细节 此对话框显示设备描述文件给出的附加信息:设备名称、供应商名称、类别、版
本和描述等。
安装 用此按钮来安装一个设备使它在系统中可用。“安装设备描述”对话框将打开,在
此对话框里可以浏览系统中各自设备的描述。
卸载 此命令将删除当前选中的设备。选中的设备将从设备库中删除,并且在程序系统
中不再可用。
此选项只负责安装、卸载以及供用户查看设备信息,只有从属设备在设备库添加完后,用户才
能在“添加设备”选项卡中找到相应的从属设备,否则不能使用该从属设备。

注意:
安装过程中所引用的设备描述文件和所有的附加文件将会被复制到一个内部地址中。改变原始文档将不会
影响已安装的设备。在设备被改变之后,改变设备描述的内部版本号是一种很好的做法。
内部设备库绝不能手动改变。不要从那里复制文件或者复制文件到那里。必须需要使用“设备库”对话框
来重装,添加或者删除设备。

2.2.2 设备编辑器

设备编辑器是用于配置设备的对话框。通过选中设备图标 ,通过鼠标右键“编辑
对象”命令,或者通过在设备窗口中双击设备对象条目打开。
主对话框是根据设备类型,以设备名称来命名的 ,它提供了包含以下子对话框的选项卡,如
表 2-x 所示。

表 2-x 设备编辑器选项卡
名称 说明
通讯设置 目标设备和其他可编程设备(PLC)之间连接的网关配置。
配置 分别显示设备参数的配置
应用 显示目前正在 PLC 上运行的应用,并且允许从 PLC 中删除应用
文件 主机和 PLC 之间的文件传输的配置
日志 显示 PLC 的日志文件
PLC 设置 与 I/O 操作相关的应用、停止状态下的 I/O 状态、总线周期选项的配置
I/O 映射 I/O 设备输入和输出通道的映射
用户和组 运行中设备访问相关的用户管理(不要与工程用户管理混同)
访问权限 特殊用户组对运行中的对象和文件访问权限的配置
状态 设备的详细状态和诊断信息
信息 设备的基本信息(名称、供应商、版本、序列号等)
此表所罗列的为基本设备参数,不同的硬件设备可能与上表参数有略微的差别。
2.3 应用
应用在 CoDeSys V3.x 之前的版本中也称之为“资源”,是指
在硬件设备(如 PLC)上运行程序时所需要的对象集合。这些对
象与硬件设备平台无关,用户可以在程序组织单元(POU)中管
理它们。然后在设备窗口中将它们实例化,分配到具体的设备中。
这种方法符合面向对象编程的思想。
应用对象包括任务,程序组织单元、任务配置、全局变量、
库管理器和采样追踪等。在 CoDeSys V3.x 中资源对象只能在设备
树中进行管理。在设备树中添加对象后,需要按一定的“规则”
与被控设备进行映射。对象(如库和全局变量列表等)在工程中
的有效范围,会依据设备树中应用和设备对象的层级关系而定,
一般来说,一个应用中的对象对其“子应用”也有效,可以被使
用。关于应用对象,在 2.4 节会对其进行详细介绍。
在一个设备内可有一个或多个应用,如下图 2.x 所示,该设
备中有 App1 和 App2 两个应用。

图 2.x 在一个设备中添加两个应用

2.3.1 任务

1. 概述
一个程序可以用不同的编程语言来编写。典型的程序由许多互连的功能块组成,各功能块之间
可互相交换数据。在一个程序中不同部分的执行通过“任务”来控制。“任务”被配置以后,可以
使一系列程序或功能块周期性地执行或由一个特定的事件触发开始执行程序。
在设备树中有“任务管理器”选项卡,使用它除了声明特定的 PLC_PRG 程序外,还可以控制
工程内其他子程序的执行处理。任务是用于规定程序组织单元在运行时的属性,它是一个执行控制
元素,具有调用的能力。在一个任务配置中可以建立多个任务,而一个任务中,可以调用多个程序
组织单元,一旦任务被设置,它就可以控制程序周期执行或者通过特定的事件触发开始执行。
在任务配置中,用名称、优先级和任务的启动类型来定义它。这启动类型可以通过时间(周期
的,随机的)或通过内部或外部的触发任务时间来定义,例如使用一个布尔型全局变量的上升沿或
系统中的某一特定事件。对每个任务,可以设定一串由任务启动的程序。如果在当前周期内执行此
任务,那么这些程序会在一个周期的长度内被处理。优先权和条件的结合将决定任务执行的时序,
任务设置界面如图 2.x 所示。
图 2.X 任务配置图
由于 CoDeSys V3.x 在任务配置时有如下的属性,编程者需遵循如下规则:
 循环任务的最大数为 100。
 自由运行任务的最大数为 100。
 事件触发任务的最大数为 100。
 根据目标系统,PLC_PRG 可能会在任何情况下作为一个自由程序执行,而不用插入任务配置
中。
 处理和调用程序是根据任务编辑器内自上而下的顺序所执行的。
2. PLC 程序执行过程
图 2.x 详细的描述了在 PLC 内部执行程序的完整流程,主要有输入采样,程序执行和输出刷新
这三个重要的步骤组成。

读输入
1.输入采样
映像寄存器

任务 1
任务 2 2.程序执行

映像寄存器
3.输出刷新
写输出

图 2.X PLC 执行程序


1) 输入采样
每次扫描周期开始时,PLC 检测输入设备(开关、按钮等)的状态,将状态写入输入映像寄存
区内。在程序执行阶段,运行系统从输入映像区内读取数据进行程序解算。输入映像区的刷新只发
生在一个扫描开始阶段,在扫描过程中,即使输出状态改变,输入状态也不会发生变化。
2) 执行程序
在扫描周期的执行程序阶段,软 PLC 从输入映像区或输出映像区内读取状态和数据,并依照
指令进行逻辑运算和算术运算,运算的结果保存在输出映像区相应的单元中。在这一阶段,只有输
入映像寄存器的内容保持不变,其他映像寄存器的内容会随着程序的执行而变化。
3) 输出刷新
输出刷新阶段亦称为写输出阶段,PLC 将输出映像区的状态和数据传送到输出点上,并通过一
定的方式隔离和功率放大,驱动外部负载。
PLC 在一个扫描周期内除了完成上述三个阶段的任务外,还要完成内部诊断、通信、公共处理
以及输入/输出服务等辅助任务。
由 PLC 的扫描方式可得知,PLC 为了迅速相应输入输出数据的变化,完成控制任务,扫描时
间较短,PLC 的扫描时间一般都控制在 ms 数量级,因此需要开发稳定、可靠、响应快的实时系统
供 PLC 运行系统所用。
PLC 重复执行上述 1)至 3)的过程,每重复一次的时间就是一个工作周期(或扫描周期)。
从 PLC 工作过程中可以了解,由于 PLC 采用循环的工作方式,输入信号只会在每个周期的开
始阶段进行刷新,输出在每个工作周期的结束阶段进行集中输出,所以必然会产生输出信号相对输
入信号的滞后现象。
从 PLC 的输入端有一个信号输入发生到变化到 PLC 的输出端对该输入信号的变化做出反应需
要一段时间。滞后时间是设计 PLC 控制系统时应了解的一个重要参数。
滞后时间的长短和以下因素有关:
 输入电路的滤波时间,它由 RC 滤波电路的时间常数决定。改变时间常数可调整输入延迟时间。
 输出电路的滞后时间,与输出电路的方式有关系,继电器输出方式的滞后时间一般为 10ms 左
右,晶体管输出方式滞后时间小于 1ms。
 PLC 循环扫描的工作方式。
 用户程序中语句的安排。

3. 任务的执行类型
在任务配置树的最顶端有条目“任务配置”。下面是当前定
义的任务,每个通过任务名代表。特定任务的 POUs 调用没有显
示在任务配置树中。
针对每个独立的任务可以对其进行执行的类型编辑及配置。
包括固定周期循环、事件触发、自由运行和状态触发 4 种类型。
详见图 2.x 所示。
图 2.x 任务执行的类型
1) 固定周期循环
根据程序中所使用的指令执行与否,程序的处理时间会有所不同,所以实际执行时间在每个扫
描周期都发生不同的变化,执行时间有长有短。通过使用固定周期循环方式,能保持一定的循环时
间反复执行程序。即使程序的执行时间发生变化,也可以保持一定的刷新间隔时间。在这里,也推
荐大家优先选择固定周期循环任务启动方式。
例如,假设将程序对应的任务设定为固定周期循环方式,间隔时间设定为 10ms 时,实际程序
执行的时序图如图 2.x 所示。
程序实际执行时间
等待时间
0 END 0 END 0 END 0 END

8ms 2ms 6ms 4ms 7ms 3ms 8ms

10ms 10ms 10ms 10ms

固定周期循环设定时间
图 2.x 固定周期循环(Cyclic)执行顺序
如果程序实际执行时间在规定的固定周期循环设定时间内执行完,则空余时间用作等待。如应
用中还有优先级较低的任务未被执行,则剩下的等待时间用来执行低优先级的任务。详见任务优先
级的说明。
2) 自由运行
程序一开始运行任务就被处理,一个运行周期结束后任务将在下一个循环中被自动重新启动。
不受程序扫描周期(间隔时间)的影响。即确保每次执行完程序的最后一条指令后才进入下一个循
环周期。否则不会结束该程序周期。
程序实际执行时间

0 END;0 END;0 END;0 END;0 END;0 END

8ms 6ms 7ms 3ms 8ms 7ms

图 2.x 自由运行(FreeWheeling)执行顺序
该执行方式因为没有固定的任务时间,所以每次执行的时间可能都不一样。故不能保证程序的
实时性,在实际的应用中选用此方式的场合较少。
3) 事件触发
如果事件区域的变量得到一个上升沿,任务开始。
4) 状态触发
如果事件区域的变量为 TRUE,任务开始。
状态触发方式与事件触发功能类似,区别在于状态触发的触发变量只要为 TRUE 程序就执行,
为 FALSE 则不执行。而事件触发只采集触发变量的上升沿有效信号。
图 2.x 中针对事件触发和状态触发分别进行了比较,绿色实线为两种触发方式选择的布尔变量
状态,表 2.x 为比较的结果。

图 2.x 任务输入触发信号
在采样点 1-4(紫色)不同类型的任务展示了不同的反应。这个具体的事件为 TRUE 完成了状
态驱动任务的条件,然而一个事件驱动任务需要事件从 FALSE 变为 TRUE。如果任务计划的采样
频率过低,事件的上升沿可能检测不到。

表 2-x 事件触发与状态触发执行结果比较
执行点 1 2 3 4
事件触发(Event) 不执行 执行 执行 执行
状态触发(Status) 不执行 执行 不执行 不执行
4. 系统事件

用户可选择的系统事件是根据
实际的目标系统而定的,由目标系
统对应的库文件提供相应的系统事
件,所以不同的目标硬件设备对应
的系统事件可能会不同。常用的系
统事件有:停止,开始,登入,改
变等。在任务配置中,可以对任务
配置中的系统事件进行设置。
图 2.x 系统事件
用户可以通过鼠标选择“任务配置”-->“系统事件”进入图 2.x 中显示的界面。选择 “添加事
件处理”按钮可以进行添加系统事件。打开后的界面如图 2.x 的 a)所示。

a) b)

图 2.x 添加事件处理

a) 添加事件处理 b)具体事件
可选择的“事件”类型如图 2.x 的 b)所示。必须在“函数调用”这里必须新建一个函数名,
而不能使用 POU 中已经存在的函数。“实现语言”为对应函数的编程语言。设置完点击“确定”。
5. 任务优先级
CoDeSys 中的可以对任务的优先级进行设置,一共可以设 32 个级别(0 到 31 之间的一个数字,
0 是最高优先级,31 是最低优先级)。当一个程序在执行时,优先级高的任务优先于优先级任务低
的任务,高优先级任务 0 能中断同一资源中较低优先级的程序执行,使较低优先级程序执行被放缓。
注意:
在任务优先级等级分配时,请勿分配具有相同优先级的任务。如果还存在其他任务视图先于具有相同优先
级的任务,则结果可能不确定且不预知。
如果任务的类型为“Cyclic”,则按照“间隔”中的时间循环执行,具体设置如下图 2.x 所示。

图 2.X 固定周期循环配置图
【例 2.X】假设有 3 个不同的任务,分别对应三种不同的优先等级,具体分配如下。
:任务 1 具有优先级 0 和 循环时间 10 ms ,
:任务 2 具有优先级 1 和 循环时间 30 ms ,
:任务 3 具有优先级 2 和 循环时间 40 ms。
在控制器内部,各任务的时序关系如图 2.x 所示,具体说明如下:
0~10ms:先执行任务 1(优先级最高),如在本周期内已将程序执行完,剩余时间执行任务 2
程序。但是如果此时任务 2 没有被完全执行完,但时间已经到了第 10ms 时,由于任务 1 是每 10ms
执行一次的且优先级更高,此时将会打断任务 2 的执行。
10~20ms:先将任务 1 的程序执行完毕,如有剩余时间,再执行上个周期为完成的任务 2。
20~30ms:由于任务 2 是每 30ms 执行一次的,在 10~20ms 之间任务 2 已经全部执行完毕,
此时不需要再执行任务 2,只需将优先级最高的任务 1 执行一次即可。
30~40ms:与之前类似。
40~50ms:此时出现了任务 3,任务 3 的优先级更低,所以只有在确保任务 2 彻底执行完后,
才能执行任务 3。

图 2.x 任务优先级中断执行顺序

6. 看门狗
看门狗是一种控制器硬件式的计时设备,CoDeSys 内可以通过“任务配置”对其进行使能,默
认不使用看门狗功能。
看门狗的主要功能是监控程序执行时出现的异常或内部时钟发生的故障。如当系统出现死机或
当程序进入死循环时,看门狗计时器就会对系统发出重置
信号或停止 PLC 当前运行的程序。我们可以形象的将它
理解为一只小狗需要主人定时的去给它喂食,如果超过规
定的时间没有喂,则他马上就会饿。要配置看门狗,必须
定义两个参数,时间和灵明度,看门狗的配置如图 2.x 所
示。

图 2.x 看门狗设置
1) 时间
CoDeSys 针对每个任务可以配置独立的看门狗。如果目标硬件支持长看门狗时间设置,则可以
设置上限和下限。默认的看门狗时间单位为毫秒(ms)。如果程序执行周期超过看门狗触发时间,
将激活看门狗功能,并将中止当前任务。
2) 灵明度
“灵敏度”用于定义必须在控制器检测到应用程序错误之前发生的任务看门狗例外数。默认为
1,可参照表 2-x。
表 2-x 灵明度设定
灵明度 超过设定时间的倍数
0,1 1
2 2
…… ……
n n
最终的看门狗触发时间=时间×灵明度。如果程序实际执行时间超过看门狗触发时间,则激活
看门狗。例如,时间为 10ms,灵明度设为 5,则看门狗触发时间为 50ms,只要任务的执行时间超
过 50ms,则立即激活看门狗并将任务中止。
7. 任务运行状态监视
每个任务可以直接启用或停用,系统会自动配置一个任务监视器,当进入在线模式后,用户可
以使用系统自带的监视器对任务的平均/最大/最小循环时间等任务执行相关参数进行监控。如图 2.x
所示。
图 2.x 任务监视界面
在项目初期阶段,可以使用该功能测试程序最大/最小/平均循环时间,用于测定程序的稳定性
及对程序设定任务周期时间的优化。监视窗口中每个参数的具体定义见表 2-x。

表 2-x 监视窗口参数定义
参数名 描述 参数名 描述
任务 在任务配置中所定义的任务名 平均循环时间 任务平均所需的执行时
(µs) 间,单位为 µs
状态 分别有如下状态: 最大/最小循环 任务最大/最小执行时
未创建:程序下载后一直未被建立,当使用事件触 时间(µs) 间,单位为 µs
发任务可能会出现此状态。
创建:任务已经在实时系统中建立,但还未正式运
行。
有效: 任务正在被执行。
异常: 任务出现异常。
IEC 循环 程序自开始运行至今的循环累积计数。“0”表示 抖动(µs) 上个周期测量到的抖动
计数 不支持该目标系统。 值,单位为 µs。
循环计数 已经运行的周期计数。取决于目标系统,它可以等 最小/最大抖动 测量得到的最大/最小抖
(µs) 于 IEC 循环计数,或者更大值,此时即使应用程序 时间(µs)” 动时间,单位为 µs。
没运行,周期也一样被计数。

最后循环 上一个任务周期的执行时间,单位为 µs
时间(µs)
了解了如上各时间的定义后,应遵循如下的时间设定关系,按照此设定方法可以更好的优化程
序任务周期及看门狗时间,保障程序的稳定性和程序的实时性。
看门狗触发时间>固定周期循环时间>程序最大循环时间
循环时间比固定周期循环时间长的情况下,CPU 会检测出程序有超出计数,此时,会影响程序
的实时性。如果程序循环时间比看门狗时间设定长的情况下,CPU 会检测出看门狗故障,会停止程
序的执行。
8. 多子程序的运行
在实际的工程项目中,通常可以将程序按控制流程或者按照设备的对象分割成很多子程序,据
此,设计人员将可以按各处理单元分别进行编程。如下图 2.x,以控制流程将主程序拆分为多个不
同流程的子程序,拆分的目的主要是使主程序调理更清晰,并且方便今后的调试。
主程序 PLC_PRG

控制流程 1 子程序 控制流程 1


PRG1

程序拆
子程序
控制流程 2 分后 控制流程 2
PRG2

子程序
控制流程 n 控制流程 n
PRGn

图 2.x 按流程拆分多子程序
图 2.x 中右半部份是按流程进行分类的各子程序 PRG1,PRG2..PRGn,图的左半部分为主程序
PLC_PRG,在主程序中可以分别调用 PRG1..PRGn 的子程序。
多子程序运行的方式有两种,第一种在任务配置中添加子程序。第二种方法是在主程序中调用
子程序,也是比较常用及灵活的一种方式,如下,分别对两种方式的进行详细说明。
1) 任务配置中添加子程序
用户可以通过在任务配置页面中添加子程序实现多程序的运行。按子程序的执行顺序依次点击
“Add Call”进行添加子程序。如图 2.x 所示,添加后,对应的任务即按用户所指定的从上至下的
顺序循环执行,也可以通过“Move Up”和“Move Down”功能再对顺序进行手动编辑。

图 2.x 任务中添加子程序
使用此种方式只要对应的任务被执行,该子程序也会自动被加载执行。
2) 主程序 PLC_PRG 中调用子程序
PLC_PRG 被系统默认为主程序,从某种意义上可以理解为汽车的电瓶,在生产汽车时,将各
个零件进行组装,相当于子程序的编写;当汽车组装完成时,就要检查汽车是否可用,如果想启动
汽车,就必须通过电瓶来启动汽车的各个部件,如发动机、车灯等,电瓶就相当于启动汽车的入口
点。通过这样调用程序使操作性更强及使程序更灵活,能够在程序中加入判断语句等,且能实现嵌
套。

PLC_PRG 是一个特殊的 POU,其默认的运行方式为“FreeWheeling”。系统默认每个控制周


期调用该 POU,用户不需要对其进行额外的任务配置,在任务配置中也看该 POU 相应的配置。
用户可以通过它来实现对其他子程序的调用,更可以在调用时添加必要的条件选择,或实现子
程序嵌套,使程序调用更为灵活。
如果要实现图 2.x 中的调用关系,可以在主程序 PLC_PRG 中写入如下代码。
POU_1 POU_3
PLC_PRG POU_3();
POU_4();
主程序 POU_1();
POU_2();
POU_4

POU_2

图 2.x POU 调用顺序


如图 2.x 中所示,主程序为 PLC_PRG,该主程序使用的是结构化文本编程语言,其中的程序
的内容如下,
POU1();
POU2();
上述程序的主要功能是分别调用执行了 POU_1 和 POU_2 子程序。而 POU_1 中又分别调用了
POU_3 和 POU_4,实际 PLC 内部实际按如下顺序执行程序,
a) PLC 先执行子程序 POU_1,
b) 由于 POU_1 中依次调用了 POU_3 和 POU_4,故先执行 POU_3,
c) 执行 POU_4,POU_1 执行完成,
d) 最后执行 POU_2,完成一个完整任务周期。
重复上述步骤 a)至 d)的即为 PLC 内部的执行顺序。
2.3.2 库文件

在CoDeSys中常会遇到的一个问题是,一些函数或功能块能够找到并可调入编辑区,但打开后
发现是一个空框,输入/输出引脚没有对应,甚至有时根本就没有输入/输出引脚。其根本原因就是
库文件问题所致。所以什么是库文件,它是怎么支持CoDeSys中的项目,本节会对库文件进行详细
介绍。
1. 概述
库文件用于存放CoDeSys中可多次使用的程序
组织单元(POU)。这些POU可以从已有的项目中
复制到库中,用户也可以直接新建库项目v,在项
目中自己定义库。项目中使用的库文件如图2.x所示。
如果在CoDeSys下的库中存放有用户希望多次
调用的功能块、函数或程序时,可以节省大量的编
程时间,并提高效率。CoDeSys标准软件包中已经
包括标准库文件,如图2.x所示。

图 2.X 项目中的库
库文件除了是函数、功能块和程序的集合,其中还包含一些特殊定义的结构体,枚举类型等。
从功能上分可以将库文件分为系统库文件、应用库文件以及厂家自定义库文件。
默认的函数库文件是“.library*”,不同于CoDeSys V2.3版本以及之前版本中的“.lib”文件。
加密库的扩展名为*.compiled-library。库可以通过一个许可证进行加密(加密狗)。
 系统库文件
该库文件是一个支持CoDeSys软件系统的文件,它包括对软件结构和语法编写的支持以及标准
I/O的支持。通常该文件库会在软件启动后自动导入到控制器中,不需要手动添加。
 应用库文件
支持基本应用的文件库。
Util:包含了各种数学运算功能,位操作指令及控制器等功能。
Standard:包括定时器、计数器、边沿检测及双稳态触发器等函数及功能块。
该功能是作为一台PLC必备的功能,因此在打开CoDeSys后会自动调入该库文件。其他的一些
需按要求导入的应用库文件如:Toolbox、PLCopen等,这些库文件都需要用户根据实际需求来进行
添加。如图2.x所示。
图 2.X 应用库文件中的功能块
 厂商自定义库文件
它是根据不同生产厂商硬件设备的环境而配置的应用库。通常,只有使用该生产厂商的硬件才
能匹配对应的库文件。故使用前需要详细阅读该库文件的说明文档。
2. 库文件的管理
库管理器显示与当前项目有关的所有库。库的POU、数据类型和全局变量,都可以像用户定义
的 POU、数据类。库管理器通过“Library Manager”(库管理器)命令打开,包括库在内的有关信
息和项目一起进行保存。
如需安装计算机上的库文件或供应商所提供的库文件进行调用,则需要使用到库文件管理。库
文件管理是通过使用菜单命令“工具”-->“库”来定义的,图2.x为库文件管理视图。

图 2.X 库管理器视图
在图2.x中的主窗口显示的是该CoDeSys目前已安装的库文件,并可以看到提供这些库文件的供
应商。已安装的库文件已按功能类型进行分组,罗列的有应用类、通讯类、控制器类、设备类、系
统类等。
只有在库文件管理器中安装过的库文件才能在项目中被调用,如果库文件不存在或版本过老,
编程人员需要通过“安装”按钮进行手动安装供应商所提供的库文件。
库文件的安装
在使用一个库文件之前,必须先在“库”对话框中
对其进行“安装”。安装后,才可以在项目中调用该库。
CoDeSys V3.s 共有三种类型的库文件可供用户安装,如
图 2.x,具体区别如下所示。

图 2.X 三种类型的库文件
 编译的库文件
“*.compiled-library”是被保护的库文件,供应商由于出于对源代码知识产权的保护,编程人
员不能直接打开库文件获取其源代码,但拥有权限正常调用库中所有的函数及功能块。
 标准库文件
所有包含外部指令和内部功能块的执行代码都存放在“*.library”之中,该库文件格式也是
CoDeSys V3.x标准类型的功能库文件格式。可使用CoDeSysV3.x打开库文件对其中的功能块或外部
指令的执行程序进行修改。但当相应库装载到PLC中后,占用用户程序空间较大。
 CoDeSys 库文件(在 V3.0 版本之前)
“ *.lib ”是 CoDeSys V2 版本 的库文件 标准格式 。 CoDeSys 为 了 做到向 下兼容, 可通 过
CoDeSys V3.x 打开直接将其转换为“V3 函数库” (*.library)。
1) 库文件的调用
安装过库文件后,需要在项目中对库文件进行添加才能调用其中的函数或功能块等,此时需要
使用库管理器实现此功能,具体步骤如图 2.x 所示。

图 2.X 使用库管理器安装/查看功能块
(1) 在项目中双击“库管理器”,
(2) 添加库,点击“Add Library”即可在库管理器中找到库文件对应的函数及功能块。
当选择“Add Library”后,用户即可选择之前已安装过的库文件,并将其导入至项目中,添加
库视图如图 2.x 所示,用户可以根据供应商名,库文件功能及版本号进行选择分类。

图 2.X 添加库
(3) 查看安装后库文件中的函数及功能块。
在标准项目或库文件项目中可以调用其他库(即库的调用),对调用的层数没有限制,可多层
嵌套。如果在库管理器中添加了一个包含了其他库的库,则引用的库也将被自动添加。
注意:
标准库 Standard.library 在工程建立时被自动载入,无需用户手动载入。
库文件只要被载入,即使不调用其中的功能块,也会占用用户程序空间,建议不要载入不使用的库文件。
2) 查看库文件简介
如在库管理器中可以直接查看 CTU 增计数功能块的简单说明,如图 2.x 所示。在“输入/输出”
选项卡中可以了解到各输入/输出变量的类型及注释。

图 2.X 查看库的输入/输出
在 “文档”选项卡中能够直接浏览查看帮助文档,省去查阅帮助手册的时间。如图 2.x 所示。

图 2.X 库文件中功能块简要说明
3) 库文件的多版本
一个函数库的不同版本可以同时安装在一个系统上。 在一个工程中可以包含相同函数库的不
同版本。应用程序使用哪个版本是按照如下规定进行的:
 如果在相同的函数库管理中多个版本都有相同的级别,那么将根据当前的 “属性”决定
哪个版本将会被调用(默认的是最新版本)。
 如果在同一个函数库管理中一个函数库的不同版本有不同的级别,特殊访问的库文件通过
添加适当的命名空间决定使用哪个。
3. 库文件的属性
库文件唯一访问性及代码的安全性,下文会针对这些特性逐一进行讲解。
1) 唯一访问性
在一个项目中如果有几个模块或变量具有同一个名字,那么访问具有相同名字变量的路径必须
是不同的(即“唯一访问”),否则就会发生编译错误。该规则对本地工程、库、被其他库引用的
库中的模块或变量都适用。用户可以通过在模块或变量名前加上名字空间来实现唯一访问。
在“库属性”中,可以定义该库的默认名字空间,如果没有明确定义,名字空间则等同于库名
称。当创建一个库工程时,可以在属性对话框中设置它的名字空间;当该库被其他工程引用时,也
可以在属性对话框中修改名字空间。
例如:假设库“Lib1”的命名空间为“Lib1”,表 2-x 中左列中是变量 var1 在项目中定义的位
置,右列是如何通过命名空间对 var1 进行唯一访问。
表 2-x 库的唯一访问
var1 在项目中的位置: 通过命名空间对 var1 进行唯一访问…
在 POU->全局库管理器->Lib1 库中 "Lib1.module1.var1"
在设备->Dev1 设备->App1 应用->库 "Dev1.App1.Lib1.module1.var1"
管理器->Lib1 库中
在 POU 窗口->全局库管理器->F_Lib 如库属性的“发布…”选项未激活:“F_Lib.Lib1.module1.var1”
库引用的 Lib1 中 如果激活了“发布…”,那么 module1 会被看做顶级库的一个组件,因
此可以通过 “Lib1.module1.var1”或者“module1.var1”访问。
在 POU 窗口->module1 对象中 "module1.var1"
在 POU 窗口->POU1 对象中 "POU1.var1"
2) 库文件访问的安全性
CoDeSys 对开发者库文件源代码保护,拥有其安全功能,
 库文件加密
如果创建一个加密函数库,许可信息必须添加到工程信息对话框中的“许可列表”中,并且工
程必须保存为“已编译的函数库”。

图 2.x 密码设置
比较常用的是采用“密码”的方式进行加密,设置完密码后,每次进入系统,系统都会提示要
求输入密码,如图 2.x 的 a)所示,如果输入密码错误则不能打开库文件,系统也会有相应的加载
错误提示,如图 2.x 的 b)所示。
a) b)

图 8.X 密码提示
a ) 输入密码提示框 b ) 输入密码错误,加载失败
使用此种方式加密,如果用户端不知道密码,则不能使用及打开该库文件。
4. 创建库文件
除了生产厂商提供的库文件,用户自己也可以根据工作经验,把常用的函数或功能块整理出来,
建立属于自己的库文件,便于应用至其他项目,具体创建库文件的步骤如下:
1) 建立库文件的准则
在用户需要开发一个完整的 CoDeSys 库文件之前,请先遵循如下的规则:

 定义一个合适的库文件名
 基于 CoDeSys V3.x 的库开发模板进行开发,以保持库文件格式的一致性
 尽可能的输入详细的工程信息
 合理的借鉴其他已有的库文件格式及规范
 开发是需要设计可供外部和内部使用的接口
 加载用户界面友好的故障处理
 选择合适的手段保护开发者的源代码
 变量名应遵循匈牙利命名法,使程序更整洁及保持一致性
 当需要修改库文件时,在编译新版本之前,需要考虑到 I/O 接口的兼容性问题,防止使用
新库文件时,I/O 接口不匹配,导致编译出错。

2) 开始创建库文件项目
使用菜单命令“文件”-->“新建工程”-->“函数库”-->“CoDeSys Library”,在图 2.x 中的
“3”处输入库的名称,选择完毕后,点击“确定”后则会自动生成一个新的库文件,具体步骤如
图 2.x 所示。

图 2.x 库文件的创建
图 2.x 中第 2 步选用的是“CODESYS library”,此类型为 CODESYS 标准库。
当创建一个库工程时,如果引用了其他库,可以在每个被引用库的“属性”栏中定义它被引用
后的行为。请注意下面几点:
 在库管理器中,被调用的库一般是缩进列在引用它的“父”库下面;用户也可以设置不显
示被引用的库,“隐藏”它们。
 如果一个库被其他库引用 ,就应当考虑到这个库由于被其他库引用而被包含进一个工程中
时,它的行为如何。这个“行为”包括版本处理、名字空间、可视性以及访问属性。这些都可以在
被引用库的属性对话框中设置,以后当该库被包含进工程时就会依照这些设置。
 可以创建“容器”库(CODESYS Container library)。“容器”库指的是,该库本身没有任
何内容,就是引用了一些其他的库,就像一个“容器”。创建“容器”库一般是为了通过引用它,
从而很方便的引用所有被它引用的库。为了方便使用“容器”库,用户可以在创建它们时激活“发
布(Publish)…”选项,这样可以将它们设为“顶层库”,从而可以在使用时忽略它们的名字空间。
但是在激活“发布…”选项时请注意,应该只对“容器”库激活该选项。
3) 进入 POU 设置主界面
建立库文件后,则可显示主界面,其框架主要包括枚举数据类型,功能块,函数全局变量,
接口,结构体等,用户可以基于该结构在其文件夹下进行内容的扩展,如图 2.x 所示。

图 2.x 库文件主框架
(1) 库管理器,用户也可以在此添加和调用其他的库文件。
(2) 工程信息设置,双击“ ”选项,可以编辑库文件的所属公司、库文件标
题,版本号,作者名和库的简要说明等信息。
图 2.x 库文件项目工程信息
在工程信息中,图 2.x 中加粗字体的部分(公司、标题和版本)必须要填写。 “库类别”
为了便于今后在“库”和“库管理器”对话框中,根据“类别”选项来排序,方便分类查找。
4) 建立 POU
在库文件中建立自己的函数及功能块:编程人员可在标准 CoDeSys 的框架下将自己编写好的
库文件对应内容添加在其对应文件夹下。
如图 2.x 所示,将用户自定义的计数功能块 FB_COUNT 添加在 Function Block 文件夹下,该文
件夹名可以根据编程人员实际分类进行编辑。

图 2.x 库文件中新建功能块
当完成库文件编写后,需要对其进行编译检查及保存。
a) “编译”--> “检查所有池对象”。
b) 确定没有错误后,点击如图 2.x 中的黄色按钮“ ”保存工程,并装入库后,即可实现对
库文件的保存。

图 2.x 编译及保存库文件
上述步骤完成后,即可保存库文件,并退出。在新的项目中即可安装此库文件,通过选择“工
具”菜单中的“库”来进行安装。安装完毕后,需要在项目中的库管理器中进行添加,添加后可以
可根据名称分类,来最终选择要添加的库。添加后即可在项目中查看其中的功能块,如图 2.x 所示。

图 2.x 加入的用户库文件

5. 第三方应用库 OSCAT
CoDeSys 及 PLC 硬件供应商会提供一些标准的库文件,此外用户也可以通过自己动手来建立
属于自己的库文件,与此同时,还有一些第三方的库文件供应商也在为 CoDeSys 提供扩展功能的
库文件,OSCAT 就是其中之一,它也是在行业内比较受工程师推荐的一个供应商。
OSCAT 是一个开源的自动化应用技术社区,在该社区中可以找到基于 IEC 61131-3 的帮助以及
库文件。其中涉及到 CoDeSys2.3 及 CoDeSys3.x。OSCAT 官方网站为 http://www.oscat.de/,用户可
以直接登入该网站的下载页面下载对应 library 库文件,如图 2.x 中的红色框出部分所示。

图 2.x OSCAT 网站主页


下载完“oscat_basic.library”后,在 CoDeSys 项目中进行添加库,即可实现将来对库文件调用,
更新和删除。图 2.x 中所示,将该库文件添加至项目中后的视图,具体功能块的说明需参阅相关帮
助文档。

图 2.x OSCAT 库文件介绍


2.3.3 全局变量和局部变量

变量的范围确定其在哪个程序组织单元中是可用的,范围可能是全局或局部。每个变量的范围
由它被声明的位置和生命所使用的变量关键字所定义。
1. 全局变量
在程序组织单元之外定义的变量称为外部变量,外部变量是全局变量。全局变量可以为本文件
中其他程序组织单元所共用。全部程序可共享同一数据,它甚至能与其他网络进行数据交换。其原
理示意图如图 2.x 所示。bIn1 能同时给程序 A 和程序 B 共用。

程序 A 变量内存
bIn1 bOut1
全局变量
bIn1: True/False

程序 B
bIn1 bOut2

图 2.x 全局变量
一个系统中不能有相同名称的两个全局变量。所有的全局变量都在全局变量列表中进行声明,
全局变量提供了两个不同程序和功能块之间非常灵活的交换数据的方法。全局变量的关键字如下。
VAR_GLOBAL
<全局变量声明>
END_VAR
用户可以通过添加全局变量列表实现全局变量的添加。鼠标选中“Application”右键选择“添
加对象”-->“全局变量列表”,系统则会自动弹出全局变量列表,用户只需输入列表名称,点击
“确认”即可,具体步骤请参考图 2.x。

a) b)
图 2.x 全局变量列表添加
a ) 添加全局变量列表 b ) 输入列表名称
2. 局部变量
在一个程序组织单元(POU)内定义的变量都为内部变量,它只在该程序组织单元内有效,这
些变量称为“局部变量”,其结构原理图如图 2.x 所示。

程序 A 变量内存
bIn1 bOut1 程序 A 用
bIn1: True/False

程序 B
程序 B 用
bIn1 bOut2 bIn1: True/False

图 2.x 局部变量
用户使用局部变量后,在执行多个独立的程序时,编程时无需理会其他独立程序中的同名变量,
他们之间没有映射关系,互不影响。局部变量的关键字如下。
VAR
<局部变量声明>
END_VAR

2.3.4 访问路径

访问路径用于将全局变量、直接表示变量、功能块的输入/输出和局部变量联系起来,实现信
息的存储。它提供在不同配置之间交换数据和信息的方法,每一个配置内的许多指定名称的变量可
通过其他远程配置来存取。
访问路径功能已经集成在 CoDeSys 内部,用户不需要对其进行操作,所有的存取操作会在
CoDeSys 的后台自动进行。
2.4 程序组织单元
程序组织单元(Program Organization Unit,POU)由声明区和代码区两部分组成,是用户程序
的最小软件单元,它相当于传统编程系统中的块(Block),是全面理解新语言概念的基础。按功
能分程序组织单元(POU)可分为函数(FUN)、功能块(FB)和程序(PRG)。
在“POU 窗口”中管理的编程对象在整个工程范围内都有效,且可以被工程中所有的“应用”
通过任务配置来调用,即实例化。在“设备窗口”中管理的编程对象(即针对特定应用的编程对
象),只能被本应用来使用,或被本应用的“子应用”实例化后使用。
程序组织单元的标准部分(如函数、功能块、程序和数据类型等)都由德国 3S 公司或 PLC 制
造商提供,集成在库文件中。用户也可通过自己的逻辑思想与 PLC 制造商所提供的程序组织单元
自行设计程序组织单元,再对其进行调用和执行。
用户可以在项目中使用右键菜单的命令“添加对象”,选择“程序组织单元”,会弹出如图
2.x 所示的对话框,用户可以选择添加程序,功能块或函数,下拉菜单中可以选择对应的编程语言。
添加后,可以在左边的项目设备树中查看程序组织单元括号内对应的属性,FB 为功能块,FUN 为
函数,PRG 为程序。

图 2.x 程序组织单元
程序组织单元具有如下特点:
 可对每个应用领域设置用户的功能块库,便于工程的应用。例如,建立运动控制功能块库

 可对功能块进行测试和记录
 能够提供全局范围内的库存取功能
 可重复使用,使用的次数无限制
 可改变编程,用于建立功能块网络

2.4.1 程序组织单元结构

一个完整的 POU 由如下三大部分组成,结构图如 2.x 所示。


 POU 类型及命名
 变量声明部分
 代码指令部分(POU 主体)
PROGRAM PROG Name
PROGRAM name FUNCTION_BLOCK FB name
FUNCTION_BLOCK FUNCTION
FUNCTION FUN name :Datatype
name:Datetype

接口变量
声明区
本地变量

指令 代码区
(POU 主体)

END_PROGRAM
END_PROGRAM END_FUNCTION_BL
END_FUNCTION_BLOCK END_FUNCTIO
END_FUNCTION
OCK N

图 2.x POU 的组成


上图中,从具体功能来看,分别能构成左边的程序(PRG),中间功能块(FB),右边函数
(FUN)。从每个功能的结构来看,都可以将其分为声明部分和代码部分。
用户声明的所有变量最终是给程序组织单元所用,变量声明中可声明接口变量和本地变量,通
过下面的例子对整个程序组织单元做个初步的讲解。

VAR_INPUT VarIn :BOOL; END_VAR (*输入接口变量*)


VAR_OUTPUT VarOut1 :BYTE;
接口变量 VarOut2 :BOOL; END_VAR (*输出接口变量*)
VAR VarLocal :BYTE; END_VAR (*本地变量*)
本地变量

VarOUT1:= VarLocal-100;
指令

(POU 主体) VarLocal.0:=NOT VarIn;

VarOUT2:= VarLocal.0

图 2.x POU 举例
上述结构可以用在功能块(FB)或程序(PRG),因函数(FUN)只有一个返回值,故上述结
构不适用于函数(FUN)。VarIn 作为输入变量,VarOut1 和 VarOut2 作为输出变量,VarLocal 作为
本地变量。通过图形化标准语言中调用的效果如图 2.x 所示,用户可以根据图中的变量类型调用该
功能块/程序。

图 2.x 图形化效果图
1) 声明区
变量声明区是用来指定变量的名称、类型和赋初始值的区域。
变量声明编辑器用来声明 POU 变量以及声明数据类型。声明部分通常是文本编辑器,也可采
用表格编辑器。所有将要在这个 POU 中的使用的变量则在 POU 的声明部分中声明,这些变量包括:
输入变量、输出变量、输入/输出变量、本地变量、添加的变量和常量。声明格式是基于 IEC
61131-3 标准的。变量的声明采用下面的格式:
<标识符>{AT<Address>}:<数据类型>{:=<初始化>}:
其中{}中的部分是可选择的。
2) 代码区
在代码区,CoDeSys 支持两种文本语言:指令表语言(IL)和结构化文本(ST)。四种图形化语
言:功能块图(FBD)、梯形图(LD)、顺序功能图(SFC)以及连续功能图(CFC)。用户可以选择一种或
几种语言在主体部分来进行程序设计。主体编辑器界面如图 2.x 所示,该图中采用的是梯形图(LD)
程序语言。

图 2.x 主体编辑器界面

2.4.2 函数

为了 PLC 编程语言的应用,函数(FUN)也被定义为一个程序组织单元。函数是一种可以赋
予参数,但没有静态变量的程序组织单元。即用相同的输入参数调用某一函数时,该函数总能生成
相同的结果作为函数值(返回值)。函数的一个重要特性是它们不能使用内部变量存储数值,这点
与功能块完全不同。
函数(FUN)是没有内部状态(没有运行时的内存分配)的基本算法单元。也就是说只要给定
相同的输入参数,调用函数必定得到相同的运算结果,绝对没有二义性。我们平时使用的各种数学
运算函数,如 sin(x)、sqrt(x)等,就是典型的函数类型。
函数是有至少一个输入变量、无私有数据、仅有一个返回值的基本算法单元。
CoDeSys 的标准库中已经预有标准函数。具体可以查看第 X 章。
函数可以被函数、功能块、程序所使用。
1. 函数的表示和声明
1) 自定义函数的表示
函数内部逻辑部分可以使用 6 种编程语言中的任意一种。函数名即是函数的返回值,也可以理
解为是函数的输出值,如下为函数的语法表达式。
FUNCTION <函数名/返回值>: <返回值数据类型>
VAR_INPUT
… (*函数的输入接口变量声明*)
END_VAR
VAR
… (*函数的本地变量声明*)
END_VAR

…; (*函数内部逻辑*)
2) 函数中变量的声明
用户自定义函数时,应注意如下事项:
 函数可以拥有很多个输入变量,但只能有一个返回值(输出变量)。但是并没有限制返回
值的数据类型,所以可以为一个结构体作为返回值。
 函数的重要特征是它们不能在内部变量存储数值,这点与功能块截然不同。
 函数没有指定的内存分配,不需要像功能块一样进行实例化。
 函数只能调用函数,不能调用功能块。
 配置到 VAR_INPUT 的自变量可以是空的、常数、变量或函数调用,在函数调用时,函数
是作为实际的自变量被调用的。
2. 标准函数
CoDeSys V3.x 支持所有 IEC 的 8 类标准函数。除此之外,还可以使用下列 IEC 标准未规定的
函数:ANDN、ORN、XORN、INDEXOF 和 SIZEOF、ADR、BITADR 等。CoDeSys 共支持如下
11 类函数,具体函数使用及说明在第六章会做详细介绍。
3. 函数的属性
1) 重载性
对某一个函数来说,如果其输入量以类属数据类型描述,则称为重载函数。这表示该功能的输
入量不限于单一的某种数据类型,而是可用于不同的数据类型。CoDeSys 所有标准函数都具有重载
属性,他能够适用于不同的数据类型。如果函数只适用于某数据类型,则需在函数名中给予声明,
这称为函数的类型化。
例如一个 PLC 能识别 INT、DINT 和 SINT,则它支持类属数据类型 ANY_INT(包括 BYTE、
WORD、DWORD、SINT、USINT、REAL 等)的重载功能 ADD。例如,ADD_INT 是一个限于数
据类型的 INT 加法函数,它属于类型化函数,这样看重载功能是独立于类型的。重载函数说明如图
2.x 所示。

INT ADD_INT INT


INT

DINT ANY_INT ADD


ADD_DINT DINT ANY_INT
DINT ANY_INT

SINT ADD_SINT SINT


SINT

图 2.x 重载函数说明
使用重载函数时,系统会自动选择合适的数据类型。例如,如果调用的 ADD 实参数据类型是
DINT,则系统内部会调用 ADD_DINT 标准功能。
2) 可扩展性
函数的输入变量个数可以扩展的属性称为函数的可扩展属性。例如,ADD 函数的输入变量可
以不仅限于两个,它可以实现多个输入变量的加法运算,因此,可以称 ADD 函数具有可扩展属性。
并非所有标准函数都具有可扩展属性,该功能的扩展限度受 PLC 所强制的上限、图形编程语言中
方框高度限制或函数本身功能定义上的限制,如 DIV 函数就具有该属性。具有可扩展属性的函数
可简化程序,降低所需的存储空间。图 2.x 是具有可扩展属性的一些函数示例。

图 2.x 具有可扩展性的函数示例
3) EN 和 ENO
只有在梯形图和功能块图编程语言中该属性才有效。EN 和 ENO 分别是函数的输入使能和输出
使能。所有的函数都可使用或禁用该属性。
使能输入使能输出的应用原则如下:
 当该输入函数被调用时,EN 的值为 False,则该函数体定义的操作不会被程序执行,同时
ENO 的值为 False。
 EN 为 True 时,该函数被调用,函数体定义的操作被执行,同时 ENO 的值为 True。
 EN 和 ENO 属性是附加属性,可根据实际需要使用或禁用该属性。
图 2.x 对有 EN/ENO 的 ADD 函数和普通的 ADD 函数进行了比较。

图 2.x 具有 EN/ENO 属性的函数和普通属性函数比较

4. 自定义函数举例
【例 2.X】使用 PLC 时常会遇到的实际问题是,很多情况需要将实际的模拟量信号转换为数字
量信号,常用的模拟量电流信号有 0~20mA,4~20mA,电压信号有 0~10V,-10~10V 的,通过
这些输入参数的类型选定,将其转换为数字量值。
函数声明:
FUNCTION F_iScaleOutput : INT
VAR_INPUT
rOutput: REAL; (* [] Physical output *)
rPhyMin: REAL; (* [] Physical minimum *)
rPhyMax: REAL; (* [] Physical maximum *)
eTerminal: E_Ctrl_TerminalType; (* [] Terminal type. *)
END_VAR
VAR
rTerMin: REAL;
rTerMax: REAL;
rPhyRange: REAL;
rTerRange: REAL;
rTerOutput: REAL;
END_VAR
模拟量输入类型通过 E_Ctrl_TerminalType 枚举数据类型对其进行声明。
TYPE E_Ctrl_TerminalType :
(
eTerminal_0mA_20mA,
eTerminal_4mA_20mA,
eTerminal_0V_10V,
eTerminal_m10V_10V
);
END_TYPE
函数代码:
rTerMax:= 32768.0;
CASE eTerminal OF
eTerminal_0mA_20mA: rTerMin:= 0.0;
eTerminal_4mA_20mA: rTerMin:= 0.0;
eTerminal_0V_10V: rTerMin:= 0.0;
eTerminal_m10V_10V: rTerMin:= -32768.0;
ELSE
rTerMin:= -32768.0;
END_CASE
rPhyRange:= rPhyMax - rPhyMin;
rTerRange:= rTerMax - rTerMin;
IF rPhyRange > 0.0 AND rTerRange > 0.0 THEN
rTerOutput:= rTerMin + (rTerRange * (rOutput - rPhyMin) / rPhyRange);
ELSE
rTerOutput:= 0.0;
END_IF
F_iScaleOutput:= REAL_TO_INT(rTerOutput);
程序调用该滤波函数结果如图 2.x 所示,样例代码请参考样例程序\F_iScaleOutput \。

图 2.x 模数转换函数调用结果

2.4.3 功能块

功能块(Function Block)是把反复使用的部分程序块转换成一种通用部件,他可以在程序中被
任何一种编程语言所调用,反复被使用,不仅提高了程序的开发效率,也较少了编程中的错误,从
而改善了程序质量。
功能块在执行时能够产生一个或多个值的程序组织单元。功能块保留有自己特殊的内部变量,
控制器目标执行系统必须给功能块的内部状态变量分配内存,这些内部变量构成自身的状态特征。
功能块的执行逻辑构成了自身的对象行为特征。所以,对于相同参数的输入变量值,由于可能存在
不同的内部状态变量,当然就可能得到不同的计算结果。在控制系统中,功能块可以是某种控制算
法,例如 PID 功能模块被用于闭环控制,其他功能块可用于计数器,斜坡和滤波等。
1. 功能块的表示和声明
1) 自定义功能块的表示
与函数一样,功能块内部逻辑部分可以使用 6 种编程语言中的任意一种。函数名即是函数的返
回值,也可以理解为是函数的输出值,如下为功能块的语法表达式。
FUNCTION_BLOCK <功能块名>
VAR_INPUT
… (*功能块的输入接口变量声明*)
END_VAR
VAR_OUTPUT
… (*功能块的输出接口变量声明*)
END_VAR
VAR
… (*功能块的本地变量声明*)
END_VAR

…; (*功能块内部逻辑*)
2) 功能块中变量的声明
功能块中变量声明与函数中变量声明类似,编写时,需注意如下事项:
 功能块的内部和输出变量可用限定属性 RETAIN,用于表示该变量具有保持功能。而输入
变量只能在调用时声明具有保持属性。
 一般不允许对功能块输入变量赋值。只有当输入作为功能块的调用部分时,才允许对功能
块输入变量赋值。
 由于功能块可以调用函数和功能块,所以,也可将调用功能块实例作为其他功能块的实例
的变量。如 DB_FF(S1:=DB_ON.Q, R:=DB_OFF.Q)。
 功能块的输入不赋值表示保持他们的初始值。
 为确保功能块不依赖于硬件,功能块的变量声明中不允许将具有固定地址的地址变量
(如%IX1.1,%QD12)作为局部变量,但在调用时可以给其赋值。
 使用 VAR_INPUT 和 VAR_OUTPUT 会造成占用过多的内存,为此,在功能块编程时,可
尽量使用 VAR_IN_OUT 替代,减少对存储区的占用。
2. 标准功能块
在标准库中已包含双稳态元素、边沿检测、计时器和定时器等功能块,本书在第六章会详细对
其进行说明。
3. 功能块的属性
1) 实例化
按照 IEC 61131-3 的标准,功能块的类型是抽象的结构类型的定义,而不是现实的数据实体,
如果不对其进行定义将其实例化,则不能被程序调用和执行。所以功能块是需要实例化后才能被使
用。
实例化后的功能块是拥有私有数据、可按照既定逻辑完成特定功能、完全封装的、独立的结构
型变量。从而将之前的抽象类型定义转换为数据实体。首先通过例子 2.x 来了解一下如何将功能块
进行实例化。
【例 2.X】功能块实例化如图 2.x 所示。

Value : BOOL; (*布尔变量*)

变量名 数据类型

Motor1 : MotorType; (*功能块实例化*)

功能块实例名 功能块类型(自定义)

图 2.x 功能块实例化示例
如例 2.X 所示,功能块实例化就如定义变量一样,MotorType 为功能块的类型,是用户通过
POU 自定义的功能块。当程序中需要调用该功能块时,只需在声明处将该功能块将其定义即可,
该例中 Motor1 为最终的实例名也可以理解为变量名,程序执行过程中都是通过 Motor1 对该功能块
进行读写操作。
实例需要按照类型进行合法定义,允许在程序中进行权限允许的调用。在控制器的目标执行平
台上必须获得固定的静态内存分配(只不过 VAR_IN_OUT 方式定义的静态内存可共享使用,内存
消耗少)。实例的类型可以同名,但实例名在同一 POU 中绝不允许相同。
【例 2.X】功能块实例化示例。
VAR
EmStop : BOOL; (*布尔变量*)
Time9 : TON; (*延时 ON 功能块*)
Time13 : TON; (*延时 ON 功能块*)
CountDown : CTD; (*减计数器*)
GenCounter : CTUD; (*增/减计数器*)
END_VAR
例 2.X 中,尽管可以看到 Time9 和 Time13 的类型都为延时 ON 的 TON 功能块,但其实它们通
过实例化后是两个独立且分开的功能块,代表了两个完全的定时功能块。
2) 扩展性
CoDeSys 支持面向对象的编程方式,所以功能块也可以派生出“子”功能块。这样“子”功能块具
有“父”功能块的属性,并且可以具有自己附加的特性,可以形象的认为“子”功能块是对“父”功能块
的扩展。所以在本文中,把这个叫做“功能块的扩展”。
在声明功能块时加上关键字“EXTENDS”就可以使用扩展功能。也可以通过在“添加对象 ”对话
框添加功能块时,选择“extends”选项来实现扩展。
声明扩展功能块的格式如下:
FUNCTION_BLOCK <功能块名称> EXTENDS <功能块名称>
后面紧跟着是功能块中变量的声明。
【例 2.X】功能块的扩展性应用,定义功能块 fbA:
FUNCTION_BLOCK fbA
VAR_INPUT
x:int;
....
定义功能块 fbB:
FUNCTION_BLOCK fbB EXTENDS fbA
VAR_INPUT
ivar:int;
....
功能块 fbB 包含功能块 fbA 中所有的变量和方法,在使用功能块 fbA 的地方都可以用 fbB 代替。
在功能块 fbB 中可以重写 fbA 中原有的方法。即可以在 fbB 中重新声明一个 fbA 中已有的方法,
它的名称、输入、输出和 fbA 中的原有方法一样。
fbB 中不允许使用与 fbA 中同样名称的功能块变量,否则程序在编译时会报错。
使 用 功 能 块 fbB 时 , 可 以 直 接 使 用 fbA 中 的 变 量 和 方 法 , 加 上 关 键 字 “SUPER” 即 可
(SUPER^.<method>)。
3) EN 和 ENO
功能块具有 EN 和 ENO 的附属属性,与函数中 EN 和 ENO 的使用方法类似。
4) 函数功能块的区别
综上所述,函数和功能块明显的区别如表 2-x 总结:

表 2-X 函数与功能块区别总结表
函数(FUN) 功能块(FB)
内存分配 没有指定的内存分配地址。 全部数据分配内存地址。
输入/输出变量 只允许一个输出变量。 多个输出变量或没有输出变量。
调用关系 可调用函数,但不能调用功能块。 可调用功能块或函数。
4.自定义功能块举例
【例 2.X】自定义一个递增/递减功能块,分为三个输入,增计数,减计数,复位,当前计数值
为输出。
FUNCTION_BLOCK FB_Counter
VAR_INPUT
bUp:BOOL;
bDown:BOOL;
bReset:BOOL;
END_VAR
VAR_OUTPUT
nValue:DWORD;
END_VAR

IF bUp THEN
nValue:=nValue+1;
END_IF
IF bDown THEN
nValue:=nValue-1;
END_IF
IF bReset THEN
nValue:=0;
END_IF
图 2.x 功能块调用结果示例
【例 2.X】自定义一个简单 PT1 一阶低通滤波函数,输入值为 rInput, 通过调整增益参数 rK
及时间常数 rK 使输出值更平滑,代码请参考样例程序\FB_PT1Filter\。
功能块声明:
VAR_INPUT
rInput: REAL:= 0.0;
rK: REAL:= 1.0;
tT: TIME;
END_VAR
VAR_OUTPUT
rOutput: REAL:= 0.0;
END_VAR
VAR
_rT: LREAL;
_rY: LREAL;
END_VAR
功能块代码:
IF _rT = 0.0 THEN
rOutput:= rInput; //Init the value
END_IF

_rT:= TIME_TO_REAL(tT) /10; //10ms, PLC cycle time

IF ABS(rOutput - rInput) < 1E-6 THEN


rOutput:= rInput; (* prevent residual error *)
ELSIF _rT > 0.0 THEN
rOutput:= (rK / _rT) * rInput + (1.0 - (1.0 / _rT)) * _rY;
ELSE
rOutput:= rInput; //Time constant less or equal zero
END_IF
_rY:= rOutput;
图 2.x PT1 功能块调用结果

2.4.4 程序

程序(Program)是规划一个任务的主核心,程序拥有最大的调用权,可以调用功能块及函数。
一般而言分为主程序、子程序,广义上讲,也包含硬件配置、任务配置、通讯配置及目标设置
信息。
一般在程序中定义普通全局变量、映射硬件地址全局变量、局部变量。通过程序间调用实现应
用逻辑。
1. 程序的表示和声明
1) 自定义程序的表示
程序采用如下的语法表达式表示,程序逻辑部分可以使用 6 种编程语言中的任意一种。
PROGRAM <程序名>
VAR_INPUT
… (*程序的输入接口变量声明*)
END_VAR
VAR_OUTPUT
… (*程序的输出接口变量声明*)
END_VAR
VAR
… (*程序的本地变量声明*)
END_VAR

…; (*程序逻辑*)
2) 程序中变量的声明
2. 程序的性能
 一个程序可包含地址的配置。允许声明存放 PLC 物理地址的直接表示变量,直接表示的地址
配置仅用于程序中内部变量的声明。直接表示变量允许分级寻址方式描述,如可有如下的表示。
可以在程序声明中按如下格式填写,
bTest AT %IX10.3: INT;
在程序编辑区可用如下的语句给直接表示变量赋值。
%QX0.0:=TRUE;
 程序组织单元不能直接或间接调用其本身,即程序组织单元不能调用由相同类型和相同名称的
程序组织单元实例。
 程序仅在资源中实例化。在资源内被声明。程序的实例只需将程序与一个任务结合,否则程序
不会被执行。而功能块仅能在程序或其他功能块中实例化。
3. 程序调用
1) 程序调用关系
在程序中允许调用功能块实例,函数甚至调用其他程序。图 2.x 显示了程序组织单元的调用的
关系。
程序(PRG)

函数 功能块 程序(PRG)
(FUN) (FB)

函数 函数 功能块
(FUN) (FUN) (FB)

图 2.x 程序调用关系
根据上图中的显示,函数和功能块用于构成子程序,程序用于构成用户主程序,因此,程序被
认为是全局的。程序是程序组织单元中的最大形式,它可以调用函数,功能块及程序。
功能块允许调用其它功能块及函数。由于函数不存在私有变量,故函数只能调用其他函数,不
能调用功能块实例。
2) 如何调用程序
一般而言,在功能块实例的调用中,需要赋值的输入参数,可以将实参显式传递形参,不要赋
值或保持原值的输入参数,可以不用任何显式赋值。功能块实例的调用允许不做任何形参的赋值。
在函数调用中,如果出现形参,则必须将全部的形参都做显示赋值。如果不出现形参,则必须按照
定义的顺序,将全部实参写入到函数的调用体内。
程序可以被其他的 POU 调用,但函数中不可以调用程序,程序也没有实例。
如果一个 POU 已调用一个程序,从而引起这个程序的值的改变,这些改变将会保持不变,直
到该 POU 下一次调用这个程序,即使其间该程序被其他的 POU 调用。注意这与功能块的调用不同,
只要功能块实例被调用了,而不管是被哪个 POU 调用的,它内部的值都会改变。
如果是在文本编辑器中,想在程序调用时设置输入/输出参数,那么可以在程序名后面的圆括
号中给各个参数赋值。对于输入参数,用":="赋值,就像在变量声明部分初始化变量一样。对于输
出参数,则使用"=>",请看后面的示例。
如果您是在文本编辑器的代码实现窗口中,通过“输入助手”的“带参数插入”选项插入一个
程序,那么会自动列出该函数的所有参数。当然,您并不一定要给所有的参数都赋值。
 文本编程语言调用
使用文本编程语言时,在调用程序时必须添加括号,示例如下。
PRGexample();
erg := PRGexample.out_var;
上述例子通过先调用程序,将其输出的 out_var 变量赋值给 erg 变量。此外也可以通过如下的
方式调用程序,功能块及函数。通过在键盘输入 F2,使用“输入助手”的帮助为参数赋值,当有
输入或输出参数时,可以直接填写在括号中,具体表示方法如下。
PRGexample(in_var:=33, out_var=>erg );
 图形化编程语言调用
使用图形化编程语言时,显示的更为直观,只需要直接在接口处填写变量及数值即可,调用示
例如图 2.x 所示。

图 2.x 使用图形化编程语言调用程序
4. 自定义程序举例
【例 2.X】实时输出输入变量 in_var 与内部变量 i_var 相加后结果,并当结果为 23 时,内部变量
bvar 置为 ON,样例代码请参考样例程序\PRG_Basic\。
PROGRAM PLC_PRG
VAR_INPUT
in_var:INT;
END_VAR
VAR_OUTPUT
out_var:INT;
END_VAR
VAR
i_var:INT;
bvar:BOOL;
END_VAR

out_var:=in_var+i_var;
IF out_var=23
THEN bvar:=TRUE;
END_IF

2.4.5 创建的原则

建议广大的编程者,编程中可以遵循如下的 POU 创建原则:


 可以将您的工程按工艺或功能分成几段程序。
 在主程序中进行调用需要反复调用的程序段可以建成功能块,这样,在您的程序中只需调
用你的功能块实例即可。例如,有 100 台开关阀需要通过程序来控制开或关,那么,在项
目中只需要建立一个开关阀的功能块,再分别调用 100 次即可。
 个别的算法程序可以建成函数,得出的结果可以参与表达式运算。
 一个 POU 的名字不能包括任何空格。
 一个 POU 不能有与其它 POU 有相同的名字,或一个数据类型相同的名字。
 一个数据类型不能接受与其它数据类型相同的名字或一个 POU 相同的名字。
 在同一个 POU 中一个动作不能有与其它动作相同的名字。

2.5 应用对象

应用对象属于应用(Application),在应用菜单 中单击右键,选择“添加对象”或通过快
捷菜单中的按钮 实现对如下对象的添加操作。下面介绍几个常用的应用对象。

2.5.1 采样跟踪

在程序的调试和诊断过程中,该采样追踪是个非常实用和有效的工具,有时数据变化是一闪而
过的,不容易看出产生的影响,此功能可以于把一个程序的执行过程全程记录下来,其中的成员就
是在实际系统中要关注的命令字、状态字、电机运动的速度,位置等。通过对这些数据的追踪记录,
可以清晰地看到系统运行的整个过程,该功能如图 2.x 所示。
图 2.x 采样跟踪功能

1. 概述
采样追踪提供“跟踪配置”和“跟踪对象”两个插件,可以对 PLC 中的过程数据进行录取波
形,类似于示波器功能。此外,可以通过设置触发信号对数据进行采集。
用户可在 CoDeSys 中可以设置多个跟踪配置文件,并可将其进行保存,如 2.x 所示。

图 2.x 设备树中设置多个跟踪对象

2. 新建采样追踪
1) 鼠标放在应用(Application)点右键打开下拉菜单,在菜单中选中添加对象,并按导向引出的
菜单找到“Trace”并按鼠标左键确认,如图 2.x 所示。
图 2.x 新建跟踪配置
2) 确认跟踪后,会弹出如下对话框,在如下对话框中,填写跟踪的名称,比如“Trace1”,如图
2.x 所示,点击“打开”确认新家跟踪配置文件。

图 2.x 添加跟踪变量
3) 配置要记录的变量
打开跟踪配置后,选择“Add variable”可以进行跟踪变量的添加,将如图 2.x 所示。
图 2.x 跟踪设置
点击“变量”栏右边的浏览图标,可以弹出输入助手,在随即打开的窗口中选择要跟踪的变量。

图 2.x 跟踪变量选择
弹出输入助手后,在其中选择要监控的变量,设置完成后点击确定,如图 2.x 所示。
图 2.x 输入助手中选择变量
在图 2.x 中点击“显示”,能编辑曲线的 X 轴和 Y 轴的长度和网格,如图 2.x 所示。

图 2.x 设置跟踪显示配置
图 2.x 中可以对跟踪进行高级设定,其中可以设定曲线记录的刷新率及采样缓冲区的大小。
图 2.x 跟踪高级配置

3. 触发记录
在跟踪配置表中可以填写触发变量,如图 2.x 所示。

图 2.x 跟踪配置框
各配置项目定义如下:
触发变量:该功能是可选的,他与其他一些条件共同决定了跟踪的时间范围。
该变量可以是一个布尔变量、一个表达式或一个模拟变量,也可以输入枚举变量或属性变量。
当该变量满足了定义的值—-该值根据“触发边沿”类型来决定,跟踪将在采样一段时间后停止-—
该采样时间段由“位置”的百分比来决定。也就是说一旦触发变量变为真或满足某一特定值,跟踪
将继续一段定义好的周期。
触发沿:
无:无触发。
正向:布尔型触发变量的上升沿,或模拟触发变量增大至“触发水平”值时触发。
负向:布尔型触发变量的下降沿,或模拟触发变量减少至“触发水平”值时触发。
后触发(P)(采样):触发事件发生后,要记录跟踪变量的测量值百分比。例如,如果在这
里输入 25, 则当触发事件发生时, 其之前显示的是测量值的 25% 的数据, 其之后显示的是测量
值的 75% 的数据,然后跟踪终止。如果希望已发生触发事件,就开始跟踪,则需要填入 100。
触发水平:当使用模拟量作为触发变量,在此处定义该变量为多少时产生触发事件。可以直接
输入一个数值,或用变量定义该数值。默认值为空。
任务:在可用的任务列表中进行选择,该任务被执行后从中读取出跟踪变量的值。
记录条件:此处可输入一个布尔变量、一个数值或一个布尔表达式。如该条件为真,则启动跟
踪采样。若此处没有任何输入,则在下载跟踪配置并且应用开始运行后,立即开始跟踪记录。
注释:在此输入有关当前记录的注释文本。
4. 数据的保存
当数据采集完后,选择“保存跟踪”选项对数据进行本地保存,方便今后对数据进行分析,如
图 2.x 所示。

图 2.x 右键“保存跟踪”
保存的格式可以为“.trace”或“.txt”后缀。如图 2.x 是将文件保存为“.txt”文档,使用
MicroSoft Excel 打开,在 Excel 中做一些数据的排列分割,既可以看到如图 2.x 中的效果。保存的
数据的配有时间戳、变量名及具体数据。

图 2.x 使用 Excel 打开跟踪数据

5. 跟踪常用功能选项
常用功能选项如表 2-x 所示。

表 2-x 常用跟踪功能选项
图标 说明
下载跟踪,该命令用于下载跟踪实时曲线。当每次需要开始跟踪曲线时,这也是需要做的第一步。

启动/停止跟踪,该命令用来启动或停止跟踪。

复位触发器,该命令在一个触发事件发生后或跟踪停止时复位跟踪显示。复位后,跟踪显示将显示到最
新值。
光标,该命令用于确定数值的 X 轴坐标值。采样追踪中可以添加 2 个光标。可以用来确定每个光标单独 X
轴的绝对位置以及 2 个光标之间的 X 轴相对位置。
鼠标缩放,该命令用于激活鼠标缩放模式。当该模式被激活后,此时可在跟踪窗口中画一个矩形,重新
定义跟踪曲线的显示区域,该区域会扩大直到填满整个跟踪窗口。
滚动鼠标轮来缩放坐标系的 X-Y 轴。使用数字键盘键+和键-可实现相同的功能。
按住<Shift>键的同时滚动鼠标轮,只缩放 X 轴。按住<Shift>键的同时,使用数字键盘键+和键-可实现
相同的功能。
按住<Ctrl>键的同时滚动鼠标轮,只缩放 Y 轴。按住<Ctrl>键的同时,使用数字键盘键+和键-可实现相
同的功能。
该命令在设置被改变后,例如被缩放了,用于恢复记录的默认外观设置。在配置对话框中可对记录的默
认设置进行定义。
压缩,使用该命令,抽样跟踪中显示的值是压缩的,例如,使用该命令后,能在一个更大的时间段内观
察跟踪变量的进展,可实现命令的多重执行。
拉伸,使用该命令可以拉伸显示的抽样跟踪的值。一个接一个的反复拉伸,在窗口中显示的跟踪部分的
尺寸将逐渐缩小。

2.5.2 持续变量

1. 概述
在设计 PLC 控制系统时,常常会需要在外部改变 PLC 内部的数据,比如计数器、定时器或其
它变量的值,以适应生产过程的需要。而且要求系统关机或异常断点以后,这些数据还能够保存在
PLC 内部,当下次开机后,这些数据可以被调出,并保持断电前的数据继续被程序使用。
CoDeSys 内包含的保持型变量有 RETAIN, PERSISTENT RETAIN 这两种。PERSISTENT
RETAIN 在实际的工程应用中使用的更为频繁。
2. 新建持续变量
选中“Application”右键选择“添加对象”--> ,系统则会自动弹出持续变量
列表,用户只需输入列表名称,点击“确认”即可,具体步骤请先按照图 2.x 的 a)先添加列表,再
按照图 2.x 的 b)修改列表名称,点击“确定”即可完成添加持续变量列表。
a) b)

图 2.x 持续变量
a )添加持续变量列表 b )输入列表名称
使用“PERSISTENT RETAIN”保存的变量是在 PLC 程序 “Rebuild all”(重新编译)之后进
行初始化。而持续变量保持其原有的值。
注意:
从 CoDeSys V3.3.0.1 起,PERSISTENT 和 PERSISTENT RETAIN/RETAIN PERSISTENT 实现的功能
已相同。
持久变量必须为全局变量。
Persistent 变量只能在 special global variables list 中定义 “Persistent Variables ”。

3. 持续变量使用
1) 持续变量的声明
RETAIN 变量的声明格式如下,
VAR_GLOBAL RETAIN
… (*变量声明*)
END_VAR
PERSISTENT RETAIN 变量的声明格式如下,
VAR_GLOBAL PERSISTENT RETAIN
… (*变量声明*)
END_VAR
2) 持续变量的复位
保留变量用关键字 RETAIN 来识别,这些变量保持它们的值即使是在控制器的非正常关闭时和
正常的关闭和其中的一个控制器或在命令“热复位”时。当程序重新运行时,存储的值将进行进一
步的处理。一个具体的例子是生产线上的饼形计数器在电源故障后重新开始计数。所有其它的变量
从新初始化,不是用它们的初始化值或标准初始化的值。与永久变量相反,保留变量在程序的一个
新的下载时重新初始化。
永久变量通过关键字 PERSISTENT RETAIN 来识别。不象保留变量,这些变量在一个重新下
载或在执行命令“ 冷复位”或“原始复位”之后还会继续保留它们的值。如表 2-x 所示,在何种在
线命令时会复位持续变量。

表 2-x 持续变量在线命令行为一览表
x = 保留值 - = 初始值
在线命令 VAR VAR RETAIN VAR PERSISTENT RETAIN
热复位 x x
冷复位 x
原始复位
下载 x
在线改变 x x x
重新下载 x x

注意:
针对不同的硬件控制器,保持变量所占用的内存容量也各不相同,需要考虑实际变量占用的内存。
如一个局部变量定义为保留变量,变量将也将保存在保留区。
如果在函数中的局部变量定义为保留变量,这不起任何作用,变量将不保存在保留区内。
如果在功能模块中的一个局部变量定义为保留变量,功能模块的整个实例将会保存在保留区(POU 的所
有数据),因而只有定义的保留变量才处理为保留变量。
2.5.3 数据单元类型

用户可以自定义自己的数据类型,生成结构体、枚举、别名和联合都可以被看作是数据单元类
型 DUT(Data Unit Type Editor)。图 2.x 为数据单元类型视图。
1. 数据单元类型添加
选中“Application”右键选择“添加对象”--> ,系统则会自动弹出添加数据单元
列表,用户需输入列表名称并选择数据单元的类型,点击“确认”即可,具体步骤请先按照图 2.x a)
先添加列表,再按照图 2.x b)修改列表名称及选择数据类型,点击“确定”。

a) b)

图 2.x 数据单元 DUT


a )添加数据单元 DUT b )输入数据单元 DUT 列表名称
类型可以选择结构体、枚举、别名和联合。在“结构体”情况下可能会使用继承的方式,因此
需要面向对象的编程方式。也可以通过一个已经在另一个工程中定义的 DUT 再扩展另一个 DUT。
这意味着扩展 DUT 的定义将会自动针对当前 DUT 进行定义。针对这个目的自动使能“扩展:”。
“扩展”在原有的结构基础上对元素的补充。可以使用默认的语法,也可以使用扩展结构进行定义,
扩展必须之前定义过的结构体。
对于标准结构体已经用户自定义的结构体的描述参阅第 4 章变量章节。

2.5.4 全局网络变量

全局网络变量列表编辑器(GNVL 编辑器)是一个用于编辑网络变量列表的声明编辑器 。此
编辑器工作在文本编辑器的当前设置状态下,在线状态下,此编辑器的布局和变量声明编辑器的布
局相似。在网络变量列表编辑器中,变量声明必须以关键字“VAR_GLOBAL”开始,以关键字
“END_VAR”结束。这两个关键字会在打开编辑器的时候自动加入。在这两个关键字之间,用户
可以声明 合法的全局变量。
一个 GNVL 对象只能被添加到应用中,如果一个 GVL 具有特殊的网络属性(网络变量列表)
定义在网络中的一个设备上,无论变量是否在相同或者不同的定义项中。如果一些合适的 GVLs 变
量定义在当前网络的当前工程中,可以在将 GNVL 添加到“添加对象”对话框中时从列表中进行
选择。其他工程中的 GVLs 变量必须先进行导入,参照下文:
这意味着在当前设备 (接收器) 中的每个 GNVL 对应另一台设备(发送器)中的 GVL。
可以通过“应用”-->“添加对象” --> “全局网络变量列表”来添加列表,如图 2.x 所示。

图 2.x 添加全局网络变量列表
为了进行网络变量的处理,在添加 GNVL 的时候必须进行定义或者直接选择一个“发送器”
从其他设备发送 GVL,一个“GVL”导出文件 “*.gvl”可以直接通过以前通过“链接到文件”指
定的 GVL 文件。
在其他的工程项目中也必须定义 GVL。为了实现 “发送端”可以“从文件中导入”的功能,
用户可以在“发送者(S)”中选择“从文件导入”,然后在“从文件导入(I)”选项中浏览本地
路径需要导入的“*.gvl”文件,点击“打开”进行确认。
属性可通过“属性”对话框(“网络设置” )进行修改。

2.5.5 配方管理器

配方是一组参数值,它用来提供生产产品和控制生产过程所需的信息。例如饼干的配方包括黄
油、白糖、鸡蛋、面粉和烹调时间等参数的数据类型和参数值等。配方可以用来设置和监视 PLC
的控制参数。为了这个目的,它们可以从 PLC 中读出和写入,也可从文件载入和存成文件。这些
相互作用通过已经设置好的视图元素是可能的。
配方管理器是一个源对象,可以通过“应用”-->“添加对象” --> “配方管理器”来添加配方
管理器,添加后的界面如图 2.x 所示,a)为添加配方管理器界面,b)为配方管理器的配置界面。
a) b)

图 2.x 配方管理器
a )添加配方管理器 b )配方管理器配置
如图 2.x 的 b)所示,存储配方可选择 “存储类型”(文本的或二进制),通过指定 “文件路
径”具体存储位置,定义存储配方的“文件扩展名”。
文本的存储会根据所选的“分隔符”将其分开。
对话框左上部分显示了所有配方定义的列 “可用列”。右侧包含配方定义“选择列” ,这些
列会被存储。其它列可以通过选中条目点击 或 移到左侧或右侧,也可使用 或
将所有条目一次性移动。按钮 和 可用来调整选择列的顺序,这将代表存储文件中列
的顺序。
如图 2.x,为可视化界面配合配方管理器的示例画面。

图 2.x 配方示例
第3章 公用元素
本章主要知识点
 CoDeSys 公共元素
 注释的表示
 常数的表示

3.1 公用元素
PLC 程序是由一定数量的基本语言元素(最小单元)组成的,把它们组成在一起以形成说明或
语句。它包括分界符、关键字、标识符和注释等。

3.1.1 字符集

根据国家标准的 GB/T15969.3-2005,可编程控制器使用的文本和图形类编程语言中的文本元素
应依据国家标准 GB1988 字符的“基本代码表”的 3-7 列字符组成,并根据 GB2312-1980《信息交
换用汉字编辑字符集 基本集》来表示汉字。
支持小写字母时,字母的大小写具有相同的意义。例如,Control 与 CONTROL 是相同的变量
名或标识符。

3.1.2 分界符

分界符(Delimiter)用于分隔程序言语元素的字符或字符组合。它是专用字符,不同的分界符
具有不同的含义。表 3-x 列出了各种分界符的应用示例。

表 3-x 分界符
分界符 应用场合 备注和示例
空格 可以在 PLC 程序中任何位置插入空格 不允许在关键字、文字、标识符和枚举值中直接插入空格。
TAB 可以在 PLC 程序中任何位置插入 TAB 不允许在关键字、文字、标识符和枚举值中直接插入 TAB。
(* 注释开始 用户自定义注释,可以在程序允许空格的任何位置输入注
*) 注释结束 释,且 CoDeSys 可以通过设置允许注释嵌套。
+ 十进制数的前缀符号(正数) +456;+1.23
加操作符 23+11
- 十进制数的前缀符号(负数) -789
年-月-日的分隔符 D#1980-02-29
减操作符 19-11
# 基底数的分隔符 2#1101;16#FF
数据类型分隔符 SINT#123
时间文字的分隔符 T#200ms;TOD#05:30:35:28;t#14m_12s
. 正数和小数的分隔符 3.14;2.18
分级寻址地址符 %IX0.3
结构元素分隔符 Channel[0].type;abc.number
功能块结构分隔符 TON1.Q;SR_3.S1
E/e 指数分界符 1.0e+6;3.14E6
' 字符串开始/结束符 'Hello World!!'
$ 串中特殊字符的开始 '$L'表示换行;'$R'表示回车
: 时刻文字分隔符 TOD#12:41:21.11
变量/类型分隔符 Test:INT
:= 初始化操作符 Var1:INT:=3
输入变量链接操作符 INT_2(SINGLE:=z2,PRIORITY:=1)
赋值操作符 Var2:=45
( ) 枚举表分界符 V:(B1_10V,UP_10V,IP_15V):= UP_10V
子范围分界符 DATA:INT(-32768..32767)
初始化重复因子 ARRAY(1..2,1..3) OFINT:=1,2,3(4),6
指令表修正符 (A>B)
函数自变量 Var2*LIMIT(Var1)
子表达式分级 (A*(B-C)+D)
功能块输入表分界符 TON_1(IN:=%IX5.1,PT:=T#500ms);
[] 数组下标分界符 MOD_5_CFG.CH[5].Range:=BI_10V;
, 枚举表分隔符 V:(BI_10V,Up_10V):=Up_1_5V;
初始值分隔符 ARRAY(1..2,1..3) OF INT:=1,2,3(4),6;
数组小标分隔符 ARRAY(1..2,1..3) OF INT:=1,2,3(4),6;
被声明变量的分隔符 VAR_INPUT A,B,C:REAL; END_VAR
功能块初始值分隔符 TON_1(IN:=%IX5.1,PT:=T#500ms);
功能块输入表分隔符 SR_1(S1:=%IX1.1,RESET:=%IX2.2);
操作数表分隔符 ARRAY(1..2,1..3) OF INT:=1,2,3(4),6;
函数自变量表分隔符 LIMIT(MN:=4,IN:=%IW0,MX:=20);
Case 至表分隔符 CASE STEP OF 1,5:DISPLAY:=FALSE;
; 类型分隔符 TYPE R:REAL;END_TYPE
语句分隔符 QU:=5*(A+B);QD:=4*(A-B);
.. 子范围分隔符 ARRAY(1..2,1..3);
Case 范围分隔符 CASE STEP OF (1..5):DISPLAY:=FALSE;
% 直接表示变量的前缀 %IW0
=> 输出连接操作符 C10(CU:=bInput,Q=>Out);

注意:
用于逻辑运算和算术运算等的操作符号为中间操作符,如 NOT、MOD、+、-、*、/、<、>、&、AND、
OR、XOR。
用于表示时间、时刻等时间文字的操作符号为时间文字分界符,如 T#、D、H、M、S、MS、DATE#、
D#、TIME_OF_DAY#、TOD#、DATE_AND_TIME#、DT#。

3.1.3 关键字

关键字是语言元素特征化的词法单元。在 IEC61131-3 标准中,关键字作为编程语言的字,被


用于定义不同结构或启动和中指特定的软件元素。
部分关键字配对使用,如 FUNCTION 与 END_FUNCTION 等。部分关键字单独使用,如 ABS
等。关键字不能用于任何其他目的,如不能作为变量名或扩展名,既不能用 TON 作为变量名,也
不能用 VAR 作为扩展名。
关键字是标准标识符,因此不能包含空格。表 2-x 列出了 CoDeSys 中常用的关键词和示例。

表 3-x 常用关键字和示例
关键字 说明 关键字 说明
PROGRAM 程序段开始 EN ,ENO 使能输入/输出
END_PROGRAM 程序结束
FUNCTION 函数段开始 TRUE 逻辑真
END_FUNCTION 函数段结束 FALSE 逻辑假
FUNCTION_BLOCK 功能块段开始 TYPE 数据类型段开始,
END_FUNCTION_ 功能块段结束 END_TYPE 数据类型段结束
BLOCK
VAR 内部变量段开始 STRUCT 结构体开始,
END_VAR 变量段结束 END_STRUCT 结构体结束
VAR_INPUT 输入变量段开始 IF THEN EISIF IF 语句
END_VAR 变量段结束 ELSE END_IF
VAR_OUTPUT 输出变量段开始 CASE OF ELSE CASE 语句
END_VAR 变量段结束 END_CASE
VAR_IN_OUT 输入输出变量段开始 FOR TO BY DO FOR 循环语句
END_VAR 变量段结束 END_FOR
VAR_GLOBAL 全局变量段开始 REPEAT UNTIL REPEAT 循环语句
END_VAR 变量段结束 END_REPEAT
CONSTANT 常数变量 WHILE DO WHILE 循环语句
END_WHILE
ARRAY OF 数组 RETURN 跳转返回符
AT 直接地址 NOT,AND,OR,XOR 逻辑操作符
此外,下列功能模块和函数胡的标识符也被保留作为关键字
1) 标准数据类型:BOOL,REAL,INT 等。
2) 标准函数名和功能块名:SIN,COS,RS,TON 等。
3) 指令表语言中的文本操作符:LD,ST,ADD,GT 等。
4) 结构化文本语言中的文本操作符:NOT,MOD,AND 等。

3.1.4 句法颜色

所有编辑器中不同的文本带有不同的颜色,不但可以变面错误,而且有助于快速的发现错误。
例如,注释没有被括上,从字体颜色上就会立即得到提示。句法颜色示例如图 3.x 所示。
 蓝色:关键字。
 绿色:编辑器中的注释。
 粉红:特殊的常数(例如 TRUE/FALSE、T#3s、%IX0.0)。
 红色:输入错误(例如无效时间常数、小写的关键字)。
 黑色:变量、常数、标点符号。

图 3.X 句法颜色
3.1.5 空格和注释

1. 空格
在程序文本的任何地方允许插入一个或多个空格。但在关键字、标识符、分界符等内部允许包
含空格。表 3-x 是空格的应用和示例。

表 3-x 空格的应用及示例
序号 描述 示例
1 允许的空格 LD %IX0.2:SR1(SET1 := Start, Reset:=Stop);
2 不允许的空格 L D %IX0.2:SR1(S ET1 := Start, Reset:=Stop);
2. 注释
通常在程序中在我们认为逻辑性较强的地方需要加入注释,以说明这段程序的逻辑是怎样的,
方便我们自己后来的理解以及其他人的理解,合理的添加注释可以增加代码的可读性。
在所有的文本编辑器、声明编辑器、语句表、结构化文本语言和在自定义数据类型中都允许使
用注释。如果工程使用一个模板来打印输出,在变量声明过程中输入的注释出现在每个变量后的基
于文本编程组件中。在 CoDeSys 针对不同的编程语言及编辑器拥有不同的注释方法,如下会做详
细分解。
1) 结构化文本 ST 的注释
在结构化文本中分有单行注释和多行注释两种。
 多行注释
以(*开始,以*)结束,这允许注释跨越多行。例如:“ (*This is a comment.*)”。使用实际效果
如图 3.x 所示。

图 3.X 多行注释
 单行注释
行注释,使用符号“//”来进行标注,使用该注释方法,可注释一行。例如: “// This is a
comment.”在 CoDeSys V2 的版本中暂不支持此种注释方式。使用实际效果如图 3.x 所示。

图 3.X 单行注释
 注释的嵌套
在日常的使用中,常会遇到需要将注释嵌套的应用,CoDeSys 支持此种注释方法,且上文中介
绍到的两种注释方法在同一程序段内可以混合使用,如图 3.x 所示。
图 3.X 注释的嵌套
2)FBD、LD 和 IL 中的注释
在 “工具”-->“选项”-->“FBD、LD 和 IL 编辑器”选项中选择常规可以对 FBD、LD 和 IL
编程语言的注释试图进行设置,如图 3.x 所示。

图 3.X 注释常规设置
将“显示节注释”选项勾选后,既可在对应的编程语言中插入/显示节注释,如图 3.x 为使用
FBD 编程语言,在网络节中添加注释的截图。

图 3.X FBD 中的注释显示


3) CFC 中的注释
在 CFC 中可随意放置注释,在“工具箱”中-->选择 “ ”进行添加注释,如图 3.x
的 a)所示。图 3.x 的 b)为在 CFC 编程语言中显示的结果。

a) b)

图 3.X CFC 中注释的显示


a )工具箱中添加注释 b )CFC 中使用注释
4) SFC 中的注释
在 SFC 编程语言中,能在编辑步属性对话中输入关于步的注释,如图 3.x 所示。

图 3.X SFC 中注释的显示


5) 注释的字体设置
可以在“工具”-->“选项”中设置注释的字体及颜色。
图 3.X 注释字体的设置

3.2 常数

3.2.1 常数的表示方法

数值文字(Numeric Literal)用于定义一个数值,它可以是十进制或其他进制的数。数值文字
分为两类:整数文字和实数文字。
书写如下: <类型># <数值>
<类型>指定所需的数据类型;可能条目 BOOL, SINT, USINT, BYTE, INT, UINT, WORD, DINT,
UDINT, DWORD, REAL, LREAL 该类型必须是书面的大写字母。
<数值>指定常数。输入的数据必须符合指定的数据类型<类型> 。
1. 数值常数
数值常数可用二进制、十进制和十六进制数表示。假如一个整数不是十进制数,你必须在该整
数常数之前写出它的基数,并加上数字符号(#),用户可在数值中使用下划线,例如 2#101。
1) BIN(2 进制)
2 进制的 1 位(bit)只能取 0 或 1,用来表示开关量(或称数字量)的两种不同的状态。例如,
若 QX0.0:=1,表示线圈“通电”状态,称改编成元件为 ON 或 1 状态;若 QX0.0:=0,则表示线圈
为“断电”状态,称该编程元件为 OFF 或 0 状态。
二进制数直接表示可用 2#前缀表示,例如 2#1111 1111 1111 0000 表示 16 位二进制常数。在编
程时,位编程元件的 1 状态和 0 状态常用 TRUE 和 FALSE 来表示。
2) DEC(十进制)
十进制数是组成以 10 为基础的数字系统,满十进一。十进制数前缀 10#不需要表示,可直接
表示,例如 255,则直接表示 10 进制数的 255。
3) HEX(十六进制)
十六进制的 16 个数字由 0~9 和 A~F(对应于十进制数 10~15)组成,其运算规则为逢 16 进
1,每个数字占二进制数的 4 位。在 CoDeSys 中 16#用来表示十六进制数的前缀。例如 16#E5。

表 3-x 数值文字的性能和示例
数值文字类型 表示方法 示例
整数文字 [整数类型名#]符号整数或二(八、十、十六)进制整数 INT#-34,UINT#32
二进制整数 2#0010_0010(34)
八进制整数 8#77(63)
十六进制整数 16#E5(229)
实数 [实数类型名#]符号整数.整数[指数] REAL#4.94,6.3e-7
符号整数.整数 3.141592
布尔数 [布尔类型名#]0 或 1,False 或 True 0,1,True,BOOL#1
这些数值可以是变量类型 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL 或 LREAL。不允许将较大的变量类型转换为较小的变量类型。这意味着,一个
DINT 变量不能简单地作为 INT 变量。你必须使用类型转换功能才能做到这种转换。
在 CoDeSys 中可以设置数值的显示方式,可在监视窗口单击鼠标右键,选择“显示模式”进
行显示的选择。

图 3.X 数值显示模式更改

2. BOOL 常数
BOOL 常数为逻辑值 TRUE(真)与逻辑值 FALSE(假)。在 CoDeSys 中也可以用 1(真)或
0(假)表达相同的意思。
3. TIME 常数
一个 TIME 常数总是由一个起始符 T 或 t (或用 TIME 或 time )和一个数字标识符 # 组成。然
后,是跟随的实际时间声明,包括天数( d)、小时( h)、分钟( m )、秒( s )和毫秒
( ms )。请注意时间各项必须根据时间长度单元顺序进行设置(d 在 h 之前,h 在 m 之前,m 在 s
之前,s 在 ms 之前),但无须包含所有的时间长度单位。
在 ST 语言的赋值语句中,正确使用时间常数的示例 :
TIME1 := T#14ms;
TIME1 := T#100S12ms;(*最高单位的值可以超出其限制*)
TIME1 := t#12h34m15s;
使用时间常数的示例 :
TIME1 := t#5m68s;(*最低单位的值溢出*)
TIME1 := 15ms;(*没有 T#*)
TIME1 := t#4ms13d;(*输入的顺序错误*)
4. DATE 常数
这些常数可用来输入日期。声明一个 DATE 常数时,起始符为 d , D , DATE 或 date 后跟随一个
# 号。然后你就可按照年-月-日的格式输入任何日期。例如,
DATE#1996-05-06
d#1972-03-29
5. TIME_OF_DAY 常数
使用这种类型常数可保存一天中的不同的时间。一个 TIME_OF_DAY 常数的声明使用起始符
tod# 、 TOD# 、TIME_OF_DAY# 或 time_of_day# ,后跟随一个时间格式为:小时:分:秒的时间。
秒值可以是实数也可是小数,例如,
TIME_OF_DAY#15:36:30.123
tod#00:00:00
6. DATA_AND_TIME 常数
日 期 常 数 和 一 天 中 的 时 间 常 数 可 合 并 起 来 构 成 一 个 所 谓 的 DATE_AND_TIME 常 数 。
DATE_AND_TIME 常数的起始符为 dt# , DT# , DATE_AND_TIME# 或 date_and_time# 。在日期之
后用(-)字符连接时间,例如,
DATE_AND_TIME#1996-05-06-15:36:30
dt#1972-03-29-00:00:00
7. REAL / LREAL 常数
REAL 和 LREAL 常数可使用十进制小数和指数形式表示。使用带小数点的美国格式表示实数
(REAL / LREAL),例如,
7.4 取代 7,4
1.64e+009 取代 1,64e+009
8. STRING 常数
一个字符串是一个字符队列。STRING(字符串)常数使用一个单引号作为其前缀和后缀。也
可以输入空格和专用字符(如音符)。这些字符将同所有其它字符一样进行处理。在字符对列中,
($)号和后面跟随的两个十六进制数组合被解释为八位字符码的十六进制表示。此外,以$作为起
始符的两个字符的组合,其含义如表 3-x 所示,并以字母的顺序排列。

表 3-x 字符串特性和示例
字符串 描述
$<两个十六进制数> ASCII 码的十六进制表示
$$ 美元符号
$' 单引号
$L 或 $l 输入行
$N 或 $n 新行
$P 或 $p 输入页
$R 或 $r 换行
$T 或 $t Tab 键
‘coesys!!’
‘3S’
‘:-)’
9. 类型符
通常,对 IEC 常数,有可能使用最小的数据类型。如必需使用另一种数据类型。则可借助于类
型符而不需要显示地声明常数。为此,常数可使用一个前缀表示,该前缀决定了其类型。
格式:<Type>#<Literal>
<Type>指定所要求的数据类型:BOOL、SINT、USINT、BYTE、INT、UINT、WORD、DINT、
UDINT、DWORD、REAL、LREAL(类型必须使用大写字母)。
<Literal>指定常数。输入的数据必须与<Type>下指定的数据类型相匹配。
Var1:=DINT#34;
如果常数不能保证在不丢失数据的情况下转换为目标类型,系统将发出一个出错信息。类型符
可用于一般常数。
第4章 变量
本章主要知识点
 变量的声明
 数据类型
 变量类型和属性

4.1 变量的表示和声明
变量可以用来表示一个数值,一个字符串值或一个数组等。CoDeSys 将变量的数据类型分为了
标准数据类型、扩展数据类型及自定义数据类型三大类。

4.1.1 变量

变量是保存在存储器中待处理的抽象数据,是为了识别 PLC 的输入/输出、PLC 内部的存储区


域而使用的名称,可以代替物理地址在程序中的使用。
可以根据需要随时改变变量中所存储的数据值。在程序执行过程中,变量的值可以发生变化。
使用变量之前必须先声明变量,及指定变量的类型和名称。变量具有名称,类型和值。变量的数据
类型确定它所代表的内存大小和类型。变量名即指在程序源代码中的标识符。

4.1.2 标识符

标识符就是变量的名称。在定义标识符时,根据 IEC 61131-3 标准,必须由字母、数字和下划


线字符组成。此外,含应遵循如下规则:
 标识符的首字母必须是字母或下环线,最后一个字符必须是字母或数字,中间允许字母、数字、
下划线。
 标识符中不区分字母的大小写。
 下划线是标识符的一部分,但标识符中不允许有两个或两个以上连续的下划线。
 不得含有空格
例如 ab_c、AB_de 和_AbC 是允许的标识符,而 1abc、 __abc 和 a__bc 均不允许。

4.1.3 变量声明

变量声明就是指定变量的名称、类型和赋初始值,变量的声明非常重要,未经声明的变量是不
能通过编译的,所以也无法在程序中使用。用户可以在程序组织单元(POU)、全局变量列表
(GVL)和自动声明对话框中进行变量的声明。在 CoDeSys 中变量声明分为两类,普通变量声明
和直接变量。
1) 普通变量声明
最常用的变量声明,不需要和硬件外设或通讯进行关联的变量,仅供项目内部逻辑使用。普通
声明须符合以下规则:
< 标识符>:<数据类型> {:=<初值>};
{}中为可选部分。
如 nTest:BOOL;,nTest:BOOL:=TRUE;
2) 直接变量声明
在 CoDeSys 应用中,当需要和可编程逻辑控制器的 I/O 模块进行变量映射或和外部设备进行网
络通讯时,需要采用此声明方法。
使用关键字 AT 把变量直接联结到确定地址,直接变量须符合以下规则:
AT<地址>:
< 标识符> AT <地址>:<数据类型> {:=<初始化值>};
{}中为可选部分。
使用“%”开始,岁后是位置前缀符号和大小前缀符号,如果有分级,则用整数表示分级,并
用小数点符号“.”表示,如%IX0.0,%QW0。直接变量声明的具体格式如图 4.X 所示。

图 4.X 直接变量的表示方法
位置前缀的定义:
 I:表示输入单元。
 Q:表示输出单元。
 M:表示存储区单元。
大小前缀的定义如表 4-X 所示。

表 4-X 大小前缀定义
前缀符号 定义 约定数据类型
X 位(bit) BOOL
B 字节(BYTE) BYTE
W 字(WORD) WORD
D 双字(DWORD) DWORD
L 长字(LWORD) LWORD
* 未特定位置的内部变量,系统自动分配。
【例 4.X】在程序中定义了变量双字型 Var1,如需拿取该变量其中的一部分数据,将其转换成
布尔/字节/字类型的变量,其首地址为多少,该如何换算:
VAR
Var1 AT%ID48:DWORD;
END_VAR
%I 说明了该变量属于输入单元,具体的地址为%ID48。该地址对应的内存映射详见表 4-x 所示。
字地址%IW96 和%IW97 两个字组合后对应%ID48,因为 48* 2(字节)后的字节首地址为 96。同
样的道理,字节地址%IB192、%IB 193、%IB 194 和%IB 195 这四个字节变量组合后对应%ID48,
因为 48 * 4(字节) 后对应的字节首地址正好为 192。表 4.x 列出了 CoDeSys V3.x 在寻址时,根据
数据类型的大小(X:bit,B:byte,W:word,D:dword)。

表 4-x
%IX 96.0 - 96.7 96.8 - 192.15 97.0 - 97.7 97.8 - 97.15
%IB 192 193 194 195
%IW 96 97
%ID 48
【例 4.x】相信有了例 2.X 的基础,就很容易理解如下的地址映射关系。
1) %MX12.0:是%MB12 的第一位。
2) %IW4:表示输入字单元 4(字节单元 8 和 9)。
3) %Q*:输出在一个为特定的位置。
4) %IX1.3:表述输入第 1 字节单元的第三位。

注意:
这里介绍的计算方法只适用于 CoDeSys V3.x 的,CoDeSys V2.x 的计算方法略有不同。

4.2 数据类型
无论声明的是变量还是常量,都必须使用到数据类型。数据类型的标准化是编程语言开放性的
重要标志,在 CoDeSys 中数据类型完全符合 IEC61131-3 所定义的标准, CoDeSys 将数据类型分为
标准数据类型、IEC1131-3 标准的扩展数据类型和自定义数据类型,数据类型决定了它将占用多大
的存储空间以及将存储何种类型的值。

4.2.1 标准数据类型

CoDeSys 标准数据类型共分为 5 大类,分别为布尔类型、整数类型、实数类型、字符串类型和


时间数据类型,图 2-1 将 CoDeSys 所支持的标准数据类型列举出来。

表 2-1 标准数据类型
数据大类 数据类型 关键字 位数 取值范围
布尔 布尔 BOOL 1 FALSE(0)或 TEUE(1)
整型 字节 BYTE 8 0~255
字 WORD 16 0~65535
双字 DWORD 32 0~4294967295
长字 LWORD 64 0~(2^64-1)
短整型 SINT 8 -128~127
无符号短整型 USINT 8 0~255
整型 INT 16 -32768~32767
无符号整型 UINT 16 0~65535
双整型 DINT 32 -2147483648~2147483647
无符号双整型 UDINT 32 0~4294967295
长整型 LINT 64 -2^63~(2^63-1)
实数 实数 REAL 32 1.175494351e-38~3.402823466e+38
长实数 LREAL 64 2.2250738585072014e-308~
1.7976931348623158e+308
字符串 字符串 STRING 8*N
时间数据 时间 TIME 32 T#0ms~T#71582m47s295ms
TIME_OF_DAY TOD#0:0:0~TOD#1193:02:47.295
DATE D#1970-1-1~D#2106-02-06
DATE_AND_TIME DT#1970-1-1-0:0:0 ~DT#2106-02-06-06:28:15

1. 布尔
布尔型变量用来表示 TRUE/FALSE 值,一个布尔型变量只有 TRUE 或 FALSE 两种状态,在
CoDeSys 还可以使用 0 或 1 来表示。
类型 内存使用
BOOL 8位
【例 4.X】将开门信号和取料信号的与逻辑结果赋值给布尔型变量 bReady,结构化文本语言代
码如下。
VAR
bReady, bDoors_Open, bGrip:BOOL;
END_VAR

bReady:=(bDoors_Open and bGrip);


在 CoDeSys 中允许将相同类型的变量进行统一声明,用“,”进行分割。
【例 4.X】将十进制数 211 赋值给 bReady 变量,结构化文本语言代码如下。
VAR
bReady:BOOL;
END_VAR

bReady:=211;
显然这种赋值方式是错误的,通过程序编译后,编译会返回错误提示“C0032:不能将类型
‘USINT’转化为类型‘BOOL’”。布尔型变量是使用最多的一种变量类型,在流程控制语句中
(如 IF,CASE,循环)中时常会用到,所以学会正确使用布尔变量至关重要。

注意:
如果在内存中的最低位被置位(例如 2#00000001 ),则 BOOL 类型变量为“true”(真)。如果内存
中最低位没有被置位,则 BOOL 变量为 FALSE 例如 2#00000000。所有其它值都不能被正确地进行转换,并显
示为 (***INVALID:16#xy *** ,联机监视时)。类似的问题是可能出现的,例如,在 PLC 程序中使用了重叠的内
存范围。
例如,如果定义了一个布尔数组, A:ARRAY[0..7] OF BOOL,在系统中,它所占用的总内存并不是一个
8 位字节,而是占用了 8 个 8 位字节。

2.整型
整型类型代表了没有小数点的整数类型,CoDeSys 中支持的整型类型在表 2.1 中所示。
在 CoDeSys 中,整型是一个最大的标准类,其成员最多,没有必要将每个类型的关键字死记
硬背,只要了解其中的规律,就非常容易记忆,下面简单的说明了整型前缀其中的规律。
 U___表示无符号数据类型,U 为 Unsigned 的缩写。
 S___表述短数据类型,S 为 Short 的缩写。
 D___表述双数据类型,D 为 Double 的缩写。
 L___表述长数据类型,L 为 Long 的缩写。
如 UINT 为无符号的整型数据,USINT 即为无符号的短整型数,LINT 表示长整型数据。
【例 4.X】整型举例。
VAR
nValue1:USINT;
nValue2:LINT;
nValue3:WORD;
END_VAR

nValue1:=4;
nValue2:=nValue1+nValue3;
nValue3:=16;
nValue2 最终的输出结果为 20。
无符号(Unsigned)和有符号(signed)的区别是最高位的区别。
无符号类型数据将全部存储空间全部储存数据本身,没有符号位。如 UINT 型将 16 为全部存
储数据本身,即数据范围可以从0~(216 − 1),即 0~65535。
有符号类型数据牺牲最高位作为符号位。如 INT 型变量牺牲最高位作为符号位,剩下 15 位作
为数据存储,故该数据范围为−215 ~(215 − 1),即-32768~32767。所以有符号整型变量中可以
存放的正数的范围比无符号的整形变量中正数的范围缩小一倍。
如下通过两个变量对无符号和有符号进行说明:
nValue1:UINT;
nValue2:INT;

数据第 1 位
nValue1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 =65535
nValue2 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 =32767

符号位

图 4.x 无符号与有符号数据结构

3. 实数
实数,有的教科书称浮点数,这里主要是用于处理含有小数的数值数据,实数类型包含了
REAL 及 LREAL 这 2 种数据类型。REAL 实数占用 32 位存储空间,而 LREAL 长实数占用 64 为存
储空间。
在 CoDeSys 中,实数和长实数常量有两种表示形式。
1) 十进制小数形式。它由数字和小数点组成。0.123、123.1、0.0 都是十进制小数表现形式。
2) 指数形式。如 123e3 或 123E3 都代表 123×103。但注意字母 e(或 E)之前必须有数字,且 e
后面的指数必须为整数,如 e3、2.1e3.5、.e3、e 等都是不合语法的指数形式。
一 个 浮 点 数 可 以 有 多 种 指 数 表 示 形 式 , 如 123.456 可 以 表 示 为 123.456e0 、 12.3456e1 、
1.23456e2 等。其中的 1.23456e2 称为“规范化的指数形式”。即在字母 e(或 E)之前的小数部分
中,小数点左边应有一位(且只能有一位)非零的数字。
【例 4.X】将 12.3 赋值给 rRealVar1 变量,结构化文本语言代码如下。
VAR
rRealVar1:REAL;
END_VAR

RealVar1:=1.23e1;
上例中,1.23e1 表示就是 12.3,当然也可以直接通过表达式 RealVar1:=12.3 完成上例要求。
此时如果将要求更换为将 0.123 赋值给 rRealVar1 变量,通过上面提到的规律,只需将表达式
更换为,
RealVar1:=1.23e-1;
或者,
RealVar1:=0.123;

注意:
数据类型 LREAL 的支持取决于目标设备。在编译时 64 位类型的 LREAL 是被转换为 REAL(可能有信息
丢失),还是保持不变,需参考不同硬件产品的相应文档。
如果 REAL 或 LREAL 类型转换成 SINT, USINT, INT, UINT, DINT, UDINT, LINT 或 ULINT 类型,且
实型数据的值超出了整形的范围,结果将会是不确定的并且该值取决于目标系统。这种情况有可能产生异常! 为了
获取与目标无关的代码,应由应用程序处理所有值域越界问题。如果 REAL/LREAL 型数据在整形的值域范围内,
他们之间的转换在所有系统上都可以进行。

4. 字符串
一个字符串是一个字符队列。字符串(STRING)常数使用一个单引号作为其前缀和后缀。也
可以输入空格和专用字符(如音符)。这些字符将同所有其它字符一样进行处理。
在 CoDeSys 中,字符串类型变量可以包含任意一串字符,使用单撇号括起来的一个字符串,
如’Hello‘、‘How are you‘、‘CoDeSys‘、‘why?‘等都是字符常串量,声明时的大小决定了存储变量所
需要的存储空间。这里的存储空间它是指字符串中字符的数量,用圆括号或方括号括起来,具体计
算及声明方法如下。
 如果在定义变量是没有指定字符串大小,系统则默认分配 80 个字符给该变量,系统中实际占
用存储空间=[80+1] BYTE。
例如在变量声明中定义的是 Str1:STRING:=‘a‘; ,虽然 Str1 变量初始值只包含一个字符,但由
于再声明中未使用括号来限定字符串大小,故 Str1 在系统内占用的内存空间为 80+1 个字节。
 如果定义了大小,则系统中实际占用存储空间=[空间的大小为(定义字符串大小)+1] BYTE。
CoDeSys 中一般不限制字符串的长度,但是字符串函数只能处理长度在 1-255 个字符之间的字
符串! 如果一个变量用字符串初始化,而字符串对于变量的数据类型来说又太长,字符串将会从
右至左相应的截断。
字符串在程序中的表示时,为了和普通的变量区分开,需要加单引号‘XXX‘。
【例 4.X】将字符串‘Hello CoDeSys’赋值给 str 变量。
VAR
str:STRING;
nNum: WORD;
END_VAR

str:='Hello CoDeSys';
nNum:=SIZEOF(str); (*使用 SIZEOF 指令查看存储空间占用量*)
程序运行的结果如图 2.X 所示,'Hello CoDeSys'实际字符数为 13 个字符,占存储空间的大小为
14 个字节,但是使用 SIZEOF 指令看到的输出结果为 81 个 BYTE,其原因就是因为没有指定字符
串大小,系统自动分配了 80 个字符给 str 变量,如果一个程序中有很多字符串变量,且在声明时均
未将其限制,这样就会导致程序中的存储空间被大量浪费。

图 2.X 字符串的实例运行结果图 1
【例 4.X】将字符串‘Hello CoDeSys’赋值给 str 变量,str 定义为 12 个字符大小。
VAR
str:STRING[12];
nNum: WORD;
END_VAR

str:='Hello CoDeSys';
nNum:=SIZEOF(str);
实际运行的结果如图 2.X 所示。

图 2.X 字符串实例运行结果图
从运行的结果来看,str 只显示了’Hello CoDeSy‘,缺少了一个’s‘,即多余部分已被系统自动截
断。字符串占用的存储空间为 13 个 BYTE。
5. 时间数据
时间数据类型包括 TIME、TIME_OF_DAY/TOD、DATE 和 DATE_AND_TIME/DT。系统内部
处理这些数据的方式与双字(DWORD)类型相似。
1) TIME,时间,精度为毫秒,范围从 0~71582m47s295ms。语法格式如下,
t#<时间声明>
一个 TIME 常数总是由一个起始符 T 或 t (或用 TIME 或 time )和一个数字标识符 # 组成。然
后,是跟随的实际时间声明,包括天数( d 标识)、小时( h 标识)、分钟( m 标识)、秒( s 标
识)和毫秒( ms 标识)。请注意时间各项必须根据时间长度单元顺序进行设置(d 在 h 之前,h 在
m 之前,m 在 s 之前,s 在 ms 之前),但无须包含所有的时间长度单位。
在 ST 语言的赋值语句中,正确使用时间常数的示例 :
TIME1 := T#14ms;
TIME1 := T#100S12ms; (*最高单位的值可以超出其限制*)
TIME1 := t#12h34m15s;

【例 4.X】时间类型变量的定义和使用。
VAR
tTime:TIME;
END_VAR

tTime:= T#3d19h27m41s1ms;

注意:
时间可以溢出,如小时可以超过 24h,如赋值时写入 T#3d29h27m41s1ms,系统会自动校正最终输出
的结果为 T#4d5h27m41s1ms。
以下的时间常量赋值是不正确的。
tTime:= 15ms; (*缺少 T# *)
tTime:= t#4ms13d; (*顺序错误*)

2) TIME_OF_DAY/TOD,时刻,精度为毫秒,范围从 0:0:0~1193:02:47.295。时刻声明使用
“<时:分:秒>”的格式。语法格式如下。
tod#<时间声明>
除了“tod#”,也可以使用“TOD#”、“time_of_day”、“TIME_OF_DAY”表示。
【例 4.X】时刻类型变量的定义和使用。
VAR
tTime_OF_DAY:TIME_OF_DAY;
END_VAR

tTime_OF_DAY:= TOD #21:32:23.123;


上式中,表示的时间为 21 点 32 分 23 秒 123 毫秒。

3) DATE,日期,精度为天,范围从 1970-01-01~2106-02-06。日期声明使用“<年-月-日>”的
格式。语法格式如下。
dt#<日期声明>
除了“d#”也可以使用也可以用“D#”、“date”、“DATE”表示。
这些常数可用来输入日期。声明一个 DATE 常数时,起始符为 d , D , DATE 或 date 后跟随一个
# 号。然后你就可按照年-月-日的格式输入任何日期。
【例 4.X】日期类型变量的定义和使用。
VAR
tDate:DATE;
END_VAR
tDate:=D#2014-03-09;
表示的时间为 2014 年 3 月 9 日。
4) DATE_AND_TIME/DT,日期和时间,精度为秒,范围从 1970-01-01-00:00~2106-02-06-
06:28:15。日期和时间的声明使用“<年-月-日-时:分:秒>”的格式,语法格式如下。
dt#<日期和时间声明>
除了“dt#”,也可以使用“DT#”、“date_and_time”、“DATE_AND_TIME” 表示。
【例 4.X】日期和时间类型变量的定义和使用。
VAR
tDT:DATE_AND_TIME;
END_VAR

tDT:=DT#2014-03-09-16:22:31.223;
表示时间为 2014 年 3 月 9 日 16 点 22 分 31 秒 223 毫秒。

4.2.2 标准的扩展数据类型

作为对 IEC61131-3 标准中数据类型的补充,CodeSysV3.x 隐含一些标准的扩展数据类型有联合、


长时间类型、双字节字符串、引用、指针。

表 2.2 IEC1131-3 标准的扩展数据类型


数据大类 数据类型 关键字 位数 取值范围
联合 联合体 UNION 自定义
时间数据 长时间 LTIME 64 ns~d
字符串 双字节字符 WSTRING 8*N
引用 引用 REFERENCE TO 自定义
指针 指针 POINTER TO 自定义
1. 联合体
1) 联合体概念
有时需要使几种不同类型的变量存放到同一段内存单元中,比如可以把一个 INT、一个 BYTE
和一个 DWORD 型变量放在同一地址开始的内存单元中,如表 4-x 所示,从同一地址 16#100 开始
存放。

表 4-x 联合体内存映射表
16#100 16#101 16#102 16#103
INT
BYTE
DWORD
上表中,有填充色部分为覆盖区域,这种使几个不同的变量共占同一段内存的结构成为联合。
联合体声明的语法如下:
TYPE <联合体名>:
UNION
<变量的声明 1>
.
.
<变量声明 n>
END_UNION
END_TYPE
【例 4.X】定义一个联合体 NAME,对其中的某一个成员进行赋值,试比较结果。
首先,先在数据单元类型中新建一个名为 NAME 的联合,选中“Application”右键-->“添加
对象”-->“DUT”,如图 4.x 所示,确定后在联合编辑器中输入如下内容。
图 4.X 新建联合体
TYPE NAME :
UNION
var1:STRING(20);
var2:STRING(20);
var3:STRING(20);
END_UNION
END_TYPE
在程序中写的代码如下,
VAR
nName:NAME;
END_VAR

nName.var1:='Zhang San';
最终输出的结果如图 2.X 所示,即所有 nName 中的成员的数值都被统一的写入'Zhang San'。

图 4.X 联合实例运行结果图 1
此外,联合体内的成员数据类型可以不一样,通过如下的例子,让读者对联合体有更深一步的
理解。
【例 4.X】使用联合体,实现将 2 个字节变量整合成一个字变量的功能。
首先,先在数据单元类型中新建一个名为 Un_WORD 的联合,内容如下,
TYPE Un_WORD :
UNION
nWord:WORD;
nByte:ARRAY [0..1] OF BYTE;
END_UNION
END_TYPE
程序及声明如下:
VAR
UN_Word_test:Un_WORD;
nByte_Low:BYTE:=16#12;
nByte_Hight:BYTE:=16#34;
END_VAR

UN_Word_test.nByte[0]:=nByte_Hight;
UN_Word_test.nByte[1]:=nByte_Low;
结果如图 2.x 中的 nWord 所示。

图 2.X 联合实例运行结果图 2
在联合中使用成员 nWord 作为整合后 WORD 变量存放的地址,由于联合体内所有成员数据结
果都一样的特性,决定了 WORD 和数组中 2 个 BYTE 的映射关系,具体映射关系如下。

表 5.x 地址映射关系表
变量 位 位
nWord 15~8 7~0
nByte[0] 15~8
nByte[1] 7~0
如上 nByte[1]对应 nWord 的低 8 位,nByte[0]对应 nWord 的高 8 位。所以只需在程序内,分别
将 2 个 BYTE 分别对应低 8 为和高 8 位即可实现分别将两个 BYTE 的数值整合在一个 WORD 型变
量内的功能。
在图 2.X 中可以看出,给其中的某一个变量 var1 进行赋值,相当于给联合中所有的变量都进行
了赋值。但需要注意到是,在此例中,NAME 下的三个变量类型都定义为 REAL,如当类型不同,
首先要确保数据占用存储空间相同,如使用不当,数据可能会出现错乱。
2. 长时间类型
提供长时间类型数据作为高精度计时器的时间基量。与 TIME 类型不同的是:TIME 的长度为
32 位且精度为毫秒,LTIME 的长度为 64 位且精度为纳秒。
LTIME:长时间,精度为纳秒。可以用 LTIME#表示日期和时间,语法格式如下。
LTIME#<长时间声明>
【例 4.X】长时间赋值。
VAR
tLT:LTIME;
END_VAR

tLT := LTIME#1000d15h23m12s34ms2us44ns;
3. 宽字符串
与字符串类型数据(ASCII)不同的是,这一数据类型由 Unicode 解码。
每个字符串占的存储空间为 2*N+2;
wstr:WSTRING:='This is a WString';

4.引用
引用是一个对象的别名。这个别名可以通过变量名读写。与指针不同的是,引用所指向的数据
将被直接改变,因此引用的赋值和所指向的数据是相同的。设置引用的地址用一个特定的赋值操作
完成。一个引用是否指向一个有效的数据(不等于 0),可以使用一个专门的操作符来检查,如下
所示。
用以下语法声明引用,语法格式如下。
<标识符> : REFERENCE TO <数据类型>

【例 4.X】引用样例程序。
VAR
REF_INT : REFERENCE TO INT;
Var1: INT;
Var2 : INT;
END_VAR

REF_INT REF= Var1; (* 此时 REF_INT 指向 Var1 *)


REF_INT := 12; (* 此时 Var1 的值为 12 *)
Var2:= REF_INT * 2; (* 此时 Var2 的值为 24 *)

输出结果如图 4.X 所示。

图 4.X 引用的例程输出结果
此外,可以通过专用指令“__ISVALIDREF”检查变量是否已经被正确引导。
具体用法如下:
<布尔变量> := __ISVALIDREF(<数据类型>声明为 REFERENCE 类型);
如果引用指向一个有效值,则返回值<布尔变量>为真(TRUE),否则为假(FALSE)。
如上<数据类型>必须被声明为引用类型,即为“REFERENCE”,否则该指令无效。
【例 4.X】 有效引用检查的样例程序。
VAR
REF_INT : REFERENCE TO INT;
Var1: INT;
Var2 : INT;
bTestRef: BOOL := FALSE;
END_VAR

REF_INT REF= Var1; (* 此时 REF_INT 指向 Var1 *)


REF_INT := 0; (* 此时 Var1 的值为 12 *)
bTestRef := __ISVALIDREF(REF_INT); (* 为 TRUE,因为 rREF_INT 指向 Var1,它不等于
0 *)
5. 指针
1) 指针的概念
所谓指针就是一个地址。如果在 CoDeSys 中定义了一个变量,然后对其进行编译,系统则会
给这个变量分配相应的内存单元。系统根据变量的类型分配相应的内存空间,如一个 BYTE 变量,
系统则为其分配 1 个字节的存储空间,如果是一个 REAL 类型变量,系统则为其分配 4 个字节的内
存存储空间。内存以字节为单位,以“地址”进行编号,可以理解为酒店的房间号,地址所标志的
内存单元中存放着具体的数据,这就相当于在宾馆中居住的客人。
一般而言,程序都是通过变量名来对内存单元进行存储操作的。这是因为程序经过 CoDeSys
编译后,已经将变量名转换为变量的内存地址,对变量的存储其实都是通过内存地址所进行的。如
假设在程序中定义了 var1,var2 和 var3 三个变量,在声明时将其都定义为 WORD 类型,经过系统
编译后,系统分配给 var1 的内存空间为两个字节,地址分别为 1000 和 1001,var2 为 1002 和 1003,
var3 为 1004 和 1005。1000 和 1001 内存中的具体数据则是 var1 内的具体数据,var2 和 var3 也是相
同的道理,示意图如图 4.x 所示。此种按变量地址存储数据的方式在高级语言中也称之为“直接访
问”方式。

图 4.X 变量名对应内存地址查询变量
2) 指针变量
至此,读者应该对指针有了初步的概念,一个变量的地址称为该变量的“指针”。如地址为
1000 和 1001 的变量是 var1 的指针,如图 4.x 所示。
如果有一个变量专门用来存放另一个变量的地址(指针),此时,我们则称它为“指针变量”。
为了更好的理解指针变量的概念,在此举一个例子,为了打开 A 抽屉有两种方法,一是将 A 钥匙
带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西,也就是之前所提到的“直接访问”。
还有一种方法是,为了安全,可以将 A 钥匙放到另一个抽屉 B 中所起来。如果需要打开 A 抽屉,
就需要先找出 B 钥匙,打开 B 抽屉,取出 A 钥匙,再打开 A 抽屉,取出物品。这就是所谓的“间
接访问”的概念。在 CoDeSys 中使用关键字“POINT TO+类型”对指针变量进行声明。类型可以
为变量、程序、功能块、方法和函数的内存地址。它可以指向上述的任何一个对象以及任意数据类
型,包括用户定义数据类型。
声明指针的语法如下:
<标识符>: POINTER TO <数据类型 | 功能块 | 程序 | 方法 | 函数>;
取指针地址内容即意味着读取指针当前所指地址中存储的数据。通过在指针标识符后添加内容
操作符“^”,可以取得指针所指地址的内容。通过下面的例子,希望读者对指针能有更深刻的理
解。
【例 4.X】指针举例,
VAR
PointVar:POINTER TO INT;
var1:INT := 5;
var2:INT;
END_VAR

PointVar := ADR(var1);
var2:= PointVar^;
图 4.x 指针示例
程序输出的结果如 4.x 所示,在声明中先定义 PointVar 变量为指针变量,该变量将来用于存储
地址数据。
程序中使用了 ADR 指令,该指令是用来获取变量内存地址的操作符,执行完第一条指令后,
PointVar 内就已经获取了 var1 的内存地址信息(16 进制的 13B7143A)。
PointVar^指的是该内存地址中对应的具体数据(16#13B7143A 中的数据),即 var1 中 5。第二
条指令执行后,就将 PointVar^赋值给了 var2,故 var2=5。
【例 4.X】使用指针,将 INT 型变量 nIntValue 中的低 8 位数据和高 8 位数据分别赋值给 BYTE
型变量 nByte_low 和 nByte_high。
VAR
PointVar_int:POINTER TO INT;
PointVar_byte_low:POINTER TO BYTE;
PointVar_byte_High:POINTER TO BYTE;
nIntValue:INT := 16#1234;
nByte_low:BYTE;
nByte_high:BYTE;
END_VAR

PointVar_int := ADR(nIntValue);
PointVar_byte_low:=PointVar_int+1;
PointVar_byte_High:=PointVar_int;
nByte_high:=PointVar_byte_low^;
nByte_low:=PointVar_byte_High^;
图 4.x 指针程序举例
输出结果如图 4.x 所示,根据要求得知原变量为 WORD 型,故可推算出系统分配内存时会分
配给它 2 个 BYTE 的存储空间,从图 4.x 中可以看出,该 WORD 变量 nIntValue 的地址为
16#13B71438,故完整的内存空间应该为 16#13B71438 和 16#13B71439。所以在程序中用到取低 8
位 BYTE 的地址时需要在原地址的基础上+1,PointVar_byte_low:=PointVar_int+1;高 8 位 BYTE 的
地址为可以直接使用 16#13B71439。最终分别将低 8 位字节的 16#34 赋值给 nByte_low,高 8 为字
节的 16#12 赋值给 nByte_high。
3) 指针校验函数
当在程序中大量使用指针时,会涉及到大量内存地址数据,如使用不当,会导致严重的内存错
误,故 CoDeSys 系统中自带“指针校验”函数“CheckPointer Function”。指针校验函数需要检查
指针指向的地址是否在有效的存储范围之类,另外还需要检查引用的连续内存空间与指针所指的变
量的数据类型是否匹配。若满足上述两个条件,指针校验应当返回这个输入指针。出现错误时则交
由用户进行适当的处理。
为了在程序运行时检查指针的指向,可以在每次访问指针的地址之前使用隐含的“指针校验”
功能。您可以通过添加对象对话框向应用程序中添加“用于隐含检查的 POU”对象。如图 4.x 的 a)
所示,其次弹出对话框,如图 4.x 的 b)所示,,在其中选择“CheckPointer”,点击 “打开”。

a) b)

图 8.X 添加 Check Pointer 功能


a )添加“用于隐含检查的 POU” b )选择功能
点选指针校验的复选框,选择一种实现语言,确认无误后点击打开。校验功能将会在编辑器中
以您选择的语言打开。声明部分是预先设置的,与前述选项的选择无关,并且只有添加了其它局部
变量之后才可以更改。与其它校验函数不同的是,没有提供指针校验函数的默认实现,这一部分需
要由用户编写!

4.2.3 自定义数据类型

1. 数组
数组类型在 CoDeSys 中被大量使用,使用数组可以有效的处理大批量数据,可以大大提高工
作效率。
数组是有序数据的结合,其中的每一个元素都拥有相同的数据类型。例如一台设备共有 20 个
需要测量温度的点,如不使用数组,需要声明 nTemp1,nTemp2,……,nTemp20 共 20 个变量作
为测量点对应的具体温度值,而此时,如使用数组,只需定义一个数组 nTemp,将它的成员定义为
20 个,即可完成这 20 个温度变量的定义。具体指令如下所示。
nTemp :ARRAY [1..20] OF REAL;
中括号内的数据表示 20 个测量点,例如 nTemp[17]就表示第 17 个测量点的温度值。
在 CoDeSys V3.x 版本中可以直接定义一维、二维和三维数组作为数据类型。您可以在 POU 的
声明部分或者全局变量表中定义数组,声明数组的语法如下。
<数组名>:ARRAY [<ll1>..<ul1>,<ll2>..<ul2>,<ll3>..<ul3>] OF <基本数据类型>
ll1, ll2, ll3 表示字段范围的最小值,ul1, ul2 和 ul3 表示字段范围的最大值。字段范围必须是整
数。
数组的标签描述如图 4.x 中的 a)所示。访问个数组的元素,都具有相同的形式,所以数组特别
适合一个对象的多重描述,如图 4.x 中的 b)所示。
三维数组 4*4*4
ArrVar [2,5,3] 二维数组 4*4
一维数组 4*1
3维
2维
1维
数组名
ArrVar [1,3]
ArrVar [1] ArrVar [2,2,0]

a) b)

图 4.X 数组结构
a )数组结构 b )一维/二维/三维数组
在定义数组变量时可以借助 CoDeSys 内部的输入助手提高效率,在输入助手中选择“ ”,
点击“数组向导(A)”,如图 4.x 所示。

图 4.x 数组自动声明
在定义数组时,需要指定数组中元素的个数,中括号的常量表达式用来表示元素的个数,即数
组长度。例如 a[1..5],表示 a 数组共有 5 个元素。
注意:
如果下标在定义时是从 0 开始的,如 a[0..5]则表示其中的元素有 a[0],a[1] ,a[2],a[3],a[4],不存
数组元素 a[5] 。
由于 CoDeSys 最大支持三维数组,在点击确定后弹出的对话框中输入各维度的上限及下线并
且设置基本类型,如图 4.x 所示。
图 4.x 数组输入向导
1) 一维数组
一维数组是最常用的一种数据类型,通过如下举例对一维数组进行说明。
VAR
NumVar: ARRAY [1..5] OF INT;
END_VAR
程序运行后,结果如图 4.X 所示。

它表示了一个元素为 INT 类型的数组,数组名为 NumVar,此数组共有 5 个元素(1~5),成


员分别为 NumVar[1], NumVar[2],NumVar[3],NumVar[4],NumVar[5] 。
定义数组时,需要指定数组中元素的个数,方括号中的常量表达式表示的即为个数,也可以理
解为数组的长度。如 NumVar[3]。
2) 二维数组
二维数组可以看作是一个特殊的一维数组,它自身的元素可以理解为又是一个新的一维数组。
例如,可以把 a 看作是一个一维数组,它有三个元素,a[0] ,a[1] 及 a[2],而其中的每个元素又包
含 4 个元素的一维数组,如图 4.x 所示。

a[0]------------------------𝑎00 𝑎01 𝑎02 𝑎03

a a[1]------------------------𝑎10 𝑎11 𝑎12 𝑎13

a[2]------------------------𝑎20 𝑎21 𝑎22 𝑎23

图 4.x 二维数组概念
可以把 a[0] ,a[1] 及 a[2]看作是一个 3 个一维数组的名字。如上所定义的二维数组可以理解为
定义了 3 个一维数组,相当于:
VAR
a[0]: ARRAY [0..3] OF INT;
a[1]: ARRAY [0..3] OF INT;
a[2]: ARRAY [0..3] OF INT;
END_VAR
此处,把带有下划线的 a[0],a[1]和 a[2]看作一维数组名。使用此种方法在数组初始化和用指
针表示时会显得非常方便。
【例 4.X】如下为二维数组的应用举例,
VAR
Card_game: ARRAY [1..2, 1..4] OF INT;
END_VAR

图 4.x 二维数组举例
通过如上的结果可以看出,第一维的成员有两个,第二维的成员有 4 个,故在数学上,相当于
绘制了一个 2×4 的 2 维矩阵表格。
3) 三维数组
CoDeSys 允许使用多维数组,有了二维数组的基础,再掌握多维数组是不困难的,如下为三维
数组定义的举例。
arr3 : ARRAY [1..2,2..3,3..4] OF INT ;
4) 数组的初始化
对数组元素的初始化可用以下方法实现。
a) 在定义数组时对数组元素赋予初值,例如:
arr1 : ARRAY [1..5] OF INT := [1,2,3,4,5];
将数组元素的初值依次列举,经过如上的定义和初始化后,arr1[1]=1,arr1[2]=2,arr1[3]=3,
arr1[4]=4,arr1[5]=5。
b) 只给一部分元素赋值,例如:
arr1 : ARRAY [1..5] OF INT := [1,2];
定义 arr1 数组有 5 个元素,但中括号中只提供 2 个初值,这表示只有前两个元素被赋初值,没
有预置的数组元素,则使用其基本类型的默认初始值进行初始化。在本例中,数组成员 arr1[3] 到
arr1[5]均被初始化为 0。
c) 对于重复的初值,可以批量定义,只需在括号前加上数量,例如:
arr1 : ARRAY [1..5] OF INT := [1,2(3)];
“2(3)”表示 2 个 3,经过上述初始化命令后,数组的初值情况为,arr1[1]=1,arr1[2]=3,
arr1[3]=3,arr1[4]=0,arr1[5]=0。
d) 针对二维/三维数组,可以将所有数据写在中括号内,按数组排列的顺序对个元素赋初值,
例如:
arr2 : ARRAY [1..2,3..4] OF INT := [1,3(7) ];
定义一个二维数组,第一个元素的初值为 1,后三个的初值为 7,最终输出的结果为,
arr2[1,3]=1,arr2[1,4]=7,arr2[2,3]=7,arr2[2,4]=7。
arr3 : ARRAY [1..2,2..3,3..4] OF INT := [2(0),4(4),2,3];
最终输出的结果为,
arr3[1,2,3]=0 , arr3[1,2,4]=0 , arr3[1,3,3]=4 , arr3[1,3,4]=4 , arr3[2,2,3]=4 , arr3[2,2,4]=4 ,
arr3[2,3,3]=2,arr3[2,3,4]=3。
5) 数组的引用
数组必须先定义,然后再使用,CoDeSys 规定只能逐个引用数组元素,而不能一次引用整个数
组。
数组的引用形式为:
<数组名>[Index1,Index2,Index3]
下标可以是整型常量也可以是变量表达式,例如:
a[i+1,2,2]:= a[0,1,1]+ a[0,0,0]+ a[i,2,2];
6) 数组变量的存储结构
程序运行中,要访问数组元素时,首先需要了解数组变量在内存中的是如何存储的。如下还会
介绍数组变量在 CoDeSys 的内存中是如何进行存储的。
数组变量从字边界开始,也就是说,起始地址为偶数 BYTE 地址。随后,每个结构元素以其声
明时的顺序依次存储到内存中。
数据类型为 BOOL,BYTE 的结构元素从偶数字节开始存储,其他数据类型的数组元素从字地
址开始存储,如图 4.x 中一维数组 BYTE 和 WORD 数据类型所示。
二维数组中元素的排列顺序是按行存放的,即在内存中先顺序存放第一行的元素,在存放第二
行的元素,图 4.x 表示了二维数组 a [0..2, 0..3]数组存放的顺序。

𝑎00 𝑎01 𝑎02 𝑎03

𝑎10 𝑎11 𝑎12 𝑎13

𝑎20 𝑎21 𝑎22 𝑎23

图 4.x 二维数组变量的存储结构
三维数组在内存中的排列顺序:第一维的下标变化最慢,最右边的下标变化最快。例如,假定
有三维数组 a[0..1,0..2,0..3],其内部的元素的内存排列顺序为:
a[0,0,0]—> a[0,0,1] —> a[0,0,2] —> a[0,0,3] —> a[0,1,0] —> a[0,1,1] —> a[0,1,2] —> a[0,1,3] —>
a[0,2,0] —> a[0,2,1] —> a[0,2,2] —> a[0,2,3] —> a[1,0,0] —> a[1,0,1] —> a[1,0,2] —> a[1,0,3] —>
a[1,1,0] —> a[1,1,1] —> a[1,1,2] —> a[1,1,3] —> a[1,2,0] —> a[1,2,1] —> a[1,2,2] —> a[1,2,3]
不同维度的数组举例详见图 4.x 所示。
一维数组 BYTE 数据类型: 三维数组:
示例: 示例:
ARRAY [1..4] OF BYTE ARRAY [1..2,1..3,1..2] OF BYTE
Byte n Byte 1.1.1
Byte n Byte 1
Byte n+1 Byte 1.1.2
Byte n+1 Byte 2
Byte n+2 Byte 1.2.1
Byte n+2 Byte 3
Byte n+3 Byte 1.2.2
Byte n+3 Byte 4
. Byte 1.3.1
.
一维数组 WORD 数据类型: Byte 1.3.2
.
示例: . Byte 2.1.1
ARRAY [1..2] OF WORD
Byte 2.1.2
Byte n Word1
Byte 2.2.1
Byte n+1
Byte 2.2.2
Byte n+2 Word2
Byte 2.3.1
Byte n+3
Byte 2.3.2

图 4.x 数组变量的存储结构
7) 数组校验函数
在 CoDeSys 中,为了保证程序运行时能够正确的访问数组中的元素,需压迫使用 CheckBounds
函数,可以通过添加
每当向数组类型变量赋值时,该函数就会自动运行。写程序时用户唯一要做的就是添加“用于
隐含检查的 POU”,接下来的一切交给系统去执行即可。
通过如下的例子对该函数进行讲解。
若工程中没有上面所述的 CheckBounds 函数,在下面的例子中,A[B]应该为 A[10],从而超出
了数组 A 的最大上界值,程序编译出错。
但因为工程中定义了上面的 CheckBounds 函数,所以执行下面的程序时,A[B]应该为 A[7]来
使用,将布尔量 True 赋值给 A[7],编译时不出错。

图 4.x CheckBounds 函数示例

2. 结构
1) 结构的概念
迄今为止,已经介绍了基本类型的变量(如整型、实数、字符串等),也介绍了数组,数组中
的个元素属于同一个类型的。
但光有这些数据类型是不够的,有时需要将不同类型的数据组合成一个有机的整体,以便于引
用。结构(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构体。
例如,一台电机通常都有其对应的信息,如产品型号(Product_ID)、生产厂家(Vendor)、
额定电压(Nominal Voltage)、额定电流(Nominal Current)、极对数(Poles),是否带刹车
(Brake)等信息。这些信息都和这台电机相关联,见表 4-x 所示。可以看出,如果将这些信息分别
以独立的变量进行声明,很难反应出它们和电机的内在联系。如果有一种数据类型可以将它们组合
起来的话,那就可以解决这个问题,在 CoDeSys 中结构体就能起到这样的功能。

表 4-x 电机结构参数
Product_ID Vendor Nominal Voltage Nominal Current Poles Brake
11000 FESTO 380 5.2 4 YES
结构体和其他类型基础数据类型一样,例如 int 类型,char 类型,只不过结构体可以做成你想
要的数据类型。以方便以后的使用。在实际项目中,结构体是大量存在的。工程人员常使用结构体
来封装一些属性来组成新的类型。所以在项目中通过对结构体内部变量的操作将大量的数据存储在
内存中,以完成对数据的存储和操作。结构体其最主要的作用就是封装。封装的好处就是可以再次
利用。
结构体声明的语法如下:
TYPE <结构名>:
STRUCT
<变量的声明 1>
.
.
<变量声明 n>
END_STRUCT
END_TYPE
<结构名>是一种可以在整个工程中被识别的数据类型,可以像标准数据类型一样使用。
结构体可以实现嵌套,如图 4.x 所示,其中子结构也是一个结构体。

结构体

子结构体
基本数据类型
复杂数据类型

图 4.x 数据结构体
图 4.x 说明了结构体的复杂结构,其中包含了多个基本数据类型,并包含其他子结构体,数据
的结构复杂程度依次从右至左递增。
2) 结构体添加
选中“Application”右键-->“添加对象”-->“DUT”。
图 4.x 添加 DUT
打开 DUT 添加窗口后类型选择“结构(S)”点击“打开”,如图 4.x 的 a)所示。确定后,系
统则会自动进入 DUT 编辑器。

a) b)

图 4.X 结构体的创建
a )DUT 创建窗口 b )DUT 编辑器
针对图 4.x 的要求,在数据单元类型中新建一个名为 Motor 的结构体,具体内容如下,如图 4.x
中的 b)所示。
TYPE Motor :
STRUCT
Product_ID:DWORD;
Vendor:STRING(20);
Nominal_Voltage:REAL;
Nominal_Current:REAL;
Poles:INT;
Brake:BOOL;
END_STRUCT
END_TYPE
建立完结构体后,只需在程序中新建一个变量,类型为刚刚建立的<结构名>,即 Motor。在程
序中键入“变量名.”后,系统则会自动弹出结构体内具体对应的信息,见图 4.x,通过点击鼠标选
择,再配合赋值语句即可实现对结构体的读写操作。

图 4.x 结构体应用举例
【例 4.X】根据图 4.x 的内容给结构体赋值。
TYPE Motor :
STRUCT
Product_ID:DWORD;
Vendor:STRING(20);
Nominal_Voltage:REAL;
Nominal_Current:REAL;
Poles:INT;
Brake:BOOL;
END_STRUCT
END_TYPE

VAR
Motor_1:Motor;
END_VAR

Motor_1.Product_ID:=11000;
Motor_1.Vendor:='FESTO';
Motor_1.Nominal_Voltage:=380;
Motor_1.Nominal_Current:=5.2;
Motor_1.Poles:=4;
Motor_1.Brake:=TRUE;
运行结果如图 4.x 所示。
图 4.x 运行结果
3) 结构变量的存储结构
结构变量从字边界开始,也就是说,起始地址为偶数字节地址。随后,每个结构元素以其声明
时的顺序依次存储到内存中。
数据类型为 BOOL,BYTE 的结构元素从偶数字节开始存储,其他数据类型的数组元素从字地
址开始存储。
3. 结构体数组
一个结构体变量可以存放一组数据(如一个设备的安装位置、湿度、温度等数据)。如果有
10 个设备的数据需要参加运算,显然应该用数组,这就是结构体数组。结构体数组与以前介绍过
的数值型数组不同支持在于每个数组元素都是一个结构体类型的数据,它们都分别包括各个成员
(分量)项。
1) 定义结构体数组
和定义结构体变量的方法相似,只需要说明其为数组即可,例如:
TYPE Machine :
STRUCT
sDeviceName:STRING;
nInstallLocation:INT;
bWorkStatus:BOOL;
rHumidity:REAL;
rTemperature:REAL;
END_STRUCT
END_TYPE

VAR
arrMachineStatus : array [0..2]of Machine;
END_VAR
以上定义了一个数组 arrMachineStatus,数组中有 3 个元素,均为 Machine 类型数据,如图 4.x
所示。

图 4.x 结构体数组举例
4. 枚举
1) 枚举的概念
如果一种变量有几种可能的值,可以定义为枚举类型。所谓“枚举”是将变量的值一一列举出来,
变量的值只能在列举出来的值的范围内。例如,必须定义一个变量,该变量的值表示一周中的一
天。 该变量只能存储七个有意义的值。 若要定义这些值,可以使用枚举类型。如一周内星期可能
取值的集合为:
{ Sun,Mon,Tue,Wed,Thu,Fri,Sat}
该集合可定义为描述星期的枚举类型,该枚举类型共有七个元素,因而用枚举类型定义的枚举
变量只能取集合中的某一元素值。
枚举类型声明的语法如下:
TYPE <标识符>:
(<Enum_0> ,
<Enum_1>,
...,
<Enum_n>) |<基本数据类型>;
END_TYPE
<基本数据类型>为可选项,如果不填写数据类型,系统默认为 INT 类型。
Workday 和 Week-end 被定义为枚举变量,它们的值只能是 sun 到 sat 之一。例如:
Workday:=mon;
Week-end:=sun;
是正确的。
这些是用户定义的标识符。这些标识符并不自动地代表什么含义。例如,不能因为写成 sun,
就自动代表“星期天”。其实不写 sun 而写成 Sunday 也可以。用什么标识符代表什么含义,完全
由程序员决定,并在程序中做相应处理。
说明:
a) 枚举类型的基本数据类型-默认是 INT 类型,也由用户明确指定,例如:
TYPE BigEnum : (yellow, blue, green:=16#8000) DINT;
END_TYPE
b) 枚举值可以直接用来做判断条件,例如:
IF nWeekday>5 THEN
nWeekday:=0;
c) 在 CoDeSys 中,整数可以直接赋给一个枚举变量,例如:
nWeekday:=10;
d) 同样的 POU 内,同样的枚举值不得用两次,在枚举或在所有枚举内,例如:
TRAFFIC_SIGNAL: (red, yellow, green);
COLOR: (blue, white, red);
Error: red may not be used for both TRAFFIC_SIGNAL and COLOR..

【例 4.X】使用枚举类型,将一周中的 7 天按照 Sun,Mon,Tue,Wed,Thu,Fri,Sat 的形式显出,并


每个程序周期进行一次变化。
TYPE Weekday :
(Sun:=0,
Mon:=1,
Tue:=2,
Wed:=3,
Thu:=4,
Fri:=5,
Sat:=6);
END_TYPE

VAR
nWeekday:Weekday;
END_VAR

IF nWeekday>5 then
nWeekday:=0;
ELSE
nWeekday:=nWeekday+1;
END_IF
输出结果如图 4.x 所示,该例程可在\Sample\第四章\ENUM_Week\ 打开。

图 4.x 枚举类型变量应用举例

5. 子范围
子范围是一种用户自定义类型,该类型定义了某种数据类型的取值范围。其值的范围是基本数
据类型的一个子集。如取值从 1 到 10 或从 100 到 1000 等。
声明子范围类型时,先确定基本类型(整型),再提供该类型的两个常数。子范围声明的语法
如下:
<标识符> : <数据类型> (<下限>..<上限>);
<数据类型>以下数据类型中的一个:SINT、USINT、INT、UINT、DINT、UDINT、BYTE、
WORD、DWORD (LINT、ULINT、LWORD)。
<下限>定义了该数据类型的下限,下限本身也属于这个范围。
<上限>定义了该数据类型的上限,上限本身也属于这个范围。
子范围的实际使用例如:
VAR
nPosition:INT(0..90);
END_VAR

nPosition:=99;
如果使用上式进行编译,编译会出现错误“C0032:不能将类型’99’转换为类型’INT(0..90)’”
99 已经超出所定义的子范围的范围。。
1) 范围边界校验函数
但是如果通过一个中间变量在进行赋值将 99 间接的赋值给 nPosition 则编译系统不会报错,但
99 其实已超过了 nPosition 原始定义的边界,故 CoDeSys 为了对数据的边界进行绝对的保障,防止
超限,定义了范围边界校验函数(Range boundary Checks)对变量的边界进行校验。
使 用 此 函 数 需 要 在 项 目 中 “ 添 加 对 象 ” , 选 择 “ 用 于 隐 含 检 查 的 POU ” , 将
“CheckRangeSigned”和“CheckRangeUnsigned”的勾都打上,然后重新编译程序,再登入即可,
在此过程中,对新添加的函数不需要进行任何修改。通过下面的例子对该函数进行说明。
VAR
nPosition:INT(0..90);
nPosition1:INT;
END_VAR

nPosition1:=99;
nPosition:=nPosition1;

程序运行后,结果如下图所示。
从上图可以看出,nPosition 的值最后为 90,确保了数据在 0~90 的范围内。
该数据类型被广泛的应用,如在针对模拟量输出模块时,需要对输出电压/电流进行限制,则
可以直接采用此数据类型进行声明,可以对数据进行软件有效的钳位。
【例 4.X】通过定义子范围类型变量防止程序出现死循环。
VAR
nCounter : UINT (0..10000);
END_VAR

FOR nCounter:=0 TO 10000 DO


...
END_FOR
由于校验函数确保了变量 nCounter 的值绝对不会超过 10000,故程序永远无法跳出这个 FOR
循环。
该功能类似于 LIMIT 函数。

4.3 变量命名建议
4.3.1 匈牙利命名法

匈牙利命名法是一种编程时的命名规范。它是由 1972 年至 1981 年在施乐帕洛阿尔托研究中心


工作的程序员查尔斯·西蒙尼发明。此人后来成了微软的总设计师。其基本原则是:变量名=属性
+类型+对象描述,其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。
命名要基于容易记忆,容易理解的原则。保证名字的连贯性是非常重要的。
CoDeSys 中的所有标准库也采用匈牙利命名法则。在声明变量、用户自定义数据类型和创建
POU(函数、功能块、程序)时定义标识符。为了使标识符的名称尽量不与其他名称重复,除了必
须遵守的事项之外,您可能还需要参考以下一些建议。
1. 变量命名
给应用程序和库中的变量命名时应当尽可能地遵循匈牙利命名法。每一个变量的基本名字中应
该包含一个有意义的简短描述。
基本名字中每一个单词的首字母应当大写,其它字母则为小写,例如:FileSize。
再根据变量的数据类型,在基本名字之前加上小写字母前缀。请看表 4.x 中列出的一些特定数
据类型的推荐前缀和其它相关信息。
 每一个变量的基本名字中应该包含一个有意义的简短描述;
 基本名字中每一个单词的首字母应当大写,其它字母则为小写;
 依据变量的数据类型,在基本名字之前加上小写字母前缀;

表 4-x 匈牙利标准类型变量命名法
数据类型 前缀 数据类型 前缀
BOOL b ULINT uli
BYTE by REAL r
WORD w LREAL lr
DWORD dw STRING s
LWORD lw TIME tim
SINT si TIME_OF_DAY tod
USINT usi DATE_AND_TIME dt
INT i DATE date
UINT ui ENUM e
DINT di POINTER p
UDINT udi ARRAY a
LINT li STRUCT stru
在嵌套声明中,按照声明顺序连接前缀,例如:
pabyTelegramData: POINTER TO ARRAY [0..7] OF BYTE;
根据表 4-x 中可以得知,
p:表示指针。
a:表示数组。
by:表示 BYTE 配型。
TelegramData:表示变量名。
2. 程序、功能块和函数的命名
在 CoDeSys 中除了有标准变量,还有程序、功能块、函数及全局变量变量,数据结构等,他
们的命名标准也有供参考的法则。
每种数据的命名(如程序组织单元,数据结构,全局变量列表等)总以它相对应的前缀开始,
如程序 Program 用“PRG_”开始,功能块 Function Block 则以“FB_”前缀开始,函数 Function 则
以 “FUN_”或“FC_”,“FUNC_” 前缀开始定义,全局变量列表则以“GlobVar”前缀进行定
义,不同的功能逻辑部分用“_”来进行分割,,具体格式可参考表 4.x 所示。

表 4-x 程序、功能块及函数的命名法则
前缀 举例
Program PRG_ PRG_ManualControl,
Function Block FB_
Function FC_,FUN_或 FUNC_ FB_VerifyComEdge,
List of Global Variables GlobVar GlobVar_IOMapping, GlobVar_Remote

4.4 变量的类型和初始化
CoDeSys 根据 IEC 61131-3 标准对变量定义了属性。通过设置变量属性将他们的有关性能赋予
变量。变量可根据他的应用范围进行分类,如表 4-X,此外变量类型之外,CoDeSys 还提供了变量
的附加属性,如表 4-X。

4.4.1 变量的类型

CoDeSys V3.x 所支持的变量类型如下:

表 4-X 变量的类型
变量类型关键字 变量属性 外部读写 内部读写
VAR 局部变量 --- R/W
VAR_INPUT 输入变量,由外部提供。 R/W R
VAR_OUTPUT 输出变量,有内部变量提供给外部。 W R/W
VAR_IN_OUT 输入-输出变量。 R/W R/W
VAR_GLOBAL 全局变量,能在所有配置、资源内使用。 R/W R/W
VAR_TEMP 临时变量,程序和功能块内部存储使用的变量。 --- R
VAR_STAT 静态变量。
VAR_EXTERNAL 外部变量,能在程序内部修改,但需由全局变量提供 R/W R/W
VAR、VAR_INPUT、VAR_OUTPUT 和 VAR_IN_OUT 是在程序组织单元(POU)中被应用的
最多的几种变量类型。
VAR_GLOBAL 全局变量在实际的工程项目中也需要被大量的使用。
1) 变量的属性
在 CoDeSys V3.x 中,支持的变量属性如 4.x 所示。

表 4-x 变量的属性一览
变量附加属性关键字 变量附加属性
RETAIN 保持型变量,用于掉电保持。
PERSISTENT 保持型变量
VAR RETAIN PERSISTENT 两者功能一样,皆为保持性变量,用于掉电保持
VAR PERSISTENT RETAIN
CONSTANT 常量
 RETAIN
以关键字 RETAIN 声明类型变量。RETAIN 型变量在控制器正常关闭、打开(或收到在线命令
“热复位”),甚至意外关闭之后这类变量仍然能保持原来的值。随着程序重新开始运行,存储的
值能继续发挥作用。
RETAIN 类型变量声明格式如下:
VAR RETAIN
<标识符>:<数据类型>;
END_VAR
但 RETAIN 变量在“初始值位”、“冷复位”和程序下载之后将会重新初始化
内存存储位置: RETAIN 型变量仅仅被存储在一个单独的内存区中。
在实际的工程应用中,如生产线上的计件器便是一个典型的例子:电源被切断之后,它仍然可
以在再次启动时继续计数。而其它所有变量此时都将被重新初始化,变为指定初始值或标准初始化
的值。
 PERSISTENT
目前只有少数 PLC 还保留独立的内存区域用于存放 PERSISTENT 类型数据,在 CoDeSys V3.x
中 , 取 消 了 其 原 掉 电 保 持 的 功 能 , 取 而 代 之 的 是 通 过 VAR RETAIN PERSISTENT 或 VAR
PERSISTENT RETAIN 来实现,两者从功能上完全一样。
PERSISTENT 类型变量声明格式如下:
VAR GLOBAL PERSISTENT RETAIN
<标识符>:<数据类型>;
END_VAR
内存存储位置:与 RETAIN 变量一样,RETAIN PERSISTENT 和 PERSISTENT RETAIN 变量
也存储在一个独立的内存区中。
 CONSTANT
常量,在程序运行过程中,只能对其读取数据而不能进行修改的量称之为常量,关键字为
CONSTANT。可以将常量声明为局部常量,也可以为全局常量。
CONSTANT 常量声明格式如下。
VAR CONSTANT
<标识符>:<数据类型> := <初始化值>;
END_VAR
在实际应用中,通常可以将一些重要参数或系数设为常量,这样可以有效的避免其他变量对其
修改最终影响系统整体稳定性及安全性。举例如下。
VAR CONSTANT
pi:REAL:= 3.1415926;
END_VAR
程序一旦开始运行,通过 CONSTANT 声明的变量在程序运行过程中,是不允许被修改的,如
强制修改系统会出现如图 4.x 所示的系统错误。

图 4.x 常量强制写入数据错误

4.4.2 变量的初始化

在程序中,有时需要对一些变量预先赋予初值,CoDeSys 允许在定义变量时对变量进行赋初值
处理。在赋值运算符“:=”的左边是变量及变量类型,该变量接受右边地址或表达式的值如:
VAR
bBoolValue:BOOL:=TRUE; (*定义 bBoolValue 为 BOOL 变量,初值为 TRUE*)
rRealValue:REAL:=3.1415926; (*定义 rRealValue 为 REAL 变量,初值为
3.1415926*)
nIntValue:INT:= 6; (*定义 nIntValue 为 INT 变量,初值为 6*)
strValue:STRING:='Hello CoDeSys'; (*定义 strValue 为 STRING 变量,初值为 Hello
CoDeSys *)
END_VAR
此外,也可以对同一类型的多个变量进行同时赋初值,例如:
bBoolValue1,bBoolValue2,bBoolValue3,bBoolValue4:BOOL:=TRUE;
其运行结果为当程序运行后,bBoolValue1,bBoolValue2,bBoolValue3,bBoolValue4 这四个变量
的初值都为 TRUE。
数组,结构体等赋初值相对复杂,数组的赋初值如下。
VAR
arr1 : ARRAY [1..5] OF INT := [1,2,3,4,5];
arr2 : ARRAY [1..2,3..4] OF INT := [1,3(7)]; (*初值为 1,7,7,7 的缩写形式 *)
arr3 : ARRAY [1..2,2..3,3..4] OF INT := [2(0),4(4),2,3]; (*初值为 0,0,4,4,4,4,2,3 的缩
写形式 *)
END_VAR
结构体可以只对其中部分的成员进行初始化,针对例 4.x 中的结构体在程序中进行赋值,声明
如下:
VAR
Motor_1:Motor:=(Vendor:='FESTO',Brake:=TRUE); (*Vendor 的初值为 FESTO,Brake 的初
值为 TRUE *)
END_VAR
用户自定义的初值只在控制器刚启动后的第一个任务周期对该变量会写入一次,在程序中如果
直接在变量声明区修改了初始值, “登入到”PLC 后选择 “在线修改”并不会对该变量的数据有
任何改变,只有在 PLC 复位后重新运行程序才有用。
4.5 变量声明编辑器中的 Pragma 指令
通过 Pragma 命令可以改变一个或几个变量的字段,而这些字段影响着编译和预编译过程。这
就意味着 Pragma 命令可以影响代码的生成。
例如,它可以决定是否对某个变量进行初始化和监控、是否将其加入参数列表或符号表设置,
也可以决定是否令其在库管理器中可见。用户可以令系统在编译过程中输出信息,也可以选择条件
pragmas。这些条件 pragma 定义了如何根据各种特定条件来处理变量。用户还可以把这些 pragma
作为“定义”输入到特定对象的编译属性中。

4.5.1 字段 Pragma

把字段 Pragmas 指定给签名之后,可以影响编译和预编译(如代码的生成)过程。


其语法格式为{Attribute ‘<COMMAND>‘ } 。详细的命令表如表 4-x 所示。

表 4-x 字段 Pragma 命令表


命令 功能 语法
Displaymode 修改显示模式 {attribute 'displaymode':= 'hex'| 'dex'| 'bin'}
ExpandFully 展开所有变量 {attribute 'ExpandFully'}
Global_init_slot {attribute 'global_init_slot':= <值>}
Hide 隐藏变量列表 {attribute 'hide'}
Hide_all_locals 隐藏所有变量 {attribute 'hide_all_locals'}
Initialize_on_call 每次被调用时恢复初始值 {attribute 'initialize_on_call'}
Init_on_onlchange 每次修改时恢复初始值 {attribute 'init_on_onlchange'}
Instance-path 初始化路径 {attribute 'instance-path'}
Linkalways 装在符号配置并下载 {attribute'linkalways'}
Monitoring 加载监视变量 {attribute 'monitoring':='variable'}
No_check 禁止程序中的校验函数 {attribute 'no_check'}
No_copy 禁止复制实例化对象 {attribute 'no_copy'}
No-Exit' 退出(需配合退出方法) {attribute 'symbol’ := 'no-exit'}
Noinit 隐含初始化 {attribute 'noinit'}
No_virtual_actions 禁止虚拟动作,防止重载 { attribute 'no_virtual_actions’}
Obsolete 用户自定义警告 {attribute 'obsolete' := 'user defined text'}
Pack_mode' 定义数据结构的封装模式 {attribute 'pack_mode':= '<Value>'}
Parameterstringof' 访问变量实例化名 {attribute 'parameterstringof? := ' <variable>'}
Qualified_only 只有加全局变量前缀才能被 {attribute 'qualified_only'}
调用
Symbol 修改符号配置的读写属性 {attribute 'symbol':= 'none'| 'read'| 'write'|
'readwrite'}

【例 4.X】使用 Displaymode 指令,将变量 a 使用 10 进制的方式显示,变量 b 用 16 进制显示。


VAR
{attribute 'displaymode':='hex'}
a : INT:=44 ;
{attribute 'displaymode':='dex'}
b : INT:=44;
END_VAR
其最终的运行结果如图 4.x 所示。

图 4.x 常量强制写入数据错误
如图 4.x,同样是 44,a 变量直接用 16 进制的方式显示为 16#2C,而变量 b 继续为默认的 10 进
制的显示方式。
通过在监视表中单击鼠标右键也能修改显示模式,但是两者的区别是 Displaymode 指令能够将
每个独立的变量进行 16/10/2 进制显示,而在监视表中修改显示模式则是批量的修改,一经修改,
整个项目的所有变量都会相应修改。

图 4.x 监视表中设置显示模式
【例 4.X】隐含初始化指令。
VAR
A : STRING:='Hello';
B : INT:=9;
{attribute 'noinit'}
C : STRING:='Hello';
{attribute 'noinit'}
D : INT:=9;
END_VAR
当程序运行后,虽然在程序声明中已经赋有初值,但因为有了隐含初始化指令,故最终忽略赋
初值指令,最终效果如图 4.x 所示。

图 4.x 隐含初始化指令
第5章 编程语言
本章主要知识点
 掌握五种语言的编程结构

很多学者在学习 CoDeSys 的过程中常会问一个问题,哪种编程语言最好?


其实,没有哪种编程语言是绝对的好或不好,不同的工程应用具有不同的最佳编程方式,每种
编程语言都具有其不同的特点,可根据实际工程应用的需求选用合适的编程语言,下面简单介绍下
CoDeSys 的 6 种不同语言的特点。
1) 梯形图(LD):与电气操作原理图相对应,其优点它的直观性,电气技术人员易于掌握和
学习。缺点是在应对复杂的控制系统编程时往往程序描述性不够清晰。梯形图在国内的工业自动化
领域中是使用最多的一种 PLC 编程语言。
2) 功能块图(FBD):以功能块为设计单位,能从控制功能入手,优点是使控制方案的分析
和理解变得容易,功能块具有直观性强、容易掌握的特点,有较好的操作性。在应对复杂控制系统
时仍可用图形方式清晰描述。缺点是每种功能块要占用程序存储空间,并延长程序执行周期。
3) 指令表(IL):优点是易于记忆及掌握,与梯形图(LD)有对应关系,便于相互转换和对
程序的检查,且编程及调试时不受屏幕大小的限制,输入元素不受限制。缺点和梯形图一样,对复
杂系统的程序描述不够清晰。
4) 结构化文本(ST):优点是可实现复杂运算控制,对编程人员的技能要求高,其缺点是编
译时需要将代码转换为机器语言,会导致编译时间长、执行速度慢,且直观性和易操作性差。
5) 顺序流程功能图(SFC):已完成的功能为主线,优点是操作过程条理清楚,便于对程序操
作过程的理解和思路;对大型程序可分工设计,采用较灵活的程序结构,节省程序设计时间和调试
时间,由于只对活动步进行扫描,因此,可缩短程序执行时间。
6) 连续功能图(CFC):实际上是功能块图(FBD)的另一种形式。在整个程序中可自定义
运算块的计算顺序,易于实现大规模、数量庞大但又不易细分功能的流程运算。在连续控制行业中,
得到大量使用。
编程语言的多样性是 CoDeSys 一大优点。所以在实际的工程项目中,从优化程序和编程便利
性的角度建议大家,涉及到算法部分请选择 ST 语言,编写的程序往往简洁而高效;涉及到流程控
制部分,请选择 SFC 语言,编写的程序会条理清晰,逻辑关系不会混乱;涉及到逻辑控制部分,
请选择 LD 语言,编写的联锁,互锁等逻辑简单易懂;涉及到功能块部分,请选择 CFC 或者 FBD,
编写的程序会形成一个网络清晰的网状电路图,易于读懂。当然,在实际的编程时,用户也可以根
据自己的使用习惯来选择编程语言,虽然实现的方法不同,但是都能得到同一个结果。
5.1 指令表(IL)
IEC 61131-3 的指令表 IL(Instruction List)语言是一种低级语言,与汇编语言很相似,是在借
鉴、吸收世界范围的 PLC 厂商的指令表语言的基础上形成的一种标准语言,可以用来描述功能,
功能块和程序的行为,还可以在顺序功能流程图中描动作和转变的行为。
指令表语言能用于调用,如有条件和无条件地调用功能块和功能,还能执行赋值以及在区段内
执行有条件或无条件的转移。指令表语言不但简单易学,而且非常容易实现,可不通过编译和连编
就可以下载到 PLC。CoDeSys 的其它语言如功能块图、结构化文本等都可以转换为指令表语言。

5.1.1 指令表语言结构

指令表语言是由一系列指令组成的语言。每条指令在新一行开始,指令由操作符和紧随其后的
操作数组成,操作数是指在 IEC 61131-3 的“公共元素”中定义的变量和常量。有些操作符可带若
干个操作数,这时各个操作数用逗号隔开。指令前可加标号,后面跟冒号,在操作数之后可加注释。
指令表语言是一种面向行的语言,类似于程言的程序类编语汇编。一条指令,是 PLC 可执行
的一项命令,它严格要求有一个行来描述。也允许空白行形式的空指令。
指令表编程语言的特点是:
 采用助记符来表示操作功能,具有容易记忆,便于掌握。
 与梯形图有对应关系。其特点与梯形图语言基本一致。
指令表 IL 编辑器的编程界面如图 5.x 所示。

图 5.x 指令表 IL 编辑器中的编程


5.1.2 连接元素

IL/FBD/LD 有共同的连接元素,只是在表达方式上略有不同,为节省篇幅,故在此作统一的介
绍。
指令表包含一系列指令。每个指令在新一行开始,包含操作符,根据操作的类型,一个或多个
操作域用逗号分开。操作符可以用修饰符扩展。
在一行中的指令前,可以有身份标识符(标签),后跟一个冒号(:),如下例中所示的
“ml:”。标号可以成为跳转的目标,如下例中所示的“JMPC next”。注释必须放在最后作为元素,
指令之间可以插入空行。
1. 修饰符
修饰符有三种,C、N 和 N 如表 5-x 所示,修饰符不能独立构成,需要配合操作符才能构成一
句完整的语句。

表 5-x 修饰符表格
修饰符 使用 功能
C 结合 JMP,CAL,RET 使用 本指令仅当前面的表达式结果为真时执行
N 结合 JMPC,CALC,RETC 使用 本指令仅当前面的表达式结果为假时执行
N 其他 操作数(而非累加器中的数)取反
2. 操作符
在引入操作符的概念之前,需要介绍一个概念,即累加器,他在指令表编程语言中尤为重要。
指令表编程语言提供了一个存储当前结果的累加器,与传统的可编程控制器使用的累加器不同,
这种标准累加器存储位数是可变的,即标准指令表编程语言提供了一种存储位数可变的虚拟累加器,
其存储位数取决于正在处理的操作数和数据类型。同样,虚拟累加器的数据类型也可以发生变化,
以适应最新运算结果的操作数的数据类型。
指令执行过程中,数据存储采用的方法是:
运算结果:=当前运算结果 操作 操作数
因此,在操作符规定的操作下,当前运算结果与操作数进行由操作符规定的操作运算。运算结
果作为新的运算将结果存放回当前运算结果的累加器。
如表 5-x 显示了可以跟修饰符配合使用的操作符指令。

表 5-x 操作符及修饰符含义
操作符 修饰符 含义 举例
LD N 将操作数(取反)载入累加器 LD iVar
ST N 将累加器中的数(取反)存入操作数变量中 ST iErg
S 当累加器中的数为真,将操作数(布尔型)设为真 S bVar1
R 当累加器中的数为假,将操作数(布尔型)设为真 R bVar1
AND N,( 累加器中的数和(取反的)操作数逐位进行与运算 AND bVar2
OR N,( 累加器中的数和(取反的)操作数逐位进行或运算 OR xVar
XOR N,( 累加器中的数和(取反的)操作数逐位进行异或运算 XOR
N,(bVar1,bVar2)
NOT 累加器中的数逐位取反
ADD ( 将累加器中的数和操作数相加,其结果复制到累加器中 ADD
(iVar1,iVar2)
SUB ( 累加器中的数减去操作数,其结果复制到累加器中 SUB iVar2
MUL ( 累加器中的数和操作数相乘,其结果复制到累加器中 MUL iVar2
DIV ( 累加器中的数除以操作数,其结果复制到累加器中 DIV 44
GT ( 检查累加器中的数是否大于操作数,其结果(布尔型)复制 GT 23
到累加器中 ;>
GE ( 检查累加器中的数是否大于或等于操作数,其结果(布尔 GE iVar2
型)复制到累加器中 >=
EQ ( 检查累加器中的数是否等于操作数,其结果(布尔型)复制 EQ iVar2
到累加器中; =
NE ( 检查累加器中的数是否不等于操作数,其结果(布尔型)复 NE iVar1
制到累加器中; <>
LE ( 检查累加器中的数是否小于或等于操作数,其结果(布尔 LE 5
型)复制到累加器中; <=
LT ( 检查累加器中的数是否小于操作数,其结果(布尔型)复制 LT cVar1
到累加器中
无条件(有条件)跳转到标签; <
JMP CN 无条件(有条件)跳转到标签 JMPN next
CAL CN (有条件)调用一个程序或功能块(当累加器中的数为正 CAL prog1
时)
RET 从当前 POU 中返回,跳回到调用的 POU 中 RET
RET C 有条件-仅当累加器中的数为真时,从当前 POU 中返回,跳 RETC
回到调用的 POU 中
RET CN 有条件-仅当累加器中的数为假时,从当前 POU 中返回,跳 RETCN
回到调用的 POU 中
) 评估延迟的操作数

注意:
累加器总是存储当前值,有后续操作时产生。
CAL 的操作数应是一个被调用的功能块实例名。
NOT 操作的结果是当前结果的位取反,修饰符 N 表示取反操作。
RET 操作符不需要操作数
修饰符 C 表示有关指令只有在当前运算的结果是布尔为 TRUE(或当操作符布尔值为 FALSE,并与“N”
修饰符结合时)才执行。
操作符可多于一个修正符,即可同时,也可以只用一个或不用。例如,JMP 操作符可以有 JMP、JMPC、
JMPN 三种格式。

左圆括号“(”表示操作符的运算被延缓直到遇到右圆括号“)”。因此,对传统 PLC 中的
程序块操作,主控操作等都可以采用该操作符实现。
【例 5.X】使用指令表实现电机的起保停控制。

例 5.x 中的程序用于对某设备进行起保停控制。程序中,标号为 START 的指令 PLC 第 1 行信


号(bStart),并将其结果存放至累加器中。第 2 行的指令用于将第 1 行指令的结果和 bHold 输出
保持信号进行或逻辑运算,运算结果仍然存放在累加器中。第 3 行指令用于将第 2 行运算结果和停
止信号 bStop 进行取反后的逻辑与运算,结果仍存放在累加器中。第 4 行指令用于将累加器中的结
果输出值 bDone 信号。
【例 5.X】
首先,装载 TRUE 至累加器,其次将“bVar1”的值取反和累加器的值进行与运算,如果结果
为 TRUE,则程序跳转至 m1,反之将“bVar2”取反加载至累加器并输出。
3. 函数及功能块的调用
1) 函数调用:
在操作符区输入函数名。(第一个) 输入参数作为 LD 的操作数。如果有更多的参数,下一个必
须是在同一行作为函数名输入的, 之后的参数可以添加到这一行并用逗号隔开, 或添加到下面的
行里。 函数返回值将被保存在累加器中,需要注意,根据 IEC 标准的规定,返回值只能有一个。
例如:函数 GeomAverage, 该函数调用三个输入参数。第一个参数是预操作数 X7,第二个参数
"25"在函数名后给出。 第三个由变量 tvar 给出, 或在同一行或下一行。分配返回值给变量 'Ave':
(在结构文本中相应的 ST 代码为:Ave := GeomAverage(X7, 25);)

2) 功能块及程序调用:
使用 CAL- 或 CALC 操作符 。在开括号前的操作域(第二栏)中输入功能块实例名或程序名。
在开括号后写入输入参数:
首栏:为参数名,操作符“:=”表示输入参数,“=>”表示输出参数。
第二栏:为实参,在最后参数的后面要以闭括号结尾。
例如:带有两个输入和两个输出参数的 POUToCAll 调用,相应的 ST 代码为:
POUToCall(Counter := MyCounter,
Decrement:=2,
bError=>Err,
wError=>ErrCode);
使用限定符编写的程序的例子:
LD TRUE (* 把 TRUE 加载到累加器中*)
ANDN BOOL1 (* 执行 AND 和 BOOL1 变量的取反后“与” *)
JMPC mark (* 当上面的结果为 TRUE 时, 跳转到标号“mark”处*)
LDN BOOL2 (* 保存 BOOL2 的反 *)
ST ERG (* 把 BOOL2 保存在 ERG*)
Lable:
LD BOOL2 (* 保存 BOOL2 的值 *)
ST ERG (*把 BOOL2 保存在 ERG*)
在 IL 中也可以在操作之后放一个圆括号。圆括号内的值被认为是一个操作数。例如:
LD 2
MUL 2
ADD 3
Erg
这里 Erg 的值为 7,但是如果加一个圆括号:
LD 2
MUL (2
ADD 3
)
ST Erg
Erg 的结果是 10,当到达")"时操作 MUL 才开始计算;此时操作数 5 计算 MUL。
图 5.x IL 语句表调用功能块

5.2 梯形图(LD)
5.2.1 简介

梯形图来源于美国,它基于图形表示的继电器逻辑,是 PLC 编程中被最广泛使用一种图形化


语言。梯形图程序的左、右两侧有两垂直的电力轨线,左侧的电力轨线名义上为功率流从左向右沿
着水平梯级通过各个触点、功能、功能块、线圈等提供能量,功率流的终点是右侧的电力轨线。每
一个触点代表了一个布尔变量的状态,每一个线圈代表了一个实际设备的状态,功能或功能块与
IEC 1131-3 中的标准库或用户创建的功能或功能块相对应。
梯形图是国内应用最为广泛的编程语言,它也是 IEC 1131-3 的三种图形化编程语言种一种,梯
形图是传统 PLC 使用得最多的图形编程语言,也被称为 PLC 的第一编程语言。根据梯形图中各触
点的状态和逻辑关系,求出与图中各线圈对应的编程元件的状态,称为梯形图的逻辑解算。
梯形图中的某些编程元件沿用了继电器这一名称,如线圈、触点等,但是它们不是真实的物理
继电器,而是一些存储单元(软继电器),每一软继电器与 PLC 存储器中映像寄存器的一个存储
单元相对应。该存储单元如果为 “TRUE”状态,则表示梯形图中对应软继电器的线圈“通电”,
其常开触点接通,常闭触点断开,称这种状态是该软继电器的“TRUE”或“ON”状态。如果该存
储单元为“FALSE”状态,对应软继电器的线圈和触点的状态与上述的相反,称该软继电器为
“FALSE”或“OFF”状态。使用中也常将这些“软继电器”称为编程元件。

5.2.2 梯形图程序执行顺序

梯形图的执行过程是按照从左至右,从上到下的顺序进行执行,如图 5.x 所示。


图 5.x 梯形图执行过程

1. 执行过程
1) 母线
梯形图采用网络结构,一个梯形图的网络以左母线为界。在分析梯形图的逻辑关系时,为了借
用继电器电路图的分析方法,可以想象左右两侧母线(左母线和右母线)之间有一个左正右负的直
流电源电压,母线之间有“能流”从左向右流动。右母线不显示。
2) 节
节是梯形图网络结构中最小单位,从输入条件开始,到一个线圈的有关逻辑的网络称为一个节。
在编辑器中,节垂直排列。在 CoDeSys 中,每个节通过左侧的一系列节号标示,包含输入指令和
输出指令,由逻辑式,算术表达式,程序,功能或功能块调用指令,跳转或返回指令所构成。
要插入一个节,可以使用命令插入节或从工具箱拖动它。一个节所包含的元素都可以通过在编
辑器中拖放来进行复制或移动。
梯形图执行时,从标号最小的节开始执行,从左到右确定各元素的状态,并确定其右侧连接元素的
状态,逐个向右执行,操作执行的结果由执行控制元素输出。然后进行下一节的执行过程。图 5.x
显示了梯形图的执行过程。
3) 能流
如图 5.x 所示,蓝色的加粗线即为能流,可以理解为一个假想的“概念电流”或“能流”
(PowerFlow)从左向右流动,这一方向与执行用户程序时的逻辑运算的顺序是一致的。能流只能从
左向右流动。利用能流这一概念,可以帮助我们更好地理解和分析梯形图。
4) 分支
当梯形图中有分支出现时,同样依据从上到下,从左至右的执行顺序分析各图形元素的状态,
对垂直连接元素根据上述有关规定确定其右侧连接元素的状态,从而逐个从左向右,从上向下执行
求值过程。在梯形图中,没有反馈路径的求值不是很明确。其所有外部输入值与这些有关的触点必
须在每个梯级以前被求值。
2. 执行控制
1) 跳转及返回
当满足跳转条件时,程序跳转到 Label 标号的节开始执行,直至该部分程序执行到 RETURN 时,
返回原来的节并继续执行。其结构图如图 5.x 所示。
Label1 Label1

RETURN

图 5.x 跳转指令执行过程
CoDeSys 中使用梯形图的跳转指令和返回指令如下,如例 5.X 所示。
【例 5.X】使用跳转指令执行程序的示例。

图 5.x 跳转指令执行
如图 5.x 所示,bInput1 被置为 True,故执行跳转语句,根据标签 Label1,程序跳转至第 3 节的
Label1,所以尽管当第 2 节的 bInput3 被置为 ON,bOutput2 始终不会被置为 True,因为程序直接跳
过了该语句。只有当 bInput1 为 False 时,且 bInput3 为 True 时,bOutput2 才会 True。

5.2.3 组成元素

IEC 1131-3 中的梯形图语言是对各 PLC 厂家的梯形图语言合理地吸收、借鉴,语言中的各图形


符号与各 PLC 厂家的基本一致,图 5.x 为梯形图编辑器视图。IEC 61131-3 的主要的图形符号包括:
 基本连接类:电源柜先、连接元素。
 触点类:常开触点、常闭触点、正转换读出触点、负转换触点。
 线圈类:一般线圈、取反线圈、置位(锁存)线圈、复位去锁线圈、保持线圈、置位保持
线圈、复位保持线圈、正转换读出线圈、负转换读出线圈。
 功能和功能块:包括标准的功能和功能块以及用户自己定义的功能块。
图 5.x 梯形图编辑器

1.电源轨线
梯形图电源轨线(Power Rail)的图形元素亦称为母线。其图形表示是位于梯形图左侧,也可
称其为左电源母线。如图 5.x 为左母线的图形表示。

图 5.X 左母线图形表示

2.连接元素
在梯形图中,各图形符号用连接元素连接,连接元素的图形符号有水平线和垂直线,它是构成
梯形图的最基本元素。图 5.x 是水平和垂直连接元素的图形表示。

a) b)

图 5.X 连接元素的图形表示
a )水平连接元素 b )垂直连接元素
3. 标签
标签是一个可选的标识符且当定义 跳转 时可以确定其地址。它可以包含任何字符。
4. 触点
触点是梯形图的图形元素。梯形图的触点(Contact)沿用了电气逻辑图的触点术语,用于表示
布尔型变量的状态变化。触点是向其右侧水平连接元素传递一个状态的梯形图元素。
触点可以分为常开触点(Normally Open Contact,NO)和常闭触点(Normally Closed Contact,
NC)。常开触点指在正常工况下,触点断开,其状态为 FALSE。常闭触点指在正常工况下,触点
闭合,其状态为 True。表 5-X 列出了 CoDeSys 梯形图中常用的触点图形符号及说明。

表 5-x 触点元素的图形符号与说明
类型 图形符号 说明
常开触点 如果该触点对应当前布尔变量值为 True 时,则该触点吸合,如触点左侧连接
元素的状态为 True 时,则状态 TRUE 被传递至该触点右侧,使右侧连接元素
的状态为 True。反之,当布尔变量值为 False 时,右侧连接元素状态为
FALSE。
常闭触点 如果该触点对应当前布尔变量值为 False 时,则该常闭触点处于吸合状态,
如触点左侧连接元素的状态为 True 时,则状态 True 被传递至该触点右侧,
使右侧连接元素的状态为 True。反之,当布尔变量值为 True 时,触点断
开,则右侧连接元素状态为 False。
插入右触点 可以进行多个触点的串联,在右侧插入触点。多个串联的触点都为吸合状态
时,最后一个触点才能传输 True。
插入并联下常 可以进行多个触点的并联,在触点下侧并联插入常开触点。两个并联触点中
开触点 只需一个触点为 True,则平行线传输 True。
插入并联下常 可以进行多个触点的并联,在触点下侧并联插入常闭触点。常闭触点默认为
闭触点 吸合状态,如该触点对应当前布尔变量值为 False 时,左侧连接元素的状态
为 True 时,则该并联触点右侧传输 True。
插入并联上常 可以进行多个触点的并联,在触点上侧并联插入常开触点。两个并联触点中
开触点 只需一个触点为 True,则平行线传输 True。
5. 线圈
线圈是梯形图的图形元素。梯形图中的线圈沿用了电气逻辑图的线圈术语,用于表示布尔型变
量的状态变化。
根据线圈的不同特性,可以分为瞬时线圈和锁存线圈,锁存线圈分为置位线圈和复位线圈。表
5-X 列出了 CoDeSys 梯形图中常用的线圈图形符号及说明。

表 5-x 线圈元素的图形符号与说明
类型 图形符号 说明
线圈 左侧连接元素的状态被传递到有关的布尔变量和右侧连接元素,如果线圈左
侧连接元素的状态为 TRUE,则线圈的布尔变量为 TRUE,反之线圈为 FALSE。
置为线圈 线圈中有一个 S。当左侧连接元素的状态为 TRUE 时,该线圈的布尔变量被置
位并且保持,直到由 Reset(复位)线圈的复位。
复位线圈 线圈中有一个 R。当左侧连接元素的状态为 TRUE 时,该线圈的布尔变量被复
位并且保持,直到由 Set(置位)线圈的置位。
6. 辅助
可以针对线圈及触点进行边沿检测、取反及置位/复位操作。

表 5-x 辅助图形符号与说明
类型 图形符号 说明
取反 将信号取反。
边沿检测 有 P,N 两种模式,可以通过单击该工具进行切换。P 为采集信号上升沿触
发,N 为采集信号下降沿触发。
置位/复位 有 R,S 两种模式,可以通过单击该工具进行切换。S 为置位,R 为复位。
例如,LD 中的网络右侧,可以有任何数量的线圈,它用括号“( )”表示。它们只能并联。一
个线圈将连接的值从左传输到右, 并将它复制到一个相应的布尔变量。 在进入线处, 可以出现值
ON (相当于布尔变量 TRUE),或值 OFF(相当于布变量 FALSE)。也可对接点和线圈求反(示
例中,接点 SWITCH1 和线圈 %QX3.0 是求反的)。若一个线圈是求反的(可通过线圈符号中的斜
线“(/)”识别),则它将求反值复制到相应的布尔变量内。若一个接点是求反的,则它仅当相应的
布尔值为 FALSE 时才接通。
7. 函数及功能块调用
与接点和线圈一起,你也可以插入功能块和程序。在网络中,它们必须有带布尔值的一个输入
和一个输出,并可在相同位置上像接点那样使用,也就是说在 LD 网络的左侧。

表 5-x 函数及功能块图形符号与说明
类型 图形符号 说明
插入运算快 插入函数或功能块,根据弹出的对话框通过鼠标选择想要使用的函数及功能
块。适用于对函数和功能块不太熟悉者使用。
插入空运算快 直接插入矩形块,在“???”处直接输入函数或功能块名,适用于对函数
及功能块较为熟悉的用户。
插入带 EN/ENO 只有当 EN 为 True 时,才执行函数或功能块并允许将状态传递至下游。适用
的运算快 于对函数和功能块不太熟悉者使用。
插入带 EN/ENO 插入带 EN/ENO 矩形块,在“???”处直接输入函数或功能块名,只有当
的空运算快 EN 为 True 时,才执行函数或功能块并允许将状态传递至下游。适用于对函
数及功能块较为熟悉的用户。
梯形图编程语言支持函数和功能块的调用。在函数和功能块调用时,需要注意如下事项:
1) 梯形图中,函数和功能块用一个矩形框表示。函数可以有多个输入参数但只能有一个返回
参数。功能块可以有多个输入参数和多个输出参数。
2) 输入列于矩形框的左侧,输出列于矩形框的右侧。
3) 函数和功能块的名称显示在框内的上中部,功能块需要将其实例化,实例名列于框外的上
中部。用功能块的实例名作为其在项目中的唯一标识。
4) 为了保证能流可以通过函数或功能块,每个被调用的函数或功能块至少应有一个输入和输
出参数。为了使被连接的功能块执行,至少应有一个布尔输入经水平梯级连接到垂直的左电源轨线。
5) 功能块调用时,可以直接将实际参数值填写在该内部形参变量名的功能块外部连接线处。
【例 5.X】功能块调用实参的设置。
图 5.x 调用 TON 延时 ON 功能块,TON_1 为功能块 TON 实例化后的实例名。功能块的输入形
参 PT 设置为 t#5s。输出形参 Q 及 ET,当不需要输出形参如示例中的 ET 时可以不连接变量。

图 5.x 调用功能块时实参的设置
可以看到,功能块 TON 的输出 Q 连接到了线圈 bWorking。表示当触点 bStartButton 为 True 且
bEmg_Stop 为 False 持续时间超过 5s 后,bWorking 为 True。当 bEmg_Stop 断开即为 True 时,
bWorking 为 False。
6) 如果没有 EN 和 ENO 的专用输入输出参数,则函数和功能块会被自动执行,且将状态传递
至下游。例 5.x 中,调用了带 EN 和 ENO 的功能块。
【例 5.X】调用带 EN 和 ENO 的功能块。
图 5.x 为带 EN 和 ENO 的功能块,布尔输入量 bEnable 用于计数器功能块 CTU_0 的启动,
bWorking 作为该功能块被启用的状态变量信号。

图 5.x 调用带 EN 和 ENO 的功能块


可以看出,当 bCounter 有上升沿触发信号时,则形参输出变量 CV 进行加 1 计算。
 当 EN 为 False 时,功能块本体定义的操作不被执行,ENO 的值也相应为 False。
 当 ENO 的值为 True,则说明该功能块的正在被执行。
5.2.4 赋值指令

通过适当的数据类型将数据分配给另一个变量。
在梯形图程序中,复制指令使用的相当广泛,在梯形图程序中,赋值指令使用函数“MOVE”
来实现,其指令符号及说明如表 5-x 所示。该指令适用于使用于所有数据类型。

表 5-x 函数及功能块图形符号与说明
类型 图形符号 说明
赋值指令 通过适当的数据类型将数据分配给另一个变量。

【例 5.X】赋值语句调用示例。
当输入条件 Input1 为 ON 满足时,将数值 999 赋值给变量 nValue。

图 5.x 赋值语句使用示例
其程序如图 5.x 所示,当 Input1 为 TRUE 时,触发 MOVE 赋值指令的“EN”使能信号,将数
值 999 赋值给变量 nValue。
5.3 功能块图(FBD)
5.3.1 简介

功能块图用来描述功能、功能块和程序的行为特征,还可以在顺序功能流程图中描述步、动作
和转变的行为特征。功能块图与电子线路图中的信号流图非常相似,在程序中,它可看作两个过程
元素之间的信息流。功能块图普遍地应用在过程控制领域。
功能块用矩形块来表示,每一功能块的左侧有不少于一个的输入端,在右侧有不少于一个的输
出端,功能块的类型名称通常写在块内,但功能块实例的名称通常写在块的上部,功能块的输入输
出名称写在块内的输入输出点的相应地方。

5.3.2 连接元素

FBD 在工具箱中可以添加很多元素,本节主要介绍其中的常规连接元素,如图 5.x 所示。

图 5.x 功能块图常规连接元素

1. 节
节是 FBD 和 LD 的基本实体, 在 FBD/LD 编辑器中,节是数值顺序安排的。每个节在左侧开
始有一个节编号,并有一个由逻辑或算数表达式,程序,函数,功能块调用,跳转或返回指令组成
的结构。
一个节同时还可以分配一个标题,注释和标号。
标题和注释区域的可用性可以通过“选项”-->“FBD, LD 和 IL 编辑器”对话框打开或关闭。
图 5.x 节标题注释和标号功能
如果选项激活,用户可通过鼠标单击节上边界下面,为标题打开一个编辑区域。输入注释则打
开标题区域下相应的编辑区域。注释可以是多行的。换行可以通过回车键实现,注释文本的输入是
通过[ Ctrl ] +[ Enter ] 终止的。
1) FBD 中的使用
编辑器中节注释是否显示及如何显示是在 FBD、LD and editor options' 对话框中定义的。
要添加一个 ⇘ 标号, 它可以被 ⇘ 跳转寻址,可以使用 ⇘ 'I 插入标号'"命令。如果一个标号被
定义,它会被显示在标题和注释之下的区域——如果这些不可用——直接在节上边界之下。
节也可以通过“切换节注释状态”设置为“注释状态”,设置后该节会像注释一样显示,不会
被执行。
通过在工具箱中插入“ ”来创建 “子节”,如图 5.x 中则使用了分支功能。

图 5.x 通过分支功能创建子节

2. 运算块
可以代表所有的 POU,包括功能块、函数及程序,如计时器,计数器等。可以在 FBD,LD 或
IL 的节中插入。运算块可以有任意的输入,任意输出。
1) FBD 中的使用
一个块可以放在 LD 节或 FBD 节的左侧(如一个触点)。可以通过工具箱进行插入,
在工具箱中可以选择插入标准运算块“ ” , 或 带 有 EN/ENO 的 功 能 块
“ ”。在编辑器中通过拖拽释放复制或移动。图 5.x 为标准的运算块与带有
EN/ENO 的运算块的图示比较。

a) b)

图 5.x FBD 中两种运算块比较


a ) 标准运算块 b ) 带有 EN/ENO 的功能块
在图 5.x 的 a)中只要前端条件满足,该功能块则会被直接执行,而 b)中,功能块只有当 EN
为 TRUE 时,该功能块才会被执行,否则,即使前端条件全部满足,该功能块不会被程序执行。如
果将 b)中的 EN 的输入信号置为常数“TRUE”,此时 a)和 b)的作用是完全一致的。
3. 分配
可以将分配功能理解为运算块分配输入/输出。
在工具箱中可以选择插入“ ”,将其拖拽至程序的编辑区中,此时编辑区中的预算块
对应的输入输出接口处会出现灰色的菱形小图案,读者可以直接将其拖拽至接口处,插入之后,文
本字符串 “??? ”可以用要分配的变量的名字替换,也可以使用 按钮调用“输入助手”,此时
已完成了对运算块输入/输出接口变量的分配。

图 5.x 分配视图

4. 跳转
主要实现程序内的跳转功能。
1) FBD 中的使用
在工具箱中插入“ ”,插入之后,自动输入的“???”,跳转目标的标号替换。

可以直接输入目标的标号或者通过点击“ ”浏览键使用输入助手进行选择,如
图 5.x 所示,系统会自动筛选可以使用的标号供用户选择。

图 5.x 跳转输入助手

5. 标号
在节区域下,每个 FBD,LD 或 IL 节都有一个文本输入区域来定义一个标号。标号是节的一个
选择性辨识符,可以在定义跳转时寻址到, 它可以包含任意顺序的字符。
1) FBD 中的使用
在节的空白处鼠标右击,选择“插入标号”,如图 5.x 中的 1)所示,然后会在 2)中弹出
Label:的标号,用户可以对其进行编辑。

图 5.x 在节中添加标号

6. 返回指令
RETURN 返回指令,如果 RETURN 的输入是 TRUE,则该 POU 的程序执行立即终止。在 FBD
或 LD 节中,它可以平行放置或放在上一元素的后面。
1) FBD 中的使用
用 RETURN 指令,在工具箱中插入“ ”,插入之后,自动输入的“???”,跳转目
标的标号替换。图 5.x 为在功能块图中的返回指令及在梯形图中的返回指令。

图 5.x RETURN 工具

5.3.3 组态

功能块图的组态结构与梯形图 LD 编程语言类似,再次不做重复介绍。
5.4 结构化文本(ST)
5.4.1 简介

结构化文本(ST)是一种高级的文本语言,可以用来描述功能,功能块和程序的行为,还可以
在顺序功能流程图中描述步、动作和转变的行为。
结构化文本编程语言是一种高级语言,类似于 Pascal,是一种特别为工业控制应用而开发的一
种语言,也是在 CoDeSys 中最常用的一种语言,对于熟悉计算机高级语言开发的人员来说,结构
化文本语言更是易学易用,它可以实现选择、迭代、跳转语句等功能。此外,结构化文本语言还易
读易理解,特别是当用有实际意义的标识符、批注来注释时,更是这样。在复杂控制系统中,结构
化文本可以大大减少其代码量,使复杂系统问题变得简单,缺点是调试不直观,编译速度相对较慢。
结构化文本的视图如图 5.x 所示。

图 5.x 结构化文本视图

5.4.2 结构化文本程序执行顺序

1. 程序执行顺序
使用结构化文本的程序执行顺序根据“行号”依次从上至下开始顺序执行,如图 5.x 所示。
图 5.x 结构化文本程序执行顺序

2. 表达式执行顺序
表达式中包括操作符和操作数,操作数按照操作符指定的规则进行运算,得到结果并返回。操
作数可以为变量、常量、寄存器地址、函数等。
【例 5.X】
a+b+c;
3.14*R*R;
ABS(-10)+var1;
如果在表达式中有若干个操作符,则操作符会按照约定的优先级顺序执行:先执行优先级高的
操作符运算,再顺序执行优先级低的操作符运算。如果在表达式中具有优先级相同的操作符,则这
些操作符按照书写顺序从左至右执行。操作符的优先级如表 5-x 所示:

表 5-x 操作符优先级
操作符 符号 优先级
小括号 () 最高
函数调用 Function name
(Parameter list)
求幂 EXPT
取反 NOT
乘法 *
除法 /
取模 MOD
加法 +
减法 -
比较 <,>,<=,>=
等于 =
不等于 <>
逻辑与 AND
逻辑异或 XOR
逻辑或 OR 最低

5.4.3 语句

结构化文本语句表如表 5-x 所示。

表 5-x 结构化文本语句表
指令类型 指令语句 举例
赋值语句 := bFan:= TRUE;
功能块/函数调用 功能块/函数调名();
选择语句 IF IF <布尔表达式> THEN
<语句内容>;
END_IF
CASE
迭代语句 FOR
WHILE
REPEAT
跳转语句 EXIT
CONTINUE
JMP
返回语句 RETURN
NULL 语句 ;

1.赋值语句
是结构化文本中最常用的语句之一,作用是将其右侧的表达式产生的值赋给左侧的操作数(变
量或地址),使用“:=”表示。
具体格式如下:
<变量>:=<表达式>;

【例 5.X】分别给两个布尔型变量赋值,bFan 置 TRUE,bHeater 置 FALSE。


VAR
bFan: BOOL;
bHeater:BOOL;
END_VAR

bFan:= TRUE;
bHeater:= TRUE;

2.函数及功能块调用
功能块调用采用将功能块名进行实例化实现调用,如 Timer 为 TON 功能块的实例名,具体格
式如下
功能块实例名:(功能块参数);
如果需要在 ST 中调用功能块,可直接输入功能块的实例名称,并在随后的括号中给功能块的
各参数分配数值或变量,参数之间以逗号隔开;功能块调用以分号结束。
例如,在结构化文本中调用功能块 TON 定时器,假设其实例名为 TON1,具体实现如图 5.x 所
示。
图 5.x 结构化文本调用功能块

3. 选择语句
1) IF 语句
用 IF 语句实现单分支选择结构,基本格式如下。
IF <布尔表达式> THEN
<语句内容>;
END_IF
如果使用上述格式,只有当<布尔表达式>为 TRUE 时,才执行语句内容,否则不执行 IF 语句
的<语句内容>。语句内容可以为一条语句或者可以为空语句,也可以并列多条语句,该语句表达式
执行流程图如图 5.x 所示。

布尔表
达式

TRUE
FALSE
语句内容

图 5.x 简单 IF 语句执行流程图
【例 5.X】使用 PLC 判断当前温度是否超过了 60 摄氏度,如果超过,始终打开风扇进行散热
处理,具体实现代码如下。
VAR
nTemp:BYTE; (*当前温度状态信号*)
bFan:BOOL; (*风扇开关控制信号*)
END_VAR

nTemp:=80;
IF nTemp>60 THEN
bFan:=TRUE;
END_IF

2) IF…ELSE 语句
用 IF 语句实现双分支选择机构,基本格式如下。
IF <布尔表达式> THEN
<语句内容 1>;
ELSE
<语句内容 2>;
END_IF
如上表达式先判断<布尔表达式>内的值,如果为 TRUE,则执行<语句内容 1>,如为 FALSE,
则执行<语句内容 2>,程序执行流程图如图 5.x 所示。

TRUE FALSE
布尔表
达式

语句内容 1 语句内容 2

语句内容 2

图 5.x IF…ELSE 语句执行流程图


【例 5.X】使用 PLC 判断当温度小于到 20 摄氏度时,开启加热设备,否则(温度大于等于 20
摄氏度)加热设备断开状态。
VAR
nTemp:BYTE; (*当前温度状态信号*)
bHeating:BOOL; (*加热器开关控制信号*)
END_VAR

IF nTemp<20 THEN
bHeating:=TRUE;
ELSE
bHeating:=FALSE;
END_IF

当程序的条件判断式不止一个时,此时,需要再一个嵌套的 IF…ELSE 语句,即多分支选择结


构,基本格式如下。
IF <布尔表达式 1> THEN
IF <布尔表达式 2> THEN
<语句内容 1>;
ELSE
<语句内容 2>;
END_IF
ELSE
<语句内容 3>;
END_IF
如上,在 IF…ELSE 中有放入了一个 IF…ELSE 语句,实现嵌套,下面通过一个例子说明嵌套
的使用。
如上表达式先判断<布尔表达式 1>内的值,如果为 TRUE,则继续判断<布尔表达式 2>的值,
如果<布尔表达式 1>的值为 FALSE,则执行<语句内容 3>,回到<布尔表达式 2>判断,如果<布尔
表达式 2>为 TRUE,则执行<语句内容 1>,反之则执行<语句内容 2>。
【例 5.X】当设备进入自动模式后,如实际温度大于 50 摄氏度时,才开启风扇并关闭加热器,
小于等于 50 摄氏度时关闭风扇打开加热器,如在手动模式时,加热器风扇均不动作。
VAR
bAutoMode: BOOL; (*手/自动模式状态信号*)
nTemp:BYTE; (*当前温度状态信号*)
bFan:BOOL; (*风扇开关控制信号*)
bHeating:BOOL; (*加热器开关控制信号*)
END_VAR

IF bAutoMode=TRUE THEN
IF nTemp>50 THEN
bFan:=TRUE;
bHeating:=FALSE;
ELSE
bFan:= FALSE;
bHeating:= TRUE;
END_IF
ELSE
bFan:= FALSE;
bHeating:=FALSE;
END_IF

3) IF..ELSIF..ELSE 语句
此外,多分支选择结构还能通过如下方式来呈现。具体格式如下
IF <布尔表达式 1> THEN
<语句内容 1>;
ELSIF <布尔表达式 2> THEN
<语句内容 2>;
ELSIF <布尔表达式 3> THEN
<语句内容 3>;
...
...
ELSE
<语句内容 n>;
END_IF
如果表达式<布尔表达式 1>为 TRUE,那么只执行指令<语句内容 1>,不执行其它指令。否则,
从表达式<布尔表达式 2>开始进行判断,直到其中的一个布尔表达式为 TRUE,然后执行与此布尔
表达式对应语句内容。如果布尔表达式的值都不为 TRUE,则只执行指令<语句内容 n>,程序执行
流程图如图 5.x 所示。

布尔表 FALSE
达式 1

TRUE 布尔表 FALSE


达式 2

TRUE 布尔表 FALSE


达式 3

TRUE

语句内容 1 语句内容 2 语句内容 3 语句内容 n

图 5.x IF..ELSIF..ELSE 语句执行流程图


4) CASE 语句
CASE 语句是多分支选择语句,他根据表达式的值来使程序从多个分支中选择一个用于执行的
分支,基本格式如下。
CASE <条件变量> OF
<数值 1>: <语句内容 1>;
<数值 2>: <语句内容 2>;
<数值 3, 数值 4, 数值 5>: <语句内容 3>;
<数值 6 .. 数值 10>: <语句内容 4>;
...
<数值 n>: <语句内容 n>;
ELSE
<ELSE 语句内容>;
END_CASE;
CASE 语句按照下面的模式进行执行:
 如果<条件变量>的值为<数值 i>,则执行指令<语句内容 i>。
 如果<条件变量>没有任何指定的值,则执行指令< ELSE 语句内容>。
 如果条件变量的几个值都需要执行相同的指令,那么可以把几个值相继写在一起,并且用逗号
分开。这样,共同的指令被执行,如上程序第四行。
 如果需要条件变量在一定的范围内执行相同的指令,可以通过写入初、终值,以两个点分开。
这样,共同的指令被执行,如上程序第五行。
【例 5.x】当前状态为 1 或 5 时,设备 1 运行和设备 3 停止;状态为 2 时,设备 2 停止和设备 3
运行;如当前状态在 10 至 20 之间,设备 1 和设备 3 均运行,其他情况时要求设备 1, 2, 3 均停
止,具体实现的代码如下。
VAR
nDevice1,nDevice2,nDevice3:BOOL; (*设备 1..3 开关控制信号*)
nState:BYTE; (*当前状态信号*)
END_VAR

CASE nState OF
1, 5:
nDevice1 := TRUE;
nDevice3 := FALSE;
2:
nDevice 2 := FALSE;
nDevice 3 := TRUE;
10..20:
nDevice 1 := TRUE;
nDevice 3:= TRUE;
ELSE
nDevice 1 := FALSE;
nDevice 2 := FALSE;
nDevice 3 := FALSE;
END_CASE;

nState
1或5 其他
2 10~20

设备 1 开 设备 2 关 设备 1 开 设备 1 关
设备 3 关 设备 3 开 设备 3 开 设备 2 关
设备 3 关

图 5.x CASE 语句例流程图


CASE 语句流程图见图 3-x 所示,当 nState 为 1 或者 5 时,设备 1 开,设备 3 关;
nState 为 2 时,设备 2 关,设备 3 开;
nState 为 10~20 时,设备 1 关,设备 3 开;
其他情况则设备 1 关,设备 2 关,设备 3 关。
4. 迭代语句
迭代语句主要用于重复执行的程序,在 CoDeSys 中,常见的迭代语句有 FOR,REPEAT 及
WHILE 语句,下面对这种语句做详细解释。
1) FOR 循环
FOR 循环语句用于计算一个初始化序列,当某个条件为 TRUE 时,重复执行嵌套语句并计算
一个迭代表达式序列,如果为 FALSE,则终止循环,具体格式如下。
FOR <变量> := <初始值> TO <目标值> {BY <步长>} DO
<语句内容>
END_FOR;
FOR 循环的执行顺序如下:
 计算<变量>是否在<初始值>与<目标值>的范围内。
 当<变量>小于<目标值>,执行<语句内容>。
 当<变量>大于<目标值>,则不会执行<语句内容>。
 当每次执行<语句内容>时,<变量>总是按照指定的步长增加其值。步长可以是任意的整数值。
如果不指定步长,则其缺省值是 1。当<变量>大于<目标值>时,退出循环。
从某种意义上理解,FOR 循环的原理就像复印机,在复印机上先预设要复印的份数,在此即循
环的条件,当条件满足时,即复印的张数等于设置的张数,停止复印。
FOR 循环是循环语句中最常用的一种,FOR 循环体现了一种规定次数、逐次反复的功能,但
由于代码编写方式不同,也可以实现其他循环功能,下面通过一个实例,演示如何使用 FOR 循环。
【例 5.x】使用 FOR 循环实现 2 的五次方计算。
VAR
Counter: BYTE; (*循环计数器*)
Var1:WORD; (*输出结果*)
END_VAR

FOR Counter:=1 TO 5 BY 1 DO
Var1:=Var1*2;
END_FOR;
假设 Var1 的初始值是 1,那么循环结束后,Var1 的值的为 32。

注意:
如果<目标值>等于<变量>的极限值,则会进入死循环。假设【例 5.X】中的计数变量 Counter 的类型为
SINT(-128 至 127),将<目标值>设定为 127 时,控制器会进入死循环。故不能对<目标值>设极限值。

2) WHILE 循环
WHILE 循环与 FOR 循环使用方法类似。二者的不同之处是,WHILE 循环的结束条件可以是任
意的逻辑表达式。即可以指定一个条件,当满足该条件时,执行循环,具体格式如下。
WHILE <布尔表达式>
<语句内容> ;
END_WHILE;
WHILE 循环的执行顺序如下:
 计算<布尔表达式>的返回值。
 当<布尔表达式>的值为 TRUE 时,重复执行<语句内容>。
 当<布尔表达式>初始值为 FALSE,那么指令<语句内容>不会被执行,跳转至 WHILE 语句的
结尾。其流程图见图 5.x 所示
FALSE
表达式

TRUE

语句

图 5.x WHILE 语句流程图

注意:
如果<布尔表达式>的值始终为 TRUE,那么将会产生死循环,应当避免死循环的产生。可以通过改变循环
指令的条件来避免死循环的产生。例如:利用可增减的计数器避免死循环的产生。

WHILE 语句在像在工程中控制一台电机,当按下“启动”按钮时(布尔表达式为 TRUE 时),


电机不停的旋转,当按下“停止”按钮后(布尔表达式为 FALSE 时),电机也立即停止。下面通
过一个实例,演示如何使用 WHILE 循环。
【例 5.x】只要计数器不为零,则始终执行循环体内的程序。
VAR
Counter: BYTE; (*计数器*)
Var1:WORD;
END_VAR

WHILE Counter<>0 DO
Var1 := Var1*2;
Counter := Counter-1;
END_WHILE
在一定的意义上,WHILE 循环比 FOR 循环的功能更加强大,这是因为在执行循环之前,
WHILE 循环不需要知道循环的次数。因此,在有些情况下,只使用这两种循环就可以了。然而,
如果清楚地知道了循环的次数,那么 FOR 循环更好,因为 FOR 循环可以避免产生死循环。
3) REPEAT 循环
REPEAT 循环与 WHILE 循环不同,因为只有在指令执行以后,REPEAT 循环才检查结束条件。
这就意味着无论结束条件怎样,循环至少执行一次。
具体格式如下。
REPEAT
<语句内容>
UNTIL
<布尔表达式>
END_REPEAT;
REPEAT 循环的执行顺序如下:
 当<布尔表达式>的值为 FALSE 时,执行<语句内容>。
 当<布尔表达式>的值为 TRUE 时,停止执行<语句内容>。
 在第一次执行<语句内容>后,如果<布尔表达式>的值为 TRUE,那么<语句内容>只被执行
一次。
注意:
如果<布尔表达式>的值始终为 TRUE,那么将会产生死循环,应当避免死循环的产生。可以通过改变循环
指令部分的条件来避免死循环的产生。例如:利用可增减的计数器避免死循环的产生。

下面通过一个实例,演示如何使用 REPEAT 循环。


【例 5.X】REPEAT 循环举例,当计数器为 0 时,则停止循环。
VAR
Counter: BYTE;
END_VAR

REPEAT
Counter := Counter+1;
UNTIL
Counter=0
END_REPEAT;
此例的结果为,每个程序周期都进入该 REPEAT 循环,Counter 为 BYTE(0-255),即每个周
期内都进行了 256 次自加一计算。
因为之前提到的“这就意味着无论结束条件怎样,循环至少执行一次”,所以每当进入该
REPEAT 语句时,Counter 先为 1,每个周期内都执行了 256 遍的 Counter := Counter+1 指令,直到
将 Counter 变量累加至溢出为 0,跳出循环。再被加到溢出,如此往复。

5. 跳转语句
1) EXIT 语句
如果 FOR、WHILE 和 REPEAT 三种循环中使用了 EXIT 指令,那么无论结束条件如何,内循
环立即停止,具体格式如下。
EXIT;
【例 5.X】使用 EXIT 指令避免当使用迭代语句时中出现除零。
FOR Counter:=1 TO 5 BY 1 DO
INT1:= INT1/2;
IF INT1=0 THEN
EXIT; (* 避免程序除零*)
END_IF
Var1:=Var1/INT1;
END_FOR
当 INT1 等于 0 时,则 FOR 循环结束。

2) CONTINUE 语句
该指令为 IEC 61131-3 标准的扩展指令,CONTINUE 指令可以在 FOR、WHILE 和 REPEAT 三
种循环中使用。
CONTINUE 语句中断本次循环,忽略位于它后面的代码而直接开始一次新的循环。当多个循环
嵌套时,CONTINUE 语句只能使直接包含它的循环语句开始一次新的循环,具体格式如下。
CONTINUE;

【例 5.X】使用 CONTINUE 指令避免当使用迭代语句时中出现除零。


VAR
Counter: BYTE; (*循环计数器*)
INT1,Var1: INT; (*中间变量*)
Erg: INT; (*输出结果*)
END_VAR

FOR Counter:=1 TO 5 BY 1 DO
INT1:= INT1/2;
IF INT1=0 THEN
CONTINUE; (* 为了避免除零 *)
END_IF
Var1:=Var1/INT1; (*只有当 INT1 不等于 0 的情况下才执行*)
END_FOR;
Erg:=Var1;

3) JMP 语句
跳转语句,跳转指令可以用于无条件跳转到使用跳转好标记的代码行,具体格式如下。
<标识符>:
.
JMP <标识符>;
<标识符>可以是任意的标识符,它被放置在程序行的开始。JMP 指令后面为跳转目的地,即一
个预先定义的标识符。 当执行到 JMP 指令时,将跳转到标识符所对应的程序行。

注意:
必须避免制造死循环,可以配合使用 IF 条件控制跳转指令。

【例 5.x】使用 JMP 语句实现计数器在 0..10 范围内循环。


VAR
nCounter: BYTE;
END_VAR

Label1:nCounter:=0;
Label2:nCounter:=nCounter+1;

IF nCounter<10 THEN
JMP Label2;
ELSE
JMP Label1;
END_IF
上例中的 Label1 和 Label2 属于标签,不属于变量,故在程序中不需要进行变量声明。
通过 IF 语句判断计数器是否在 0-10 的范围内,如果在范围内,则执行语句 JMP Label2,程序
会在下一个周期跳转到至 Label2,执行程序 nCounter:=nCounter+1,将计数器进行自加 1,反之,
则会跳转至 Label1,执行 nCounter:=0,将计数器清零。
此例子中的功能同样可以通过使用 FOR,WHILE 或者 REPEAT 循环来实现。通常情况下,应
该避免使用 JMP 跳转指令,因为这样降低了代码的可读性和可靠性。

RETURN 指令
RETURN 指令是返回指令,用于退出程序组织单元(POU),具体格式如下。
RETURN;

【例 5.x】使用 IF 语句作为判断,当条件满足时,立即终止执行本程序。
VAR
nCounter: BYTE;
bSwitch: BOOL; (*开关信号*)
END_VAR

IF bSwitch=TRUE THEN
RETURN;
END_IF;
nCounter:= nCounter +1;
当 bSwitch 为 FALSE 时,nCounter 始终执行自加 1,如 bSwitch 为 TRUE 时, nCounter 保持上
一周期的数值,立刻退出此程序组织单元(POU)。
6. 空语句
即什么内容都不执行。
具体格式如下。
;

7. 注释
注释是程序中非常重要的一部分,它使程序更加具有可读性,同时不会影响程序的执行。在
ST 编辑器的声明部分或执行部分的任何地方,都可以添加注释。
在 ST 语言中,有两种注释方法:
1) 多行注释以 (* 开始,以 *) 结束。这种注释方法允许多行注释,如图 5.x 的 a)所示。
2) 单行注释以“//”开始,一直到本行结束。这是单行注释的方法,如图 5.x 的 b)所示,
CoDeSysV2 暂不支持此注释方式。

a) b)

图 5.X 结构化文本语言注释
a )多行注释 b )单行注释
5.5 顺序流程图(SFC)
顺序功能流程图语言是为了满足顺序逻辑控制而设计的编程语言。编程时将顺序流程动作的过
程分成步和转换条件,根据转移条件对控制系统的功能流程顺序进行分配,一步一步的按照顺序动
作。每一步则代表一个控制功能任务,用方框表示。在方框内含有用于完成相应控制功能任务的梯
形图逻辑。这种编程语言使程序结构清晰,易于阅读及维护,可以大大减轻编程的工作量,缩短编
程和调试时间。用于系统的规模校大,程序关系较复杂的场合。它的特点是:以功能为主线,按照
功能流程的顺序分配,条理清楚,便于对用户程序理解。

5.5.1 SFC 顺序流程图

SFC 程序按照梯形图表示的各步发生的具体控制把设备运行的顺序分解成不同的步。
1. 基本结构
在 SFC 程序中,从初始步开始,当转移条件成立时按顺序执行转移条件的下一个步,通过
END 步结束一系列的动作,完整过程如图 5.x 所示:
a) 如果启动了 SFC 程序,将首先执行初始步。
在初始步的过程执行中,将检查初始步的下一个转移条件(图中的转移条件 0(t0))是否成立。
b) 在转移条件 0(t0)成立之前仅执行初始步。
当转移条件 0(t0)成立时,将停止初始步的执行,执行初始步的下一个步(图中的步 1(S1))。
在步 1(S1)的执行过程中,将检查步 1(S1)的下一个转移条件(图中的转移条件 1(t1))是否成立。
c) 当转移条件 1(t1)成立时,将停止步 1(S1)的执行,执行下一个步(图中的步 2(S2))。
d) 按照转移条件的成立顺序依次执行下一个步,当执行 END 步时相应块将结束。

图 5.X SFC 基本流程


2. SFC 程序特点
1) SFC 优点
 执行顺控的最佳选择,
将自动运行的顺序就照原样转换成图形描述即可,因此便于编程,且谁看了都能方便地理
解。
 易于理解的结构化程序,
可以采用图形进行层次化和模块化的编写工作,所以便于试运行以及维护工作。如图 5.x 所示。

设备运行流程图 SFC 图

工艺开始 初始步

转移条件 1
托盘确认、夹
紧操作 步1

转移条件 2

钻孔 步2

转移条件 3

松开操作、工
步3
件卸载

转移条件 4
加工完成

图 5.X 结构化的 SFC 程序


 工序(步)间不需要互锁
由于 CPU 只对动作中的步进行运算,所以前进动作和后退动作等的互锁不需要,如图 5.x 所
示。
图 5.X SFC 不需互锁
 在多个工序(步)中可使用同一线圈
由于 CPU 只对动作中的步进行运算,所以即使在没有动作的步中存在相同的线圈,也不会被
作为双线圈处理。(与主顺控程序中的线圈相同时,会变为双线圈处理。)
 用图形监控动作状态
机械设备因为故障而停机时,通过监控,可以在画面上显示当前停止中的步,从而在第一时间
查找出停机的原因,便于排除故障。此外,如果在各步上附有注释,那么动作时为什么会停止的原
因就一目了然了。
 设计的标准化
按照控制流程以图形方式编程,所以无论是谁编写的,都会是几乎相同的没有个人差别的程序,
从而达到设计图的标准化。
 由多人分担程序编写
可以将控制内容分成多个,由不同的人编写程序,然后编辑成一个。
 按工序进行运算处理
由于 CPU 只对动作中的步进行运算,所有通过好的编程方法可以缩短扫描时间。
 此外,有效地使用 SFC 具备的功能,可以缩短机械动作的节拍时间。
2) SFC 缺点
 不适用的控制内容
采用中断处理方式的紧急停止、一直监控、从计算机接收数据等程序都不是顺序控制,所以不
适合编写 SFC 程序。(对这些内容的控制如果在主程序中编写梯形图程序,则便于汇总掌握。)
 不习惯导致的不放心
因为不习惯,所以有不能在极其复杂的控制中使用的先入为主的成见。(通过 SFC 进行结构化
和模块化,可以整理要控制的内容,所以可以只用梯形图编程。)

5.5.2 SFC 的结构

SFC 的基本元素是步加转换条件,整合各基本元素形成了几种基本结构,任何一个复杂的或简
单的 SFC 结构都是以这些基本部件构成的,如图 5.x 所示。

转换条件

图 5.X 基本组成结构

1. 步
1) 步的定义
步表示整个工业过程中的某个主要功能。它可以是特定的时间、特定的阶段或者是几个设备执
行的动作。步属于 SFC 的执行体,所有的实现执行的逻辑代码都包含在其中,转换条件则是决定
步的状态,当上一步的转换条件成立,这个步就被激活,被激活的步将进入执行的状态。被激活期
间,这个步被反复扫描,知道这个步的转换条件成立,步的激活被解除,退出执行到下一个步,下
一个步则被激活,以此类推,直到整个 SFC 遇到 END 步,执行完毕,如图 5.x 所示。
SFC 顺序功能图中的步由一个方框表示,该方框内表示 “步名称”以及由连接线表示的上下
转于关系。步的名称可以在当前位置直接编辑,并且步的名称必须在其所在的 POU 内是独一无二
的,尤其是在 SFC 内使用动作编程时,需要特别注意。
2) 步的组态
步分为两种:初始步和普通步。
 初始步
初始步是表示各个块的开始的步。可以选中对应的“步”,单击鼠标右键,选择“初始步”来
进行初始步的设定。如图 5.x 图中的 a)所示,初始步的视图和普通步略有不同,初始步为双矩形方
框(被一个双边线包围)的视图。

a) b)
图 5.X 设定初始步
a )初始步视图 b )设定初始步
 激活步
当前正在被执行的步称为“激活步”。在线模式下,“激活步”被填充成蓝色。
每步包括一个动作 和一个标记,这个标记用来表示此步是否激活。如果单步动作正在执行,
那么在步就会编程蓝色的框。

图 5.X 激活步
在一个控制循环中激活步的所有动作都将执行。所以,当激活步之后的转换条件是 TRUE 时,
它之后的步被激活。当前激活的步将在下个循环中再执行。
2. 动作
1) 动作的定义
每个步都可以执行多个(或单个)动作,动作包括了此步执行的详细描述,动作可以有梯形图、
FBD、ST、SFC 等语言编写。
动作是步具体要执行的操作,例如,阀门的开启、电动机的起动或停止,工作或产品的移动等。
一个 IEC 步动作有一个双框表示,通过连接线连接在步的右侧。左侧框显示动作的限定符,右
侧显示为动作名称。这些都可以在当前位置直接进行编辑,IEC 标准步和限定符如图 5.x 所示。
限定符是用来配置一个动作将以什么样的方式与 IEC 步相关联的。限定符是被插入到一个动作
元素的限定符区域内,这些限定符有 IecSfc.library 的 SFCActionControl 功能块来进行处理的,并通
过 SFC 插件 IecSfc.library 可以被自动的包含到一个工程中去,SFC 限定符如表 5-x 所示。

表 5-x 限定符
限定符 名称 说明
N Non-stored 只要步激活动作就激活。

S0 Set (Stored) 当步激活时动作启动,步失效时仍继续,直到动作重启。

R0 Overriding Reset 动作失效

L Time Limited 当步激活时动作启动,动作会继续直到步不活跃或设定时间已到。

D Time Delayed 激活后延时器启动。延时后如果步仍激活,动作开始直到步失效。

P Pulse 当步激活/失效时动作开始执行,且值执行一遍。

SD Stored and time Delayed 延时后动作开始,它会继续直到重启。

DS Delayed and Stored 具体设定的时间延时之后如果步仍激活,动作开始并继续,直到重


启。

SL Stored and time limited 步激活后动作开始,并继续一定时间或重启。

当使用限定符 L、D、SD、DS 或 SL 时,需要一个时间值,格式为 TIME 的类型。


2) 动作的组态
在工具栏中选择“ ”按钮进行动作的添加,工具栏如图 5.x 所示。

图 5.X 工具栏“动作”
将其拖拽至步的上方后,会显示如图 5.x 左图中的四个灰色方框,可以将动作拖拽至对应的方
框中,拖拽后会在步对应的“步属性”中也添加相应的设置,如图 5.x 右图所示。
左图中的 1)为 IEC 标准步的动作,CoDeSys 控制平台扩展了 IEC 标准的动作,额外加入了
“步入口”,“步出口”和“步活动”三个动作,三种扩展动作分别为 2),3),4)。

图 5.X 添加“动作”
图 5.x 中所示的 1),2),3),4)对应具体的步动作解释如下,
1) 步动作
使用当前步成为 IEC 标准步时,先点击步,例如 Step0,然后通过“SFC”-->“插入前关联动
作”命令,将 IEC 步动作与步进行关联,一步可以关联一个或多个动作,如图 5.x 的 a)图所示。
新的动作的位置由当前光标位置及使用的命令决定,动作必须在工程内是可用的,并且被插入时必
须采用一个唯一的动作名称,如图 5.x 的 b)图所示。
a) b)

图 5.X IEC 标准步动作


a )添加关联动作 b )添加具体动作
IEC 标准步被至少执行两次,第一次执行是当他们被激活时,第二次执行实在下个周期,他们
被禁止时。由于一个步中可以分配多个动作,这些动作按照从上到下的顺序进行执行。
例如,动作 Action_AS1 关联到步 AS1,作为一个步动作(左),作为一个有资格 N 的 IEC 动
作(右)。两种情况下,两个转换都被使用了,初始步再次到达将会花费两个 PLC 周期的时间。
假设,一个变量 iCounter 在 Action_AS1 中增加。再次激活步 Init 之后,左侧例子中的 iCounter 值为
1。右侧值却是 2,因为 IEC 动作——由于 AS1 的无效,已经执行了两遍
2) 步入口
该步被激活前执行的动作。只要该步被程序激活,这些步动作就会被执行,且在“步活动”动
作之前。 该动作通过步属性的“步入口”区域的入口关联到步。它通过步左下角的“E” 显示,如
图 5.x 所示。

图 5.X “步入口”状态图示
3) 步出口
这个动作会在步执行完的下一周期执行。当步无效时它会被执行一遍。但是,执行不会在同一
个周期,在下一步执行周期的开始。动作通过步属性的“步入口”区域的入口关联到步。它通过步
右下角的“X”显示,如图 5.x 所示。

图 5.X “步出口”状态图示
4) 步活动
步激活时这个动作会被执行,可能的入口已经执行完。这种步动作会在步激活会执行,且在这
一步可能的“步入口”执行完之后。 但是,不同于 IEC 步动作,当它无效时不会被再执行,且它
不可分配资格。
动作通过步属性的“步活动”区域的入口关联到步。它通过步右上角的小三角显示,如图 5.x
所示。

图 5.X “步激活”状态图示

各步的动作编辑画面类似与 POU 的界面,各种语言的编辑界面均可用。所不同的是动作编辑


画面里没有变量申明区,所有的局部变量都在总的 SFC 界面里,如下图所示,所有步的局部变量
都在 POU_2(PRG)。

例如,
每个动作都需要组态,电机

为了关联动作和步,用到下面的限定词。限定词 L、 D、 SD、 DS 和 SL 需要一个时间 常量格


式的时间值。
时间格式为 T#(数值)(单位)。如 5 秒表示为 T#5S。

如图所示:
图 5.X “步激活”状态图示

动作的编程和转换换条件的编程

【例 5.X】限定符 N 的应用举例。

图 5.X 动作限定符 N
限定符“N”的作用是只要对应的步被激活,则相应的连接的变量也被激活。如图 5.x 中的
bVar2,每次 Step0 被执行,bVar2 被置位 ON,反之为 OFF,该限定符可以用于监控步的执行状态。
在本节的开始就介绍到,SFC 的执行过程最基本的结构就是步加转换条件,每当步被激活时,
将执行步的操作,直到转换条件成立才转至下一步。下一步被激活开始新的执行动作,直到自己的
转换条件成立才离开,如此顺序往下执行,如图 5.x 所示。
转换条件告知 SFC 进入下一步

循环扫描

转换条件 为真,转下一步
执行

图 5.X SFC 执行步骤


每个步里面,可以是多个动作在执行,转换条件也是执行判定,所以,建立好 SFC 运行的流
程结构,确定步和动作的组态,剩下的就算是动作和转换条件的编程了。

此外,将产生如下的标签:
 每当创建一个步,会自动分配一个步的结构标签,
 每当创建一个动作,会自动分配一个动作的结构标签,
 每当创建一个转换条件,会自动分配一个 BOOL 量的标签,

这些标签的数据可以在编程中引用。

非布尔量的动作编程

双击动作,即可进入编程界面,
图 5.X 添加动作

可以对添加动作的语言进行编辑。
【例 5.X】建立一个简单的 SFC 程序,

在“动作”中添加代码如下,

bVar1:=TRUE;
只有当 bStart 为 TRUE 后,即可执行 Step0 步中的“动作”,将 bVar1 置为 1。

3. 转移
在步和步之间有所谓的转换。转换条件的值必须是 TRUE 或 FALSE。因而它可以是一个布尔
变量、布尔地址或布尔常量。只有当步的转换条件为真时,步的转换才进行。即前步的动作执行完
后,如果有出口动作则执行一次出口动作,后步如果有入口动作则执行一次后步入口的动作,然后
按照控制周期执行该活动步的所有动作。

用顺序功能图编写的程序组织单元包含了一系列的步,这些步之间是通过定向连接(转换条件)
实现的。

转移是以构成块的基本单位对转移条件进行指定。
转移条件是用于转移至下一个步的条件,通过条件成立转移至下一个步。

转换表示从一步到另一步的切换,这些切换是有条件的。当条件满足时转换才能发生,转换可
以是布尔变量,也可以是一个逻辑判断或者是一个用编程实现的 POU。转换的不同方式如图 5.x 所
示。
如下,介绍几种常用的转移方式:
1) 串行转移
串行转移是指,通过转移条件成立转移至串行连接的下一步执行处理的方法。

图 5.X 串行分支转移
如图 5.x 所示,执行步 n 的动作输出[A]时,如果转移条件 b 成立,则对动作输出[A]进行非执
行处理,执行步(n+1)的动作输出[B]。
2) 选择转移
选择转移是指,在并行连接的多个步中,仅执行最先成立的转移条件的步的方式。
a) 选择分支转移

图 5.X 选择分支转移
 执行步 n 的动作输出[A]时,选择转移条件 b 或者 c 中最先成立的条件的步(步(n+1)或者步
 (n+2)),执行该步的动作输出([B]或者[C])。
 转移条件同时成立时,左侧的转移条件优先。对步 n 的动作输出[A]进行非执行处理。
 选择后,依次执行所选列的各个步,直至进行合并为止。
b) 选择合并转移

图 5.X 选择合并转移
 如果分支中执行列的转移条件(b 或者 c)成立,则对执行步的动作输出([A]或者[B])进行非
执行处理,执行步(n+2)的动作输出[C]。
3) 并行转移
并行转移是指,通过转移条件成立同时执行并行连接的多个步的方式。
a) 分支转移

图 5.X 并行分支转移
 执行步 n 的动作输出[A]时,如果转移条件 b 成立,则同时执行步(n+1)的动作输出[B]、步
(n+3)的动作输出[D]。
 转移条件 c 成立时转移至步(n+2),转移条件 d 成立时转移至步(n+4)。
b) 合并转移

图 5.X 并行合并转移
 执行步 n 的动作输出[A]、步(n+1)的动作输出[B]时,如果转移条件 b、转移条件 c 成立,
则分别对步 n 的动作输出[A]、步(n+1)的动作输出[B]进行非执行处理,转移至等待步。
 等待步是用于使并行处理的步同步的步,通过将并行处理的所有的步转移至等待步,对转
移条件 d 进行检查,如果转移条件 d 成立,则执行步(n+2)的动作输出[C]。
 等待步被作为虚拟步,即使没有动作输出梯形图也没有关系。

更容易设计和维护系统
因为整个系统和各个站以及机器本身的控制都是在一对一的基础上与 SFC 程序的块和步对应
所以即使顺控程序经验较少的人也可以设计和维护系统此外其它程序员用该格式设计的程序也比顺
控程序更易于解码。

1号 2号 3号
主 控制单元 控制单元 控制单元
控制单元
传送带

主控程序 1 号程序 2 号程序 3 号程序

Init Init Init Init

1 号运行 夹紧 夹紧 夹紧

2 号运行 钻孔 钻孔 钻孔

3 号运行 卸料 卸料 卸料

图 5.X SFC

4. 跳转
跳转是指,通过转移条件成立转移至同一个块内的指定步执行处理的方式。

跳转是通过一条竖线和水平箭头及跳转目标名展示的。
跳转定义了后续转换为 TRUE 时将要执行的步。因为处理线不能交叉或往上,跳转就需要了。
除了图最后的跳转,跳转只能用在分支的最后。当最后一个转换被选中时,可以通过 ⇘ “插
入前跳转” 命令插入 。
跳转的目标可以通过关联的文本字符串给定,可内引编辑。它可以是一个步名或平行分支的标
签。
图 5.X 并行合并转移
 执行步 n 的动作输出[A]时,如果转移条件 b 成立,则对动作输出[A]进行非执行处理,执
行步 m 的动作输出[B]。
在并行转移内进行跳转时,只能在分支的各个纵方向进行跳转。

例如,从分支起至合并为止的纵方向内的跳转程序

图 5.X 并行合并转移
不能创建如下所示的跳转程序:向分支内的其它纵向梯形图的跳转,向并行分支外部的跳及从
并行分支外部向并行分支内的跳转。

例如,向并行分支外部的跳转程序(不能指定)
图 5.X 并行合并转移
例如,如下图所示的转移条件成立时,不要指定至当前步的跳转。
如果指定了至当前步的跳转,则无法正常动作。

图 5.X 并行合并转移

跳转插入

【例 5.x】
图 5.X SFC 跳转举例

5.5.3 SFC 的编程元素

SFC 顺序功能图在快捷菜单中可以添加 SFC 中的元素,如图 5.x 所示。

添加入口动作 插入后关
初始步 添加出口动作 进入宏
选择分支 联动作
插入后跳转 退出宏
并行分支 插入右分支

插入后步转移 插入前跳转 添加宏


插入前步转移 插入左分支 插 入 前 关
插入宏
联动作

图 5.X 新建快捷菜单

在“工具箱”中可以添加 SFC 中的元素,如图 5.x 所示。



转移
动作
跳转

分支

图 5.X SFC 工具箱


各元素的定义如下。

5.5.4 SFC 元素的属性

SFC 元素的属性分为标准属性及隐含变量属性,如下会对这 2 中属性做详细介绍。


1. 标准属性
属性可分为常规属性和指定属性,如图 5.x 中红色框出部分所示。常规属性为每个不同元素所
公有的属性,而指定的属性针对不同的元素,其成员也不同。

图 5.X SFC 元素属性图示


1) 常规属性
常规属性包括名称,注释及符号,具体解释如表 5-x 所示。

表 5.x SFC 标准常规属性


属性名 说明
名称 元素名,默认是“<element><running number>”,如,步名 “Step0”,“Step1”,
分支名“branch0” 等。
注释 注释,文本字符串,如“Reset the counter”。断行通过 [ Ctrl ] +[ Enter ]。
符号 针对每一个SFC元素,隐含标示会被创建,命名同元素。
你可以定义这个标示标量是否输出到符号配置中,以及这个符号如何在PLC中访问。

2) 指定的属性

3) 表 5.x SFC 标准指定的属性


属性名 说明
初始步 这个选项在当前初始步 (init step)特性中总是激活的。默认它是对SFC第一步激活,对其
它步无效。注意,如果你对其它步激活这个选项,你在其他初始步前面必须使之无效,来避
免编译错误。
次数 最小活动 处理该步的最小时间;允许值:时间常数,如t#8s或时间变量,默认:t#0s。
最大活动 处理该步的最大时间;允许值:时间常数,如t#8s或时间变量,默认:t#0s。
动作 步入口 步激活前执行的动作。
步活动 步激活时这个动作会被执行,可能的入口已经执行完。
步出口 这个动作会在步执行完的下一周期执行(“步出口”)。

2. 隐形变量属性
每个 SFC 步和 IEC 动作提供隐含生成变量供运行时监视步和 IEC 动作。还可以定义变量来监
视和控制 SFC 执行(超时,重启,尖模式)。
这些隐含变量的类型实在库 IecSFC.library 中定义的。SFC 对象添加时这个库会自动被添加。
在 SFC 编程语言里有些隐形变量可以外部调用。正常情况下这些变量不显示出来。要使用这
些变量需要对 SFC 属性做设置。右击 SFC 语言的 POU 的“属性”,弹出属性对话框中点击“SFC
设置”选项,将需要使用变量前打勾。如图 5.x 所示:

图 5.X SFC 隐形属性


为了访问这些标识使它们工作,它们必须声明和激活。这在“ SFC 设置”对话框中设置。 它
是对象属性对话框的子对话框。如需使用该变量,则必须在变量前的“使用”前打上勾,该变量在
其描述中也说明了其具体的使用方法。
5.6 连续功能图(CFC)
5.6.1 简介

实际上是 FBD 的另一种形式。在整个程序中,可以自定义运算块的顺序,易于实现流程运算。


连续功能流程图是功能块图的一种特殊形式,它用于描述资源的顶层结构以及程序和功能块对
任务的分配。
连续功能流程图和功能块图之间的主要区别是资源和任务分配的不同。每一功能用任务的名称
来描述,如图所示。如果一个程序内的功能块象它的父程序一样在相同的任务下执行,任务关联是
隐含的。连续功能流程图如图 5.x 所示。

图 5.x CFC 连续功能流程图

5.6.2 程序执行顺序

在 CFC 语言里元素的右上角的数字,显示了在线模式下 CFC 中元素的执行顺序。执行流程从


编号为 0 的元素开始。移动元素时,它的编号仍保持不变。添加一个新元素时,按照拓扑序列(从
左到右,从上到下),该元素将自动获得一个编号,如图 5.x 红色部分所示。

图 5.x CFC 编程语言顺序编号


CFC 语言中运算块、输出、跳转、返回和标签元素的右上角的数字,显示了在线模式下 CFC
中元素的执行顺序。执行流程从编号为 0 的元素开始。考虑到执行顺序会影响到结果,在一定情况
下可以改变执行顺序。操作在菜单“CFC”下的“执行顺序”中的子菜单命令可以改变元素的执行
顺序。
执行顺序包含的命令有:置首、置尾、向上移动、向下移动、设置执行顺序、按数据流排序、
按拓扑排序,如图 5.x 所示。

图 5.x CFC 顺序编排


1) 置首
把选中元素移到执行顺序的首端。如果选中多个元素执行这个命令时,选中元素的原有的内部
顺序保持不变;未选中元素的内部顺序也保持不变。
2) 置尾
把所有选中元素移到执行顺序的末端。选中元素的内部顺序保持不变;未选中元素的内部顺序
也保持不变。具体操作可以参照上述“置首”功能。
3) 向上移动
把所有选中元素(如果某个元素已在执行顺序的首端,除去该元素)在执行顺序上向前移动一
位。如选中图 7 中的 3 号元素执行“向上移动”命令,结果是 2 号元素与 3 号元素的执行顺序互换
了一下,其余都不变。
4) 向下移动
把所有选中元素(如果某个元素已在执行顺序的末端,除去该元素)在执行顺序上向后移动一
位。具体操作参考“向上移动”。
5) 设置执行顺序
该命令可以对选中元素重新编号,调整元素的执行顺序。执行“设置执行顺序”命令后,会打
开“设置执行顺序”对话框。在当前执行次序区域显示当前单元编号,用户可以在“新处理顺序”
中输入需要单元编号,括弧内的值为可选值,如图 5.x 所示。

图 5.x 设置执行顺序
6) 按数据流排序
数据流排序表示各个元素按照数据流顺序执行,而不是按照元素所在位置(拓扑)决定执行顺
序。执行数据流排序命令后,CFC 编辑器内部做如下操作:
a) 按照拓扑对所有元素进行排序;
b) 创建一个新的执行顺序链表;
c) 找到那些已知的输入值,下一步可以被执行但还没有放入到链表中的元素。
数据流排序的优点是:一个算法执行后,连接到它的输出引脚上算法块会立刻执行;但是在拓
扑排序中却不一定是这样。拓扑排序的执行结果可能和数据流排序的执行结果不同。
【例 5.x】图 5.x 为打乱元素标号的程序,使用“按数据流排序”的排序方法查看结果。

图 5.x 使用数据流排序之前
选中全部元素后执行“按数据流排序”后结果如图 5.x 所示。
图 5.x 使用数据流排序之后
元素的编号按照数据流的流向重新编排的,函数 MUL 和 SUB 的执行顺序较之前有了改变。
7) 按拓扑排序
拓扑排序表示各个元素按照拓扑顺序执行,而不是按照元素数据流决定执行顺序。拓扑排序后,
元素按照从左到右,从上到下的顺序执行;左边的元素的执行顺序编号小于右边的,上边的小于下
边的。拓扑排序依据的是元素的位置坐标,与连线位置无关。
【例 5.x】图 5.x 为打乱元素标号的程序,使用“按拓扑排序”的排序方法查看结果。

图 5.x 使用按拓扑排序之前
选中 SUB 函数,右键执行“按拓扑排序”命令后结果如图 5.x 所示,

图 5.x 使用按拓扑排序之后
拓扑排列的顺序就是:从左到右,从上到下的顺序执行;左边的元素的执行顺序编号小于右边
的,上边的小于下边的。

5.6.3 连接元素

CFC 的元素包括块、输入、输出、跳转、标记、返回和注释等具体参考表 5-x:


图 5.x CFC 工具箱
具体描述如表 5-x 所示,

表 5-x CFC 插入元素一览


插入图标 类型 图形符号 说明
默认在工具箱最上方。一旦这个条目被选中,光标编程箭
头形状,你可以选择编辑窗口中的元素来放置并编辑它
们。
输入

输出

运算

跳转

标签

返回

合成

选择

注释 用该元素可以为图表添加注释。选中文本,即可以输入注
释。用户可以用<ctrl>+<enter>在注释中换行。
输入 有些运算块可以增加输入引脚。首先在工具箱中选中
引脚 Input Pin,然后拖放到在CFC编辑器中的算法块上,该运
算块就会增加一个输入引脚。
输出 有些运算块可以增加输出引脚。首先在工具箱中选中
引脚 Output Pin,然后拖放到在CFC编辑器中的算法块上,该
运算块就会增加一个输出引脚。

1. 输入/输出
1) 输入
在 CFC 工 具 箱 中 插 入“ ” 符 号 添加 合 成器 功能 。 在 CFC 编 辑 器 中插 入 后 的 图示 为
“ 。
选中“???”文本,然后修改为变量或者常量。通过输入助手可以选择输入一个有效标识符。
2) 输出
在 CFC 工 具 箱 中 插 入“ ” 符 号 添加 合 成器 功能 。 在 CFC 编 辑 器 中插 入 后 的 图示 为

“ 。
选中“???“文本,然后修改为变量或者常量。通过输入助手可以选择输入一个有效标识符。
2. 运算块
在 CFC 工具箱中插入“ ”符号添加合成器功能。在 CFC 编辑器中插入后的图示为

“ ”。
运算块可用来表示操作符,函数,功能块和程序。插入运算块后,选中运算块的“???”文本
框,将其修改为操作符名,函数名,功能块名或者程序名。或者可以通过“输入助手”选择输入一
个有效的对象。
【例 5.x】通过运算块,在 CFC 编程语言中调用定时器功能块。
新建 POU,使用 CFC 编程语言,添加“运算块”,点击“???”输入“F2”弹出输入助手,在
其中选择功能块,找到定时器功能块,如图 5.x 所示。

图 5.x CFC 输入助手工具


如果需要在 ST 中调用功能块,可直接输入功能块的实例名称,并在随后的括号中给功能块的
各参数分配数值或变量,参数之间以逗号隔开;功能块调用以分号结束。
例如,在结构化文本中调用功能块 TON 定时器,假设其实例名为 TON1,具体实现如图 5.x 所
示。

图 5.x 连续功能图调用功能块
在例子中,当插入一个功能块,随即运算块上出现另一个“???”,这时要把“???”修改为功
能块实例名 0,在本例中实例名为 TON_0 和 TOF_0。
若运算块被修改为另一个运算块(通过修改运算块名),而且新运算块的最大输入或输出引脚
数,或者最小输入或输出引脚数与前者不同。运算块的引脚会自动做相应的调整。若要删除引脚,
则首先删除最下面的引脚。
3. 合成器
合成器用于结构体类型的运算块输入。合成器会显示结构体的所有成员,以方便编程人员使用
它们。
在 CFC 工具箱中插入“ ”符号添加合成器功能。在 CFC 编辑器中插入后的图示为

“ 。
使用方法是:先增加一个合成器到编辑器中,修改“???”为要使用的结构体名字,然后连接
合成器的输出引脚和运算块的输入引脚。
【例 5.x】CFC 程序 CFC_PROG 处理一个功能块实例 fubblo1,有一个结构体类型输入变量
struvar。 通过使用合成器元素,结构体变量可以访问:
结构 stru1 定义:
TYPE stru1 :
STRUCT
ivar:INT;
strvar:STRING:='hallo';
END_STRUCT
END_TYPE
功能块 fublo1,声明和实现:
FUNCTION_BLOCK fublo1
VAR_INPUT
struvar:STRU1;
END_VAR
VAR_OUTPUT
fbout_i:INT;
fbout_str:STRING;
END_VAR
VAR
fbvar:STRING:='world';
END_VAR
fbout_i:=struvar.ivar+2;
fbout_str:=CONCAT (struvar.strvar,fbvar);
程序 CFC_PROG 的 声明和实现:
PROGRAM PLC_PRG
VAR
intvar: INT;
stringvar: STRING;
fbinst: fublo1;
erg1: INT;
erg2: STRING;
END_VAR
程序如图 5.x 所示,1)为合成器,2)为含有结构体输入变量的 stru1,实现了结构体类型的输
入块运算。

图 5.x 合成器的应用
最终的程序运行结果如图 5.x 所示。

图 5.x CFC 合成器最示例运行结果

4. 选择器
选择器用于结构体类型的运算块输出。选择器会显示结构体的所有成员,以方便编程人员使用
它们。
在 CFC 工具箱中插入“ ”符号添加选择器功能。在 CFC 编辑器中插入后的图示为

“ ”。
使用方法是:先增加一个选择器到编辑器中,修改“???”为要使用的结构体名字,然后连接
选择器的输出引脚和运算块的输出引脚。
【例 5.x】CFC 程序 cfc_prog 处理功能块实例 fubblo2,它有一个 stru1 结构的输出变量 fbout。
通过选择元素,结构体成员变量可以被访问:
结构定义 stru1:
TYPE stru1 :
STRUCT
ivar:INT;
strvar:STRING:='hallo';
END_STRUCT
END_TYPE
功能块 fublo1,声明与实现:
FUNCTION_BLOCK fublo2
VAR_INPUT
fbin : INT;
fbin2:STRING;
END_VAR
VAR_OUTPUT
fbout : stru1;
END_VAR
VAR
fbvar:INT:=2;
fbin3:STRING:='Hallo';
END_VAR
程序 PLC_PRG_1,声明与实现:
PROGRAM PLC_PRG_1
VAR
intvar: INT;
stringvar: STRING;
fbinst: fublo2;
erg1: INT;
erg2: STRING;
fbinst2: fublo2;
END_VAR
程序如图 5.x 所示,1)为拥有 stru1 结构体类型输出变量 fbout 的功能块,2)选择器。

图 5.x CFC 选择器示例运行结果


最终的程序运行结果如图 5.x 所示。样例程序可在\第五章\CFC_CFG\中查看。
图 5.x CFC 选择器示例运行结果

5. 注释
在 CFC 工具箱中插入“ ”符号可以实现添加注释功能。在 CFC 编辑器中插入后的图示为
“ ”。
通过添加该元素,可以在 CFC 程序中为图表添加注释。选中文本,直接输入注释即可。如需
要换行,输入<ctrl>+<enter>即可实现换行,图 5.x 为 CFC 中的注释视图。

图 5.x CFC 中插入注释的视图

6. 跳转
CFC 程序的跳转由跳转指令和标签两部分组成,如下会对这两部分做详细介绍。
1) 跳转
在 CFC 工具箱中插入“ ”符号可以实现跳转功能。在 CFC 编辑器中插入后的图示为

“ ”。
跳转用来指示程序下一步执行到哪,具体去哪最终“标签”所定义,如下会介绍“标签”的使
用方法。插入一个新跳转后,要用跳转名替代“???”。
2) 标签
在 CFC 工 具 箱 中 插 入 “ ” 符 号 可 以 添 加 标 签 。 在 CFC 编 辑 器 中 插 入 后 的 图 示 为

“ ”。
“标签”可以标识程序跳转的位置在在线模式下,如果跳转被激活,则可以进入跳转对应的
标签,如此循环执行。
标签名不属于变量,故在程序声明区中不需要对其定义,例 5.x 说明了如何正确使用跳转指令
和标签。
【例 5.x】CFC 跳转指令和标签功能示例。
图 5.x CFC 跳转功能示例
程序启动后,当输入值 nInput 大于 10 且小于 100 时,程序执行跳转功能,转至标签 Label1,
由于 Label1 的执行序号为 0,故在该程序中执行的顺序为:4—>0—>1—>2—>3—>4,如此循环执
行。
由于在此程序中还有自加 1 的功能,但执行序号为 5 和 6,故当跳转指令被执行时,该自累加
功能不会被程序执行,反之 nCounter 则进行自累加。
7. 返回指令
在 CFC 工具箱中插入“ ”符号可以实现返回功能。在 CFC 编辑器中插入后的图示为

“ ”。
需特别注意该执行顺序号,当条件满足时,则会直接返回程序。

命令返回一个入令插这个命注意在联机模式下带 RETURN 名字的跳转标签自动插入到第一列和编


辑器最后元素的后面,在分支中,它自动跳转到执行将离开 POU 之前的地方。
RETURN 指令是返回指令,用于退出程序组织单元(POU)。

注意:
在线模式下,RETURN 自动插入到编辑器最后那个元素之后。在单步调试中,在离开该 POU 之前,会自
动跳转到该 RETURN。

5.6.4 CFC 的组态

1. 在 CFC 程序中添加连接
添加连接时,首先激活连接程序块的管脚,激活后在管脚出会有一个方形区域出现,鼠标左键
选中这个方形区域,如图 5.x 的 1)所示,按住鼠标至要连接的另一个连接点处松开鼠标,连接至
5.x 中的 2)处,即完成了两部分的连接。
图 5.x CFC 程序添加连接

2. 在 CFC 程序中删除连接
删除连接时,首先激活连接程序块的管脚,激活后在管脚出会有一个方形区域出现,鼠标右键
选中这个方形区域,在随后显示菜单栏中选择“删除”即可,如图 5.x 中框出部分所示。也可以在
快捷菜单栏中选择“ ”按钮来删除程序中的连接线。

图 5.x CFC 程序删除连接

CFC 页面

置首
连接标记 向上
取反 无 复位 复位引脚

EN/ENO 置尾 向上
选择连接的管脚 参考分配
置位 删除未使用引脚
图 5.x CFC 快捷菜单按钮

图 5.x CFC 工具箱

图 5.x CFC 分页

页面的大小可以通过命令“编辑页面尺寸”来改变。
两个页面的连接是通过 "连接标记 -源"和 "连接标记 - 沉" 元素实现的(参见 ⇘ “连接标示”)。
"连接标记 -源" 可以通过拖动放到右侧边缘, "连接标记 - 沉" 在左边缘,如果一个元素的输入或输
出通过连接线到了边缘,连接标记自动被放置。
第6章 指令系统
本章主要知识点
 了解 CoDeSys 软件指令系统的内容
 掌握常用的基本指令,位逻辑指令,定时器、计数器、数据处理指令和运算指令
 掌握如何封装库、函数及功能块

在可编程控制器中,使 CPU 完成某种操作或实现某种功能的命令及多个命令的组合称为指令,


指令的集合称为指令系统。指令系统是可编程控制器硬件和软件的桥梁,是可编程控制器程序设计
的基础。本章会介绍到的包括位逻辑指令、定时器指令、计数器指令、数据处理指令、运算指令和
数据转换指令等。

6.1 位逻辑指令
位逻辑指令处理布尔值“1”和“0”的逻辑变化。CoDeSys 提供的位逻辑指令包括基本的逻辑
运算,置位/复位优先触发器及上升/下降沿检测指令,如表 6-1 所示。

表 6-1 位逻辑指令的图形化与文本化指令表
位逻辑指令 图形化语言 文本化语言 说明
位逻辑指令 AND 与

OR 或

NOT 非
XOR 异或

SR 置为优先触发器
RS 复位优先触发器

R_TRIG 上升沿触发

F_TRIG 下降沿触发

6.1.1 基本逻辑指令

基本位逻辑指令包括有“与”、“或”、“非”、“异或”。在 CoDeSys 中,从功能上分可


以分为:按位逻辑运算及布尔逻辑运算。
 按位逻辑运算:对两个整型数据的相应位逐一进行布尔逻辑运算,并返回兼容的整数结果。
 布尔逻辑运算:对两个布尔类型数据执行逻辑运算。
1. 按位“与”AND 表 6-1 “与”指令逻辑关系表
功能:按位“与”运算指令是比较两个整数的相应位。当 输入 1 输入 2 结果
两个数的对应位都是 1 时,返回相应的结果位是“1”;当两个 0 0 0
整数的相应位都是“0”或者其中一个位是“0”时,则返回相 0 1 0
应的结果位是“0”。其“与”逻辑如表 6-x 所示。 1 0 0
1 1 1
【例 6.x】创建一个 POU,声明两个整形
变量 iVar1 和 iVar2,分别对其进行赋值 1 和
85,并对这两个变量进行按位与运算,输出结
果至 iResult,具体实现代码如下所示。
VAR
iVar1:INT:=1;
iVar2:INT:=85;
iResult:INT;
END_VAR 图 6.x 按位“与”逻辑指令程序举例

iResult:=iVar1 and iVar2;


10 进制数 1 对应 2 进制数为 0000 0001,10 进制数 85 对应 2 进制数为 0101 0101。根据按位与
运算的定义,将每一个独立位逐一进行“与”运算,得出最终的结果 0000 0001,即 10 进制数值 1,
见图 6.x 所示。
2. 布尔“与”AND
功能:布尔“与”运算用于计算两个布尔表达式的“与”结果。当两个布尔表达式的结果都为
真时,则返回为真,其中只要有一个为假时,则返回为假。
【例 6.x】创建一个 POU,利用布尔“与”运算,判断运算返回值,代码如下。
VAR
bResult:BOOL;
iVar1:INT:=30;
END_VAR

bResult:=iVar1 <80;
由于 30 的确小于 80,故等式右边的条件为真,程序的运行结果是 bResult 为 TRUE。
3. 按位“或”OR
功能:按位“或”运算指令是比较两个整数的相应位。 表 6-x “或”指令逻辑关系表
当两个数的对应位有一个是“1”或者都是“1”时,返回相应 输入 1 输入 2 结果
的结果位为“1”。当两个整数的相应位都是“0”时,则返回 0 0 0
相应的结果为是“0”。其“或”逻辑如表 6-x 所示。 0 1 1
【例 6.x】创建一个 POU,对变量 iVar1 和 iVar2 进行按位 1 0 1
“或”运算,并对这两个变量进行按位或运算,输出结果至 1 1 1
iResult,具体实现代码如下所示。
VAR
iVar1:INT:=1;
iVar2:INT:=85;
iResult:INT;
END_VAR

iResult:=iVar1 OR iVar2;
程序的最终运行结果为 85。
4. 布尔“或”OR
功能:布尔“或”运算指令用于计算两个布尔表达式的“或”结果。当两个布尔表达式中有一
个表达式返回为真时,则结果为真;当两个布尔表达式的结果都是假时,则结果为假。
【例 6.x】创建一个 POU,利用布尔“或”运算,判断运算返回值,代码如下。
VAR
bResult:BOOL;
bVar1:BOOL;
iVar1:INT:=30;
END_VAR

bResult:=bVar1 OR (iVar1 <80);


由于 iVar1 的初始值为 30,故 iVar1<80 条件为真,而 bVar1 的初始值为“0”,故为假,一真
一假最终的“或”逻辑结果可根据表 6-x 可以看出,为真。故等式右边的条件为真,程序的运行结
果是 bResult 为 TRUE。
5. 按位“非”NOT
功能:对逻辑串进行取反,将当前的值由“0”变“1”, 表 6-x “非”指令逻辑关系表
或由“1”变“0”。 输入 结果
按位“非”运算指令是将变量或常量逐一取非。其逻辑见表 6-x 0 1
所示。 1 0
【例 6.x】创建一个 POU,利用按位“非”运算,判断运算返回
值,具体代码如下。
VAR
byVar1:BYTE:=1;
byVar2:BYTE;
END_VAR

byVar2:=NOT byVar1;
由于 byVar1 的值为 1,将其转换为 2 进制后为 0000 0001,进行按位取反后,结果为 1111 1110。
最终的输出结果为 254。
6. 布尔“非”NOT
功能:布尔“非”运算指令用于计算单个布尔表达式的结果。当输入为真时,结果为假;当输
入为假时,结果为真。
【例 6.x】创建一个 POU,利用布尔“非”运算,判断运算返回值,具体代码如下。
VAR
bResult:BOOL;
bVar1:BOOL;
iVar1:INT:=30;
END_VAR

bResult:=NOT ( 80 < iVar1 );


80<30 该命题为假,使用 NOT 指令对该布尔表达式取反后,得到的结果为真,故最后 bResult
的结果为 True。
7. 按位“异或”XOR
功能:按位“异或”运算指令比较两个整数的相应位。
当两个整数的对应位是一个“1”而另外一个是“0”时,返回相应的结果位是“1”。当两个
整数的相应位都是“1”或都是“0”时,则返回相应的结果位是“0”。
【例 6.x】创建一个 POU,对变量 iVar1 和 iVar2 进行按位“异或”运算,并输出结果,具体
实现代码如下。
VAR
iVar1:INT:=1;
iVar2:INT:=85;
iResult:INT;
END_VAR

iResult:=iVar1 XOR iVar2;


10 进制的 1 对应 2 进制数是 0000 0001,10 进制数 85 对应的 2 进制数是 0101 0101。根据按位
“异或”运算指令的定义,其结果为 84。
按位异或位运算。只有当一个触点的输入状态为“1”,另一个触点的输入状态为“0”时,输
出为“1”,如果两个触点状态同时为“1”或同时为“0”,则输出为“0”。其时序图如 6.x 所示。
Input1
Input2

与 Output1

或 Output2

异或 Output3

图 6.x 基本逻辑指令时序图
【例 6.X】装修卧室时,通常都会选择安装双控开关面板。比如进卧室时在门口按开关 IX0.1
打开灯具,上床后不想起来,在床头也有一个开 IX0.2 控制卧室的灯 QX0.1,卧室门口的开关和床
头的开关同时都可以独立的开关卧室的灯,请用位逻辑指令实现此功能。
程序如下,也可参考样例程序\BitLogic_XOR\。

图 6.x 异或指令使用举例
【例 6.X】某设备工作时有三台风机需要降温散热。当设备处于运行状态时,三台风机正常转
动,则设备降温状态指示灯常亮;当其中任意两台风机转动时,则设备降温状态指示灯以 2Hz 的频
率闪烁;当只有一台风机转动时,则设备降温状态指示灯以 0.5Hz 的频率闪烁;如三台风机都不转
动时,则设备降温状态指示灯不亮。I/O 地址分配表见表 6-x。控制程序如图 6.x 所示。

表 6-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 1 号风机反馈信号 %QX0.0 设备降温状态指示灯
%IX0.1 2 号风机反馈信号 %MX0.0 0.5Hz 脉冲闪烁信号
%IX0.2 3 号风机反馈信号 %MX0.1 2Hz 脉冲闪烁信号
程序如下,请参考样例程序\FanMonitor\。
图 6.x 风扇降温控制程序举例

8. 布尔“异或”XOR
功能:布尔“异或”运算指令用于计算两个布尔表达式的结果,只有当其中一个表达式是真,
另外一个表达式为假时,该表达式返回的结果才是真;当两个表达式的计算结果都是真或者都是假
时,则返回的结果为假。
【例 6.x】创建一个 POU,利用布尔“异或”运算指令,判断返回值是 TRUE 还是 FALSE,具
体实现代码如下。
VAR
bResult:BOOL;
bVar1:BOOL;
iVar1:INT:=30;
END_VAR

bResult:=bVar1 XOR (iVar1 <80);


程序的运行结果为 TRUE。

6.1.2 置位优先与复位优先触发器指令

在继电器系统中,一个继电器的若干对触点是同时动作的。在 PLC 中,指令是一条一条执行


的,指令的执行是有先后次序的,没有“同时”执行的指令。
所以线圈格式的置位、复位指令有优先级。SR 触发器与 RS 触发器的置位输入和复位输入在同
一条指令里,置位和复位输入谁在指令输入端的下面谁后执行。
SR 触发器为“置位优先”型触发器,当置位信号(SET1)和复位信号(RESET)同时为 1 时,
触发器最终为置位状态; RS 触发器为“复位优先”型触发器,当置位信号(SET)和复位信号
(RESET1)同时为 1 时,触发器最终为复位状态。置位优先 SR 与 RS 复位优先触发器指令参数如
表 6-x 所示,指令表详见 6-x。

表 6-x 置位优先 SR 与 RS 复位优先触发器指令


功能名 FB ST 说明
置位优 SR 置位优先触发器
先 SR 与
RS 复位
优先触
RS 复位优先触发器
发器

表 6-x 置位优先 SR 与 RS 复位触发器指令参数


名称 定义 数据类型 说明
SET1 输入变量 BOOL 置位优先命令
SET 输入变量 BOOL 置位命令
RESET1 输入变量 BOOL 复位优先命令
RESET 输入变量 BOOL 复位命令
Q1 输出变量 BOOL 输出
1. 置位优先触发器 SR
功能:置位双稳态触发器,置位优先。逻辑关系:Q1=(NOT RESET AND Q1) OR SET1 其中
SET1 为置位信号,RESET 为复位信号。
语法:当 SET1 为“1”时,不论 RESET 是否为“1”,Q1 输出都为“1”;当 SET1 为“0”
时,如果 Q1 输出为“1”,一旦 RESET 为“1”,Q1 输出立刻复位为“0”。如果 Q1 输出为
“0”,不论 RESET 为“1”或者“0”,Q1 输出保持为“0”。其时序图详见图 6.x 所示。

SET1 SET1 RESET Q1 输出


0 0 保持原状态
RESET 1 0 1
0 1 0
Q1 1 1 1

a) b)

图 6.x SR 置位优先触发器时序图
a) 时序图 b) 状态表
【例 6.X】某系统需要一个停机信号,并要求系统出现故障后要求马上停机,控制设备停机的
输出信号为 bStopMachine,如该变量被置位“1”,让需要让系统安全停机。否则可以正常运行。

表 6-x 变量分配表
变量名 说明
bRun 系统运行
bError 系统故障
bStopMachine 停机命令
图 6.x SR 置位优先触发程序举例
设备的运行信号为 bRun,当系统中如出现任一故障 bError 会被置位“1”。具体变量分配表见
表 6-x 所示,程序如图 6.x 所示,因为 bError 的优先权高于 bRun,故 bError 需要对应置位优先,只
有当没有故障时,bRun 为 ON 才有意义。
2. 复位优先触发器 RS
功能:复位双稳态触发器,复位优先。逻辑关系:Q1=NOT RESET1 AND (Q1 OR SET)其中
SET 为置位信号,RESET1 为复位信号。
语法:当 RESET1 为“1”时,不论 SET 是否为“1”,Q1 输出都为“0”;当 RESET1 为“0”
时,如果 Q1 输出为“0”,一旦 SET 为“1”,Q1 输出立刻置位为“1”。如果 Q1 输出为“1”,
不论 SET 为“1”或者“0”,Q1 输出保持为“1”。其时序图详见图 6.x 所示。

SET RESET1 Q1 输出
SET
0 0 保持原状态
RESET1 1 0 1
0 1 0
Q1 1 1 0

a) b)

图 6.x RS 复位优先触发器时序图
b) 时序图 b) 状态表

6.1.3 边沿检测指令

边沿检测指令用来检测 BOOL 信号的上升沿


(信号由 0---->1)和下降沿(信号由 1---->0)的 1 上升沿
变化,如图 6.x 所示。在每个扫描周期中把信号 下降沿
状态和它在前一个扫描周期的状态进行比较,若
不同则表明有一个跳变沿。因此,前一个周期里 0 TIME
的信号状态必须被存储,以便能和新的信号状态
相比较。边沿检测指令表详见 6-x。边沿检测指 图 6.x 边沿信号
令参数如表 6-x 所示。

表 6-x 边沿检测指令
功能名 图形化语言 文本化语言 说明
R_TRIG R_TRIG 上升沿检测

F_TRIG F_TRIG 下降沿检测

表 6-x 边沿检测指令参数
名称 定义 数据类型 说明
CLK 输入变量 BOOL 被检测信号输入
Q 输出变量 BOOL 触发器状态输出
1.上升沿检测 R_TRIG
功能:用于检测上升沿。
语法:当 CLK 从“0”变为“1”时,该上升沿检测器开始启动,Q 输出先由“1”然后输出变
为“0”,持续一个 PLC 运算周期;如果 CLK 持续保持为“1”或者“0”,Q 输出一直保持为
“0”。
采集 bInput 信号的上升沿,程序如图 6.x 所示,也可参考样例程序\R_TRIG\。

bInput

R_TRIG.Q
1 循环周期 1 循环周期

图 6.x 上升沿触发程序
图 6.x 上升沿触发数序图
【例 6.X】工业项目中,常会使用到报警显示,使用上升沿触发指令检测报警信号源,通过置
位复位功能控制报警显示,变量分配表见表 6-x 所示,程序如图 6.x 所示,也可参考样例程序
\AlarmTrig\。

表 6-x 变量分配表
变量名 说明 变量名 说明
bAlarm1 报警信号源 1 bAlarm4 报警信号源 4
bAlarm2 报警信号源 2 bReset 复位按钮
bAlarm3 报警信号源 3 bTowerLightRed 报警红色显示灯

图 6.x 报警显示复位程序举例

2. 下降沿检测 F_TRIG
功能:用于检测下降沿。
语法:当 CLK 从“1”变为“0”时,该下降沿检测器开始启动,Q 输出先由“1”然后输出变
为“0”,持续一个 PLC 运算周期;如果 CLK 持续保持为“1”或者“0”,Q 输出一直保持为
“0”。
【例 6.X】采集 bInput 信号的下降沿,当 bInput 由 True 变为 False 时,功能块 F_TRIG.Q 会根
据下降沿的触发事件给出相应输出,输出时间维持在一个周期。程序如图 6.x 所示,可参考样例程
序\F_TRIG\。

bInput

F_TRIG.Q
1 循环周期 1 循环周期
6.2 定时器指令
6.2.1 定时器

定时器采用 IEC61131-3 标准的定时器,分为脉冲定时器 TP、通电延时定时器 TON、断电延时


定时器 TOF 和实时时钟 RTC。定时器参数表详见 6-x。定时器特性时序图如图 6.x 所示。

表 6-x 定时器指令的图形化与文本化指令表
定时 图形化语言 文本化 说明
器指 语言

定时 TP 脉冲定时器

TON 通电延时定
时器

TOF 断电延时定
时器

RTC 实时时钟

表 6-x 定时器指令参数
名称 定义 数据类型 说明
IN 输入变量 BOOL 启动输入
PT 输入变量 TIME 延时时间
Q 输出变量 BOOL 定时器输出
ET 输出变量 TIME 当前定时时间

定时器时序图详见图 6.x 所示。


t t t

IN

TP.Q

TON.Q

TOF.Q t t t

图 6.x 定时器特性时序图

1. 脉冲定时器 TP
功能:脉冲定时。
语法:在定时器的输入端 IN 从“0”变为“1”时,定时器则启动,无论定时器输入端 IN 如何
变化,定时器的实际运行时间都是用户所定义的 PT 时间,在定时器运行时,其输出端 Q 的输出信
号为“1”。
输出端 ET 为输出端 Q 提供定时时间。定时从 T#0s 开始,到设置的 PT 时间结束。当 PT 时间
到时,ET 会保持定时时间直到 IN 变为“0”时。如果在达到 PT 定时时间之前输入 IN 已经变成
“0”,输入 ET 编程 T#0s,PT 定时的时刻。为了复位该定时器,只需要设置 PT=T#0s 即可。
【例 6.X】使用脉冲定时器 TP 制作一个指示灯闪烁程序,ON 维持时间为 1s,OFF 维持时间为
五秒。
程序中使用两个 TP 定时器,控制定时器 ON 维持 1s 的输入通过 OFF 定时器的输出信号取反作
为控制。变量分配表见表 6-x 所示,程序
如 图 6.x 所 示 , 也 可 参 考 样 例 程 序
\Sample_TP\。

表 6-x 变量分配表
变量名 说明
变量名 说明
DI_bStart 启动按钮
bTowerLightGreen 指示灯输出
DI_bStop 停止按钮
图 6.x 脉冲定时器 TP 程序举例 DI_bFuse1 M1 过载保护
2. 通电延时定时器 TON
功能:通电延时定时。
在定时器的输入端 IN 从“0”变为“1”时,定时器则启动,当到达定时时间 PT 且输入端的信
号 IN 始终维持在“1”时,其输出端 Q 的输出信号为“1”,如果在定时器的定时时间到达之前,
输入端 IN 信号由“1”变为“0”时,则定时器复位,下一个 IN 信号的上升沿定时器重启。
输出端 ET 提供定时时间,延时从 T#0s 开始,到设置的 PT 时间结束。PT 到达时,ET 将会保
持定时时间直到 IN 变为“0”为止。如果在达到 PT 定时时间之前,输入 IN 变为“0”,输出 ET
立即变为 T#0s。为了重启定时器,可以设置 PT=T#0s,也可以将 IN=FALSE。
【例 6.X】两台电动机 M1、M2,要求当启动时按下启动按钮 DI_bStart 后,M1 启动,20 秒后
M2 启动;当需要停车时按下停止按钮 DI_bStop,M2 停车,10 秒后 M1 停车。每台电动机都有过
载保护,当任一台电动机过载时,两台电动机同时停车。变量分配表见表 6-x 所示。

表 6-x 变量分配表
当按下启动按钮 DI_bStart 时,马上置 DO_KM_M1 为 DI_bFuse2 M2 过载保护
“1”,并通过自锁信号触发 M2 电机启动延时,达到 20s 后, DO_KM_M1 启动 M1
定时器 M2_StartDelay.Q 被置位“1”,通过此信号启动 M2 DO_KM_M2 启动 M2
电机。
当需要停止时,按下停止按钮 DI_bStop 后,置中间变量 bStopTemp 为“1”,且马上停止 M2
电机,并通过该中间变量启动 M1 电机的停止延时定时器 M1_StopDelay,到达设定时间 10s 后,
M1 也停止。程序如图 6.x 所示,也可参考样例程序\ MotorStartStopDelay\。

图 6.x 电机延时启动程序举例

3. 断电延时定时器 TOF
功能:断电延时定时。
在定时器的输入端 IN 从“0”变为“1”时,定时器的 Q 输出信号为“1”,定时器的启动输入
端变为“0”时,定时器则启动,只要当定时器在运行,其输出 Q 一直为“1”,当到达定时时间时,
输出端 Q 复位,在到达定时时间之前,如果定时器的输入端返回为“1”,则定时器复位,输出端
的 Q 输出信号保持为“1”。可参考图 6.x 中的 TOF 相关时序图。
输出端 ET 提供定时时间,延时从 T#0s 开始到设置的定时时间 PT 结束。当 PT 时间到时,ET
将保持定时时间直到输入 IN 返回“1”为止。如果在达到 PT 定时时间之前,输入 IN 变为“1”,
输出 ET 立即变为 T#0s。为了复位定时器,可以设置将 PT=T#0s。
【例 6.X】在车内灯光控制中,打开车门时,车内灯会点亮,即使关上车门 10 秒钟内,车内的
灯还会继续亮着,此种控制用的就是定时器断开延时动作模式。如下通过 PLC 程序实现此功能。
程序时序图如图 6.x 所示,当车门打开时,bDI_Door 门锁信号为“1”,关闭时为“0”。程序
如图 6.x 所示,变量分配表见表 6-x 所示。样例程序\TOF_CarIndoorLight\。

表 6-x 变量分配表
变量名 说明
bDI_Door 车门门锁信号
bDO_IndoorLight 车内灯
车门开关

车内灯 t t t

图 6.x 汽车车内灯控制程序时序图

4. 实时时钟 RTC
功能:在给定时间启动,返回当前日期和时间。
语法:RTC(EN, PDT, Q, CDT) 表示:当 EN 为 “0”,输出变量 Q 以及 CDT 为 “0”相关时
间为 DT#1970-01-01-00:00:00。一旦 EN 为“1”,PDT 给予的时间将会被设置,并且将会以秒进行
计数一旦 EN 为 TRUE 将返回 CDT 。一旦 EN 被复位为 FALSE, CDT 将会被复位为初始值
DT#1970-01-01-00:00:00。请注意,PDT 时间只上升沿有效。RTC 定时器参数表详见 6-x 所示。

表 6-x 标准定时器指令参数
名称 定义 数据类型 说明
EN 输入变量 BOOL 启动使能
PDT 输入变量 DATE_AND_TIME 设置将要启动的时间和日期
Q 输出变量 BOOL 状态输出
CDT 输出变量 DATE_AND_TIME 当前计数时间和日期的状态
【例 6.X】创建一个 POU,使用 RTC 指令,为其设定初始时间,并当 bEnable 变量 ON 后,返
回 ON 后的当前日期和时间。

图 6.x RTC 指令应用举例


程序如图 6.x 所示,也可参考样例程序\RTC_Timer\。
6.3 计数器指令
6.3.1 计数器简介

CoDeSys 标准功能库中提供了加、减计数功能块,系统提供了 CTU 加计数器、CTD 减计数器


和 CTUD 加减计数器三个功能块。

6.3.2 计数器指令

表 6-x 标准计数器的图形化与文本化指令表
计数器指 图形化语言 文本化语言 说明

计数器 CTU 增计数器

CTD 减计数器

CTUD 增/减计数器

表 6-x 标准计数器指令参数
名称 定义 数据类型 说明
CU 输入变量 BOOL 检测上升沿的信号输入触发输出 CV 递增
CD 输入变量 BOOL 检测上升沿的信号输入触发输出 CV 递减
RESET 输入变量 BOOL 复位计数器
LOAD 输入变量 BOOL 加载计数器
Q 输出变量 BOOL CV 递增到计数上限/0 时,输出 TRUE
QU 输出变量 BOOL CV 递增到计数上限 PV 时,则 QU 输出 TRUE
QD 输出变量 BOOL 输出 CV 递减到 0 时,则 QD 输出 TRUE
CV 输出变量 WORD 当前计数值
1. 增计数器 CTU
当计数器输入端 CU 的信号从状态“0”变为状态“1”时,当前计算值加 1,并通过输出端
CV 进行显示,第一次调用时(复位输入 RESET 信号状态为“0”),输入 PV 端的计数为默认值,
当计数达到上限 32767 后,计数器将不会再增加,CU 也不会再起作用。
当复位输入端 RESET 的信号状态为“1”时,计数器的 CV 和 Q 都为“0”,只要输入端
RESET 状态为“1”,上升沿对 CU 就不再起作用。当 CV 值大于或等于 PV 时,输出端 Q 为“1”。
此时 CV 仍可继续累加,输出端 Q 继续为输出“1” 。
增计数器 CTU 指令示例如图 6.x 所示,时序图如 6.x 所示。

图 6.x 增计数器 CTU 使用举例

bInput

2 2
1 1
0 0
CTU.CV
CTU.RESET

CTU.Q

图 6.x 增计数器 CTU 特性时序图


增量功能块。输入变量 CU 和复位 RESET 以及输出变量 Q 是布尔类型的,输入变量 PV 和输
出变量 CV 是 WORD 类型。
CV 将被初始化为 0 ,如果复位 RESET 是 TRU 真的。如果 CU 有一个上升沿从 FALSE 为
TRUE ,CV 提升 1,Q 将返回 TRUE,如此 CV 将大于或等于上限 PV。
【例 6.X】某工厂要实现每天的产量计数,每个产品出厂前都会经过流水线,流水线上有一个
光电传感器,当产品经过时,该信号会被置为“1”,示意图如图 6.x a)所示。通过计数器指令,
使用程序计算输出的总产量。

光电传感器

a) b)

图 6.x 增计数器 CTU 使用举例

b) 应用示意图 b)程序梯形图
表 6-x 变量分配表
变量分配表请见表 6-x,当流水线上有产品流经时,
变量名 说明
bDI_ConverySensor 的感应状态对应为“1”,无产品时为
bDI_ConverySensor 传输带传感器信号
“0”,故可直接使用此信号作为增计数器 CTU 的 CU 输入
bDI_Reset 计数器复位按钮
信号,当前实时值通过 nCurrentValue 进行显示。bDI_Reset
作为清零信号清除当前值。样例程序请参考 nCurrentValue 当前产品总数

\Counter_Convery\。

2.减计数器 CTD
当减计数器输入端的 CD 信号从“0”变为状态“1”时,当前计数值减 1,并在输出端上 CV
显示当前值,第一次调用时(需要将加载输入端信号 LOAD 初始化,需要将其从“0”变为状态
“1”,再变为状态“0”后功能块才能生效),输入 PV 端的计数为默认值,当计数达到 0 后,计
数值将不在会减少,CD 也不再起作用。
当加载输入端信号 LOAD 为“1”时,计数值将设定成 PV 默认值,只要加载输入端信号
LOAD 状态为“1”,输入端的 CD 上升沿就不起作用。当 CV 值小于或等于 0 时,输出端 Q 为
“1”。减计数器 CTD 指令示例如图 6.x 所示,时序图如 6.x 所示。

图 6.x 减计数器 CTD 使用举例

bInput

2
1
0
CTD.CV
CTD.LOAD

CTD.Q

图 6.x 减计数器 CTD 特性时序图


【例 6.X】某工厂生产的产品每 25 个可以装一箱,流经流水线后,每次满箱后,需要输出一个
3s 的延时指示 bPackingDone 信号,流水线上装有光电传感器,通过 bDI_ConverySensor 信号反馈给
PLC。此外需要统计当日生产的总箱数 nPackageQTY。

图 6.x 减计数器 CTU 程序举例

表 6-x 变量分配表
变 量 分 配 表 如 表 6-x 所 示 , 使 用 传 输 线 上 的
变量名 说明
bDI_ConverySensor 传感器信号作为 CTD 功能块的 CD 源信
bDI_ConverySensor 传输带传感器信号
号,PV 给定 25,当满 25 箱时 Counter_Down.Q 输出一个高
bPackingDone 满箱指示灯
电平脉冲作为满箱的 BOOL 信号。同时将此信号作为累计
nPackageQTY 当日生产总箱数
箱 数 的 Package_Counter 计 数 器 的 CU 源 信 号 ,
nPackageQTY 为当日的生产总箱数。满箱指示灯通过使用 TP 功能块做延时输出。样例程序请参考
\CTU_Packing\。
3. 增/减双向计数器 CTUD
当加计数输入端的 CU 信号从“0”变为状态“1”时,当前计数值加 1,并在输出 CV 上线时。
当减计数输入端的 CD 的信号状态从“0”变为状态“1”时,当前计数值减 1,并在输出端 CV 上
显示。如果两个输入端都是上升沿,当前计数值将保持不变。
当计数值达到上限值 32767 后,加计数输入端 CU 的上升沿不再起作用。因此即使加计数输入
端 CU 出现上升沿,及数值也不会增加。同理,当计数值达到下极限值 0 后,减计数输入端 CD 也
不会在其作用,因此,即使减计数输入端 CD 出现上升沿,计数值也不会减少。
当 CV 值大于或等于 PV 值时,输出 QU 为“1”。当 CV 值小于或等于 0 时,输出 QD 为“1”。

【例 6.X】创建一个 POU,使用增/减双向计
数器 CTUD,当 bUp 有上升沿信号时,计数值增
加 , bDown 有 上 升 沿 信 号 时 , 计 数 值 减 小 。
bReset 用于数据复位,具体代码如下。
VAR
bUp: BOOL;
bDown: BOOL;
bReset: BOOL;
bLoad: BOOL;
CTUD_0: CTUD;
END_VAR

CTUD_0(CU:= bUp,CD:=
bDown,RESET:=bReset ,LOAD:= bLoad,
PV:= ,QU=> ,QD=> ,CV=> );

图 6.x 增/减计数器 CTUD 使用举例


【例 6.X】一自动仓库存放某种货物,最多 6000 箱,需对所存的货物进出计数,货物多于
1000 箱,灯 L1 亮;货物多余 5000 箱,灯 L2 亮。进货的输入信号为 bInput,出货对应输入信号为
bOutput。具体详见表 6-x 的变量分
配表。

表 6-x 变量分配表
变量名 说明
bInput 进货
bOutput 出货
nL1Value 数值 1000
nL2Value 数值 5000
L1 多于 1000 指示灯
L2 多于 5000 指示灯

使用 CTUD 指令,当进货时,
bInput 连接双向计数器的 CU 信号
进 行数 值累加 ,出 货时, bOutput
连接双向计数器的 CD 信号进行数
值递减。当前数值用 FB_CTUD.CV
进行表示。输出采用比较指令,如
当前计数数值大于 nL1Value,L1
为 ON,大于 nL2Value,L2 为 ON。
程序举例详见图 6.x 所示,样例程
序请参考\AutoWarehouse\。

图 6.x 自动仓库进出货计数功能举例
6.4 数据处理指令
CoDeSys 标准功能库中所提供数据处理指令包括选择操作指令、比较指令和移位指令等,下文
会对各部分的指令进行详细说明。

6.4.1 选择操作指令

在实际的应用中常会用到一些数据的选择和筛选,在选择操作指令中会介绍几种常用的指令供
读者在将来的实际应用中提供便利,常用选择操作指令如表 6-x 所示。

表 6-x 选择操作指令的图形化与文本化指令表
选择操作指令 图形化语言 文本化语言 说明
选择操作指令 SEL 二选一指令

MAX 取最大值

MIN 取最小值

LIMIT 限制值

MUX 多选一

1. 二选一指令 SEL
功能:通过选择开关,在两个输入数据中选择一个作为输出,选择开关为 FALSE 时,输出为
第一个输入数据,选择开关为 TRUE 时,输出为第二个数据。
语法:其文本化语言语法格式如下,
OUT := SEL(G, IN0, IN1)
参数 G 必须是布尔变量。如果 G 是 FALSE,则返回值的结果是 IN0, 如果 G 是 TRUE ,则返
回值的结果为 IN1,其参数说明详见表 6-x 所示。

表 6-x 二选一指令 SEL 参数说明


名称 定义 数据类型 说明
G 输入变量 BOOL 输入选择位
IN0 输入变量 任何类型 输入数据 0
IN1 输入变量 任何类型 输入数据 1
返回值 输出变量 任何类型 输出数据
【例 6.x】创建一个 POU,当输入值 bInput 为 FALSE,输出为 3,反之,当其为 TRUE 时,输
出为 4,具体实现程序如下。
VAR
iVar1:INT:=3;
iVar2:INT:=4;
iOutVar: INT;
bInput: BOOL;
END_VAR

iOutVar:=SEL(bInput,iVar1,iVar2);
2. 取最大值 MAX
功能:最大值函数。在多个输入数据中选择最大值作为输出。
语法:其文本化语言语法格式如下所示,
OUT := MAX(IN0, …,INn)
其参数说明详见表 6-x 所示。

表 6-x 取最大值 MAX 参数说明


名称 定义 数据类型 说明
IN0 输入变量 任何类型 输入数据 0
INn 输入变量 任何类型 输入数据 n
返回值 输出变量 任何类型 输出数据
【例 6.x】创建一个 POU,iOutVar 的输入值为 iVar1 和 iVar2 中的较大者,具体实现程序如下。
VAR
iVar1:INT:=30;
iVar2:INT:=60;
iOutVar: INT;
END_VAR

iOutVar:=MAX(iVar1,iVar2);
程序运行后输出结果为 60。
3. 取最小值 MIN
功能:最小值函数。在多个输入数据中选择最小值作为输出。
语法:其文本化语言语法格式如下所示,
OUT := MIN(IN0, …,INn)
IN0, INn 以及 OUT 可以是任何数据类型,其参数说明详见表 6-x 所示。

表 6-x 取最小值 MIN 参数说明


名称 定义 数据类型 说明
IN0 输入变量 任何类型 输入数据 0
INn 输入变量 任何类型 输入数据 n
返回值 输出变量 任何类型 输出数据
【例 6.x】创建一个 POU,iOutVar 的输入值为 iVar1 和 iVar2 中的较小者,具体实现程序如下。
VAR
iVar1:INT:=30;
iVar2:INT:=60;
iOutVar: INT;
END_VAR

iOutVar:=MIN(iVar1,iVar2);
程序运行后输出结果为 30。
4.限制值 LIMIT
功能:限制值输出。判断输入数据是否在最小值和最大值之间,若输入数据在两者之间,则直
接把输入数据作为输出数据进行输出。若输入数据大于最大值,则把最大值作为输出值。若输入数
据小于最小值,则把最小值作为输出值。
语法:其文本化语言语法格式如下,
OUT := LIMIT(Min, IN, Max)
IN, Min ,Max 以及返回值可以是任何数据类型,其参数说明详见表 6-x 所示。

表 6-x 限制值 LIMIT 参数说明


名称 定义 数据类型 说明
Min 输入变量 任何类型 输入数据 0
IN 输入变量 任何类型 输入数据 n
Max 输入变量 任何类型 输入数据 n
返回值 输出变量 任何类型 输出数据
【例 6.x】创建一个 POU,使用限制值指令,无论输入为何值,确保输出值在能在 30~80 的
范围内。具体实现程序如下。
VAR
iVar:INT:=90;
iOutVar: INT;
END_VAR

iOutVar:=limit(30,iVar,80);
最小值输入值为 30,最大值输入值为 80,实际输入值为 90,大于最大值,故最终输出以最大
值 80 为输出,故最终结果为 80。
5. 多选一 MUX
功能:多路器操作。通过控制数在多个输入数据中选择一个作为输出。
语法:其文本化语言语法格式如下,
OUT := MUX(K, IN0,...,INn)
IN0,...,INn 以及 返回值可以是任何变量类型。但是 K 必须为 BYTE, WORD, DWORD, LWORD,
SINT, USINT, INT, UINT, DINT, LINT, ULINT 或者 UDINT。 MUX 从变量组中选择第 K 个数据输
出。其参数说明详见表 6-x 所示。

表 6-x 多选一 MUX 参数说明


名称 定义 数据类型 说明
K 输入变量 整数类型 控制数
IN0 输入变量 任何类型 输入数据 0
INn 输入变量 任何类型 输入数据 n
返回值 输出变量 任何类型 输出数据
【例 6.x】创建一个 POU,使用多选一指令,根据输入控制数 iVar 选择最终要输出的数据。具
体实现程序如下。
VAR
iVar:INT:=1;
iOutVar: INT;
END_VAR

iOutVar:=MUX(iVar,30,40,50,60,70,80);
最终输出结果为 40,因为数据排序是从第 0 个元素开始累积。
如果数据超出范围,最数据按最后一个数据为输出,如例 6.x 中,将 iVar 的值设定为 10,最终
的输出结果为 80。如果 iVar 为-1,最终输出值还是为 80。
6.4.2 比较指令

比较指令用于两个相同数据类型的有符号数或无符号数 IN1 和 IN2 的比较判断操作。涉及到的


运算有: = ,>=,<=,>,<,<>在图形化语言中,比较指令是以动合触点的形式编程的,
在动合触点的中间注明比较参数和比较运算符。当比较的结果为真时,该动合触点闭合;在文本化
语言中,比较指令可以用符号直接表示,当比较结果为真时, PLC 将运算结果置 True。比较指令
的图形化及文本化指令的表现形式见表 6-x。

表 6-x 比较指令的图形化及文本化指令表
比较指令 图形化语言 文本化语言 说明
比较指令 = 相等

<> 不等

> 大于

>= 大于等于

< 小于

<= 小于等于

【例 6.X】某风力发电设备需要对发电机温度进行实时监控,要求程序能够当发电机温度大于
等于 90 摄氏度,并且时间维持在 1min 以上,发出发电机过热警告;当温度小于等于 60 摄氏度,
且时间维持在 1min 以上,发出发电机温度过低警告。变量分配表如表 6-x 所示。
表 6-x 变量分配表
变量名 说明
程 序 通 过 GE 与 LE 指 令 对 输 入 温 度
AI_rGenTemperature 进行比较。输出结果直接赋值给
AI_rGenTemperaturer 发电机温度
定时器的输入端 IN。程序如图 6.x 所示,样例程序请
bTempHighAlarm 温度过高报警
参考\Temp_CMP\。
bTempHighAlarm 温度过低报警
图 6.x 发电机温度报警程序举例

6.4.3 移位指令

移位操作指令是 CeDeSys 中经常使用的指令,它分为按位移位指令,循环移位指令两大类。其


功能为将操作数的所有位按操作指令规定的方式移动 1 位 n 次移动,将其结果送入返回值。移位指
令表的图形化及文本化指令表详见表 6-x 所示。

表 6-x 移位指令的图形化及文本化指令表
移位指令 图形化语言 文本化语言 说明
移位指令 SHL 按位左移

SHR 按位右移

ROL 循环左移

ROR 循环右移
1. 按位左移 SHL
功能:对操作数进行按位左移,左边移出位不做处理,右边空位自动补 0。
语法:指令可以将输入 IN 中的数据左移 n 位,输出结果赋值至 OUT,二进制数左移一位相当
于将原数乘以 2。如果 n 大于数据类型宽度,BYTE, Word 和 DWORD 值将填补为零。文本化语
言语法格式如下所示,
OUT:= SHL (IN, n)
【例 6.x】利用了按位左移指令完成 WORD 类型输入变量 wWord1 当前值左移 4 位,程序如
6.x 所示,样例程序请参考\SHL\。

图 6.x 按位左移程序举例

图 6.x 按位左移 4 位过程


如上,wWord1 为 16 进制的 0001,经过按位向左移动 4 位后,最终输出结果为 16#0010。其过
程见图 6.x。低 4 位的空位补 0。
移位运算的总位数会受到输入变量的数据类型的影响。如果输入变量是常量,将会取长度最小
的数据类型。而输出变量的数据类型则不会对算术运算产生影响,通过如下例子鉴别两者的区别。
【例 6.x】请比较下面 16 进制数的按位左移的运算,尽管 byte 和 word 形式的输入变量值相等,
但根据输入变量的数据类型不同(BYTE 或 WORD),erg_byte 和 erg_word 将得到不同的结果。
VAR
in_byte : BYTE:=16#45;
in_word : WORD:=16#45;
erg_byte : BYTE;
erg_word : WORD;
n: BYTE :=2;
END_VAR

erg_byte:=SHL(in_byte,n); (* 结果为 16#14 *)


erg_word:=SHL(in_word;n); (* 结果为 16#0114 *)
图 6.x BYTE 与 WORD 变量按位左移比较
当 BYTE 类型变量 b6 和 b7 位左移 2 位后溢出,最终的数据为 16 进制的 14。而当 WORD 类型
变量的 b6 和 b7 位左移两位后,进入高字节的 b8 和 b9 位,该位会继续保留,最终的结果为 16 进
制的 114。其过程见图 6.x 所示。
2. 按位右移 SHR
功能:对操作数进行按位右移,右边移出位不做处理,左边空位自动补 0。
语法:指令可以将输入 IN 中的数据右移 n 位,输出结果赋值至 OUT,二进制数右移一位相当
于将原数除以 2。如果 n 大于数据类型宽度, BYTE, Word 和 DWORD 值将填为零。如果使用带
符号数据类型,则算术移位将按最高位补充数。其文本化语言语法格式如下所示,
OUT:= SHR (IN, n)
【例 6.x】利用按位右移指令完成 WORD 类型输入变量 wWord1 的当前值右移 5 位,输出结果
赋值给 wWord2,程序如 6.x 所示,样例程序请参考\SHR_WORD\。

图 6.x 按位右移程序举例

图 6.x 按位右移 5 位过程


如上,wWord1 为 16 进制的 0100,经过向右移动 5 位后,最终输出结果为 16#0008。由于
WORD 类型变量属于无符号数据类型,有效值从 0~65535,故右移 5 位后,没有符号位,高 5 位
补 0,移位过程如图 6.x 所示。
例 6.x 为无符号位的数据右移,如遇到有符号整型数据,高位右移需要补符号位。如下例 6.x
所示。
【例 6.x】利用按位右移指令完成 INT 类型输入变量 iINT1 的当前值右移 4 位,输出结果赋值
给 iINT2,程序如 6.x 所示,样例程序请参考\SHR_INT\。

图 6.x 带符号位的按位右移程序举例

图 6.x 带符号位的按位右移 4 位过程


如上,由于 INT 为有符号位数据,有效值为-32768~32767,iINT1 为 16 进制有符号数据 F100,
最高位 b15 为符号位,经过向右移动 4 位后,需要补数据,由于源数据符号位为 1,故高 4 位补 4
个 1,故程序运行最终结果为 16#FF10,具体移位过程如图 6.x 所示。
3. 循环左移 ROL
功能:对操作数进行按位循环左移,左边移出的位直接补充到右边的最低位。
语法:允许的数据类型:BYTE、WORD、DWORD,使用该指令可以将输入 IN 中的全部内容
循环的逐位左移,空出的位用移出位的信号状态填充。输入参数 n 提供数值表示循环移动的位数,
OUT 是循环移位的操作结果。其文本化语言语法格式如下所示,
OUT:= ROL (IN, n)
【例 6.x】创建一个 POU,试对比按位左移和循环左移的区别,将 16 进制 WORD 型变量
wWord1 分别采用两种不同的左移方式移动同样的位数,试比较结果。

图 6.x 按位左移循环左移比较程序举例

图 6.x 循环左移 4 位程序举例


通过例 6.x 不难看出,使用循环右移后的输出 wWord3 的 b0~b3 位并不是将空位补 0,而是将
输入数据 wWord1 中的 b12~b15 中的 1010 补到 b0~b3 位,其详细过程详见 6.x 图示。
循环移位指令的总位数同样也会受到输入变量的数据类型的影响。如果输入变量是常量,将会
取长度最小的数据类型。而输出变量的数据类型则不会对算术运算产生影响,通过如下例子鉴别两
者的区别。
【例 6.x】请比较下面 16 进制数的循环左移的运算,尽管 byte 和 word 形式的输入变量值相等,
但根据输入变量的数据类型不同(BYTE 或 WORD),erg_byte 和 erg_word 将得到不同的结果。
VAR
in_byte: BYTE:=16#45;
in_word: WORD:=16#45;
erg_byte : BYTE;
erg_word : WORD;
n: BYTE :=2;
END_VAR

erg_byte:=ROL(in_byte,n); (* 结果为 16#15 *)


erg_word:=ROL(in_word,n); (* 结果为 16#0114 *)
图 6.x BYTE 与 WORD 变量循环左移比较
如图 6.x 所示,当 BYTE 类型变量的 b6,b7 位左移 2 位后移至输出数据中的 b0 和 b1 位,最终
的数据为 16 进制的 15。而当 WORD 类型变量的 b6,b7 位左移两位后,移至输出数据中的 b8 和
b9 位,原数据的 b14 和 b15 位为 0,左移后,移至输出数据的 b0 和 b1 位,故最终的结果为 16 进
制的 114。
4. 循环右移 ROR
功能:对操作数进行按位循环右移,右边移出的位直接补充到左边最高位。
语法:允许的数据类型:BYTE、WORD、DWORD。使用该指令可以将输入 IN 中的全部内容
循环的逐位右移,空出的位用移出位的信号状态填充。输入参数 n 提供数值表示循环移动的位数,
OUT 是循环移位的操作结果,其文本化语言语法格式如下所示,
OUT: = ROR (IN, n)
【例 6.x】利用循环按位右移指令完成 WORD 类型输入变量 wWord1 的当前值循环右移 5 位,
输出结果赋值给 wWord2,程序如 6.x 所示,样例程序请参考\ROR_WORD\。

图 6.x 循环按位右移程序举例

图 6.x 循环按位右移 5 位过程


最终程序的运行结果为 16 进制的 1008,程序将原来 wWord1 的低 5 位 b0~b4 移至 wWord2 中
的 b11~b15。
【例 6.x】利用循环右移指令,设计一个 16 位的闪灯程序,按 2s 的频率逐一向右闪烁。

图 6.x 循环按位右移闪灯程序
通过通电延时定时器的输出每 2 秒触发一次指令循环右移指令,样例程序请参考\ROR_LIGHT\。
6.5 运算指令
运算指令针对操作数进行运算,同时产生运算结果。运算指令是一种专门处理数据运算的特殊
符号,数据变量结合的运算指令形成完整的程序运算语句。本节会针对 CoDeSys 中常用的运算指
令做详细介绍,包括赋值指令、算术运算指令、数学运算指令和地址运算指令。

6.5.1 赋值指令

赋值指令是 CoDeSys 中最常用的指令,在实际应用中,他实现的功能是将一个变量的数据传


送给另外一个变量中。
1. 赋值指令 MOVE
功能:将一个常量或者变量的值赋给另外一个变量,也是 CoDeSys 中最常用的指令,赋值指
令表的图形化及文本化指令表详见表 6-x 所示。

表 6-x 赋值指令的图形化及文本化指令表
赋值指令 图形化语言 文本化语言 说明
赋值指令 := 赋值

【例 6.x】创建一个 POU,将 WORD 变量 nVar1 中的数据赋值至 nVar2 中,具体实现程序如下。

图 6.x MOVE 指令程序举例


如使用文本化指令,实现例 6.x 中的代码为:
nVar2:=nVar1;

6.5.2 算术运算指令

+、-、*、/、MOD 运算指令都算算术运算指令,分别用于进行加、减、乘、除和求余数运算。
下面对这几种算术运算指令进行详细的讲解。其指令详细详见表 6-x 所示。

表 6-x 算术运算指令的图形化及文本化指令表
算术运算指令 图形化语言 文本化语言 说明
算术运算指令 + 相加

- 相减
* 相乘

/ 相除

MOD 取余数

1. 加法运算 ADD
功能:加法运算指令,两个(或者多个)变量或常量相加。两个时间变量也可相加,结果是另
一个时间变量。
语法:指令可以将输入变量 IN0 的值直至 INn 的值做加法运算,将其结果赋值至 OUT。加法
运算指令支持如下的变量类型,BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、(L)REAL、TIME 和常数。其文本化语言语法格式如下所示,
OUT := IN0 +…+INn
【例 6.x】创建一个 POU,声明两个整型变量 iVar1 和 iVar2,并将 iVar1 赋值为 2014,然后使
iVar2 的值为 iVar1 与 iVar1 相加后的值,具体代码如下。
VAR
iVar1:INT:=2014;
iVar2:INT;
END_VAR

iVar2:=iVar1+iVar1;
程序的运行结果为 iVar2 等于 4028。
【例 6.x】在实际工程中,经常需要记录操作的次数,使用 ST 程序语言,当数字累加到 10 时,
将该累计变量清零。
如下为使用 ST 语言的程序实现。通过上升沿触发功能块对被加数 iCounter 进行累加。
VAR
bCalStart: BOOL;
FB_StartTrigR_TRIG:R_TRIG;
iCounter:word;
END_VAR

FB_StartTrigR_TRIG(CLK:=bCalStart);
IF FB_StartTrigR_TRIG.Q THEN
iCounter:=iCounter+1;
END_IF
IF iCounter=10 THEN
iCounter:=0;
END_IF
样例程序请参考\ADD\。
注意:
TIME 型变量也可使用加法功能,两个 TIME 变量相加得到一个新的时间。
例 :t#45s + t#50s = t#1m35 s。
被选择的输出数据类型应可存储输出结果,否则可能引起数据错误。
2. 减法运算 SUB
功能:减法运算指令,两个变量或常量相减。
语法:指令可以将输入变量 IN0 的减去 IN1 的值,将其结果赋值至 OUT。减法运算指令支持
如下的变量类型,BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、UDINT、
REAL、(L)REAL、TIME 和常数。其文本化语言语法格式如下所示,
OUT := IN0 –IN1
【例 6.x】创建一个 POU,声明两个浮点数变量 rVar1 和 rVar2,分别赋值 3.14 和 10,此外再
声明一个 rResult 变量,将其值为 rVar2 减去 rVar1 之后得到的值,具体代码如下。
VAR
rVar1:REAL:=3.14;
rVar2:REAL:=10;
rResult:REAL;
END_VAR

rResult:=rVar2-rVar1;
程序的运行结果为 rResult 等于 6.86。
注意:
TIME 型变量也可使用减法功能,两个 TIME 变量相减得到一个新的时间。
例 :t#1m35s - t#50s = t#45s ,但时间结果不能有负值。
TOD 型变量也可使用减法功能,两个 TOD 型相减得到一个新的 TIME 型数据。
例 :TOD#45:40:30- TOD#22:30:20=T#1390m10s0ms ,但时间结果不能有负值。

3. 乘法运算 MUL
功能:乘法运算指令,两个(或者多个)变量或常量相乘。
语法:指令可以将输入变量 IN0 的值直至 INn 的值做乘法运算,将其乘积赋值至 OUT。乘法
运算指令支持如下的变量类型,BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、(L)REAL、TIME、TOD 和常数。其文本化语言语法格式如下所示,
OUT := IN0 *…*INn
【例 6.x】创建一个 POU,声明两个整形变量 iVar1 和 iVar2,并分别赋值为 10 和 2,再声明
一个整型变量 iResult,使其结果为 iVar1 和 iVar2 的乘积,具体实现代码如下。
VAR
iVar1:INT:=10;
iVar2:INT:=2;
iResult:INT;
END_VAR

iResult:=iVar1*iVar2;
程序的运行结果为 iResult 等于 20。
4. 除法运算 DIV
功能:除法运算指令,两个变量或常量相除。
语法:指令可以将输入变量 IN0 的除以 IN1 的值,将其得到商值赋值至 OUT。除法运算指令
支持如下的变量类型,BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、UDINT、
REAL、LREAL 和常数。其文本化语言语法格式如下所示,
OUT := IN0 / IN1
【例 6.x】创建一个 POU,声明两个整型变量 iVar1 和 iVar2,并分别赋值为 10 和 2,再声明
一个整型变量 iResult,使其值为 iVar1 除以 iVar2 得到的值,具体实现代码如下。
VAR
iVar1:INT:=10;
iVar2:INT:=2;
iResult:INT;
END_VAR

iResult:=iVar1/iVar2;
程序的运行结果为 iResult 等于 5。
注意:
在 工 程 中 使 用 DIV 指 令 时 , 可 使 用 CheckDivByte 、 CheckDivWord 、 CheckDivDWord 和
CheckDivReal 等指令检查除数是否为零,避免了除数为零的现象

5. 求余数运算 MOD
功能:变量或常量相除取余,结果为两数相除后的余数,是一个整型数据。
语法:求余数运算指令 MOD 指令可以将输入变量 IN0 与 IN1 相除的余数赋值给 OUT,通常使
用该运算指令创建余数在特定范围内的等式。求余数运算指令支持如下的变量类型, BYTE、
WORD、DWORD、SINT、USINT、INT、UINT、DINT、UDINT、REAL、LREAL 和常数。其文
本化语言语法格式如下所示,
OUT := IN0 MOD IN1;
【例 6.x】创建一个 POU,声明两个整型变量 iVar1 和 iVar2,并分别赋值为 44 和 9,再声明
一个整型变量 iResult,使其值为 iVar1 与 iVar2 求余运算之后的值,具体实现代码如下。
VAR
iVar1:INT:=44;
iVar2:INT:=9;
iResult:INT;
END_VAR

iResult:=iVar1 MOD iVar2;


程序的运行结果为 iResult 等于 8。

6.5.3 数学运算指令

数学运算指令包括三角函数运算指令,高级算术指令,相关指令表如表 6-x 所示。

表 6-x 数学运算指令的图形化及文本化指令表
数学运算指令 图形化语言 文本化语言 说明
数学算术运算 ABS 绝对值指令
指令

SQR 平方根指令

EXP 指数指令

LN 自然对数指令

LOG 常用对数指令

SIN 正弦指令

COS 余弦指令

ACOS 反余弦指令
ASIN 反正弦指令

TAN 正切指令

ATAN 反正切指令

1. 绝对值 ABS
功能:这个函数指令是用来计算一个数的绝对值,与正负号数符号没有关系。
语法:绝对值运算指令支持如下的变量类型,BYTE、WORD、DWORD、SINT、USINT、
INT、UINT、DINT、UDINT、REAL、LREAL 和常数。其文本化语言语法格式如下所示,
OUT := ABS (IN);
【例 6.x】ABS 函数示例。
VAR
iVar1:INT:=-44;
iResult:INT;
END_VAR

iResult:=abs(iVar1);
程序的运行结果为 iResult 等于 44。
2. 平方根 SQRT
功能:非负实数的平方根。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := SQRT(IN);
【例 6.x】SQRT 函数示例。
VAR
rVar1:REAL:=16;
rResult:REAL;
END_VAR

rResult:=SQRT(rVar1);
程序的运行结果为 rResult 等于 4。
3. 指数函数 EXP
功能:返回 e(自然对数的底)的幂次方,e 是一个常数为 2.71828 的数。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := EXP(IN);
【例 6.x】EXP 函数示例。
VAR
rVar1:REAL:=2;
rResult:REAL;
END_VAR

rResult:=EXP(rVar1);
程序的运行结果为 rResult 等于 7.389056。
4. 自然对数 LN
功能:返回一个数的自然对数。自然对数以常数项 e (2.71828182845904) 为底。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := LN (IN);
【例 6.x】LN 函数示例。
VAR
rVar1:REAL:=45;
rResult:REAL;
END_VAR

rResult:=LN(rVar1);
程序的运行结果为 rResult 等于 3.80666。
5. 10 为底的对数 LOG
功能:返回底为 10 数的对数。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := LOG(IN);
【例 6.x】LOG 函数示例。
VAR
rVar1:REAL:=314.5;
rResult:REAL;
END_VAR

rResult:=LOG(rVar1);
程序的运行结果为 rResult 等于 2.49762。
6. 正弦函数 SIN
功能:正弦函数。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := SIN(IN);
【例 6.x】SIN 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:=SIN(rVar1);
程序的运行结果为 rResult 等于 0.479426。
【例 6.x】下列程序中通过算术指令完成某角度的正弦值运算。在使用三角函数指令之前先将
角度值换算成弧度值,然后再用 SIN 指令求正弦值。程序如图 6.x 所示。

图 6.x 正弦 SIN 指令程序示例

7. 余弦函数 COS
功能:余弦函数。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := COS(IN);
【例 6.x】COS 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:=COS(rVar1);
程序的运行结果为 rResult 等于 0.877583。
8. 反余弦函数 ACOS
功能:余弦弧度(反余弦函数)。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := ACOS(IN);
【例 6.x】ACOS 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:=ACOS(rVar1);
程序的运行结果为 rResult 等于 1.0472。
9. 反正弦函数 ASIN
功能:正弦弧度(反正弦函数)。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := ASIN(IN);
【例 6.x】ASIN 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:=ASIN(rVar1);
程序的运行结果为 rResult 等于 0.523599。
10. 正切函数 TAN
功能:正切函数。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := TAN(IN);
【例 6.x】TAN 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:= TAN (rVar1);


程序的运行结果为 rResult 等于 0.546302。
11. 反正切函数 ATAN
功能:正切弧度(反正切函数)。
语法:输入变量 IN 可以是 BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、LREAL 和常数,但输出必须是 REAL 或 LREAL 类型。其文本化语言语法格式如
下所示,
OUT := ATAN(IN);
【例 6.x】ATAN 函数示例。
VAR
rVar1:REAL:=0.5;
rResult:REAL;
END_VAR

rResult:= ATAN (rVar1);


程序的运行结果为 rResult 等于 0.463648。

6.5.4 地址运算指令

在实际应用中,有很多情况涉及到内存地址的指令,比如取数组的内存首地址,需要了解该数
组在内存中占了多少个字节等相关信息,所涉及的指令在本节会一一介绍。

表 6-x 地址运算指令的图形化及文本化指令表
选择运算指令 图形化语言 文本化语言 说明
选择运算指令 SIZEOF 数据类型大小

ADR 地址操作符

BITADR 位地址操作符

1. 数据类型大小 SIZEOF
功能:执行这个功能以确定给出的数据类型所需要的字节数量。简单的说其作用就是返回一个
对象或者类型所占的内存字节数。
语法:SIZEOF 的返回值的是一个无符号值,类型的返回值将会被用于查找变量 IN0 的大小,
OUT 输出值的单位为字节,IN0 可以为任何数据类型。其文本化语言语法格式如下所示。返回值的
类型是隐式数据类型,它会根据实际数据值来决定,具体详见表 6-x 所示。
OUT := SIZEOF(IN0);

表 6-x SIZEOF 的返回数据类型


SIZEOF 的返回值 X 隐式数据类型
0 <= size of x < 256 USINT
256 <= size of x < 65536 UINT
65536 <= size of x < 4294967296 UDINT
4294967296 <= size of x ULINT
【例 6.x】使用 SIZEOF 指令取数组占用内存大小的举例,程序如下所示。
ST 语言的示例: IL 语言的示例:
VAR
arr1:ARRAY[0..4] OF INT;
var1:INT;
END_VAR

var1 := SIZEOF(arr1);
程序将结果赋值给 var1,最终 var1 等于 10,因为 arr1 数组共由 5 个 INT 整型元素构成,
SIZEOF 的结果单元为 BYTE,故最终程序运行结果为共有 10 个 BYTE,表示 arr1 占用 10 个字节
的内存。
2. 地址操作符 ADR
功能:取得输入变量的内存地址,并输出。该地址可以在程序内当作指针使用,也可以作为指
针传递给函数。
语法:ADR 操作符其返回值为一个 DWORD 的地址变量,IN0 可以为任何数据类型。其文本
化语言语法格式如下所示,
OUT :=ADR(IN0);
ADR 的返回值仅是变量的内存地址。该内存地址可以存放的数据长度为 1 个 BYTE。可以通过
内容操作符“^” 提取对应地址中的内容,如需获取 var_int1 的内存地址,将其地址赋值给指针变
量,再将其对应地址中的具体内容通过“^”操作符提取出来并赋值给 var_int2。实现程序如下所示,
pt := ADR(var_int1);
var_int2:= pt^;
【例 6.x】使用 ADR 指令取数组的举例,程序如下所示。
ST 语言的示例: IL 语言的示例:
VAR
arr1:ARRAY[0..4] OF INT;
dwVar:DWORD;
END_VAR

dwVar:=ADR(arr1);

【例 6.x】使用 ADR 指令取数组的举例,程序如下所示。ADR 指令


ST 语言的示例:
VAR
arr1:ARRAY[0..4] OF INT;
dwVar:DWORD;
END_VAR

dwVar:=ADR(arr1);

【例 6.x】使用 ADR 指令取数组的举例,程序如下所示。


ST 语言的示例:
pt:POINTER TO INT;
var_int1:INT;
var_int2:INT;
pt := ADR(var_int1);
var_int2:=pt^;

3. 位地址操作符 BITADR
功能:返回分配变量的位地址信息偏移量。
语法:BITADR 操作符其返回值为一个 DWORD 的地址变量,IN0 可以为任何数据类型。其文
本化语言语法格式如下所示,
OUT :=BITADR(IN0);
ADR 的返回值仅是变量的内存地址。该内存地址可以存放的数据长度为 1 个 BYTE。可以通过
内容操作符“^” 提取对应地址中的内容,如需获取 var_int1 的内存地址,将其地址赋值给指针变
量,再将其对应地址中的具体内容通过“^”操作符提取出来并赋值给 var_int2。实现程序如下所示,
BITADR 以 DWORD 变量类型返回位偏移数值地址。注意偏移值取决于选项类型地址是否可以
从目标系统中获得。DWORD 最大值定义内存区域如表 6-x 所示:

表 6-x BITADR 各地址区偏移地址


地址区 起始地址 说明
Memory 16x40000000 %M
Input 16x80000000 %I
Output 16xC0000000 %Q
【例 6.x】使用 BITADR 指令取位地址信息的举例,程序如下所示。
ST 语言的示例: IL 语言的示例:
VAR
var1 AT %IX2.3:BOOL;
bitoffset: DWORD;
END_VAR

bitoffset:=BITADR(var1);

运行结果为 16 进制的 80000013, %IX2.3 中的“2”为 2 个


Byte,“.3”为第 4 个 Bit,所以其地址等于 2*8+4=20。将 10 进
制的 20 转换为 16 进制的 14。又因为对应 I 区的首地址是从
80000000 开始存放的,故不难理解,16 进制的 14 对应的实际地
址是 16#80000013。示意图如图 6.x 所示。

图 6.x BITADR 示例说明

6.6 数据转换指令

6.6.1 数据类型转换指令

语法:<TYPE1>_TO_<TYPE2>
严禁将“较大的”数据类型隐含地转换为“较小的”数据类型使用,因当从较大数据类型转为
较小数据类型时,有可能丢失信息。
如被转换的值超出目标数据类型的存储范围,则这个数的高字节将被忽略。例:将 INT 类型转
换为 BYTE 类型,或将 DINT 类型转换为 WORD 类型。
<TYPE>_TO_STRING 的转换中,字符串是从左边开始生成的。如果定义的字符串长度小于
<TYPE>的长度,右边部分会被截去。
1. BCD 码与整型数据相互转换
BCD(Binary Coded Decimal…BCD)即用 4 位 2 进制数来并列表示 10 进制数中各个位数的值。
例如,BIN 数据中按照如图 6.x 方式用 BCD 数据 0000 0001 0101 0111(343)来表示 10 进制数
“157”。

图 6.x BCD 示例说明


BCD 数据保存在 16 位存储器内时,可以处理 0~9999(4 位的最大值)的数值。各个位的权重如
下图 6.x 所示。
图 6.x BCD 用 10 进制表示的各数值权重
CoDeSys 用于 BCD 码与整型的互相转换指令详见表 6-x。使用该转换函数前需要先添加 ⇘
util.library 库。

表 6-x BCD 码与整数的互相转换指令


转换 图形化语言 文本化语言 说明
指令
BCD 码 BCD_TO_BYTE BCD 转 INT
与整
数的
互相
BCD_TO_DWORD BCD 转 DWORD
转换
指令

BCD_TO_INT INT 转 BCD

BCD_TO_WORD BCD 转 WORD

BYTE_TO_BCD BYTE 转 BCD

DWORD_TO_BCD DWORD 转 BCD

INT_TO_BCD INT 转 BCD

WORD_TO_BCD WORD 转 BCD

【例 6.x】使用 ST 编程语言,将 BCD 码 73 转换为整型数据。


i:=BCD_TO_INT(73);
图 6.x BCD 转 INT 应用举例
如上图 6.x 所示,使用 BCD_TO_INT 指令进行转换,因为 73 转换为 2 进制后的结果为 0100
1001,故将其转换为 BCD 后的结果为 49。

【例 6.x】使用 ST 编程语言,将整型数据 73 转换为 BCD 码。


i:=INT_TO_BCD(73);

20 + 21 + 24 + 25 + 26 = 115。

图 6.x INT 转 BCD 应用举例


如上图 6.x 所示,采用 INT_TO_BCD 指令进行转换。程序将 10 进制的 73 转换为 BCD 码后的
结果为 0111 0011,故最终 BCD 码十进制的表示结果为 115。

【例 6.x】工业控制中经常会遇到数据设定及数据显示的情况,此时通常需要通过 BCD 码与整


型数据转换来实现。如图 6.x 所示,用户利用数字输入按钮输入数据 1942,程序内需要将该数进行
加法计算,加 752,将结果显示在 7 段码数据显示窗中。其程序如图 6.x 所示。

a) b)

图 6.x 输入信号与输出显示
a)数字输入开关的输入信号 b)7 段显示器(数字显示器)的输出信号
程序如图 6.x 所示,有效区为红色框内段程序,梯形图第 1 句和第 3 句为了便于理解,实际应
用中不要此转换指令。
当用户通过拨码开关键入 1942 时,在程序内实际收到对应的 BCD 数据为 6466,故需要将
6466 转换为实际整型数据进行逻辑运算。由于 BCD_TO_INT 输出的是为 BYTE 类型变量,如使用
6466 转换后会使数据溢出,故在此需要使用 WORD 类型的输出指令 BCD_TO_WORD 将其 BCD 数
据还原成整型数据。转换后能在程序内进行正常的逻辑运算,在此进行了加法运算,还原有效数据,
通过运算将结果转换为 7 段显示器能识别的 BCD 数据最终输出。
图 6.x 输入信号与输出显示程序举例
样例程序详见\BCD_TO_INT\。

2.BOOL_TO_<TYPE> 布尔类型转换数据
功能:把布尔数据类型转换为其它数据类型。
支持数据类型 :BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、UDINT、
REAL、TIME、DATE、TOD、DT 和 STRING。
输出为数字类型时 :如果输入是 TRUE,则输出为 1。如果输入是 FALSE,则输出为 0。
输出为字符串类型时 :如果输入是 TRUE,则输出字符串'TRUE'。如果输入是 FALSE,则输
出为字符串'FALSE'。
【例 6.x】BOOL_TO_<TYPE>示例如下表 6-x 所示。

表 6-x BOOL_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

BOOL_TO i:=BOOL_TO_INT(TRUE); 1

str:=BOOL_TO_STRING(TRUE); 'TRUE'

t:=BOOL_TO_TIME(TRUE); T#1ms

tof:=BOOL_TO_TOD(TRUE); TOD#00:00:00.001

dat:=BOOL_TO_DATE(FALSE); D#1970

dandt:=BOOL_TO_DT(TRUE); DT#1970-01-01-00:00:01

3. BYTE_TO_<TYPE> 字节类型转换数据
功能:把字节类型转换为其它数据类型。
支持数据类型:BOOL、WORD、DWORD、SINT、USINT、INT、UINT、DINT、UDINT、
REAL、TIME、DATE、TOD、DT 和 STRING。
输出为 BOOL 时 :输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
输出为 TIME 或 TOD 时 :输入将以毫秒值进行转换。
输出为 DATE 或 DT 时 :输入将以秒值进行转换。
【例 6.x】BYTE_TO_<TYPE>示例如下表 6-x 所示。

表 6-x BYTE_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

BYTE_TO bVarbool:= BYTE_TO_BOOL(255); TRUE

iVarint:= BYTE_TO_INT(255); 255

tVartime:= BYTE_TO_TIME(255); T#255ms

dtVardt:= BYTE_TO_DT(255); DT#1970-


01-01-
00:04:15
rVarreal:= BYTE_TO_REAL(255); 255

stVarstring:=BYTE_TO_STRING(255); ‘255’

4.<整型数据> _TO_<TYPE>整数类型转换指令
功能:把整数类型数据转换为其它数据类型。
支持数据类型:BOOL、BYTE、SINT、WORD、DWORD、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时:输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。()
 输出为 TIME 或 TOD 时,输入将以毫秒值进行转换。
 输出为 DATE 或 DT 时 :输入将以秒值进行转换。
【例 6.x】由于整数类型很多,转换过程相似,故以 WORD_TO_<TYPE>举例,如表 6-x 所示。

表 6-x <整型数据>_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

<整型 iVarsint:=WORD_TO_USINT(4836); 255

据>_TO
tVartime:=WORD_TO_TIME(4836); T#4s863ms

dtVardt:= BYTE_TO_DT(4836); DT#1970-


01-01-
01:21:03
5. REAL_TO_<TYPE>实数类型转换指令
功能:把浮点数转换为其它类型数据。把浮点数转换为其它类型数据时,先将值四舍五入成整
数值,然后转成新的量类型。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时:输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
 输出为 TIME 或 TOD 时:输入将以毫秒值进行转换。
 输出为 DATE 或 DT 时 :输入将以秒值进行转换。
【例 6.x】REAL_TO_<TYPE>示例如下表 6-x 所示。

表 6-x REAL_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

REAL_TO iVarsint:= REAL_TO_INT(1.5); 2

6. TIME_TO_<TYPE> 时间类型转换指令
功能:把时间型数据转换为其它类型数据,时间在内部以毫秒为单位存储成 DWORD 类型
(对于 TIME_OF_DAY 变量从凌晨 00:00 开始)。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时:输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
【例 6.x】TIME_TO_<TYPE>示例如下表 6-x 所示。

表 6-x TIME_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

TIME_TO sVarstring:= ‘T#12ms’
TIME_TO_STRING(t#12ms);

dVardword:= 300000
TIME_TO_DWORD(t#5m);

7. DATE_TO_<TYPE> 日期类型转换指令
功能:把日期型数据转换为其它类型数据,日期在内部以秒为单位存储,时间从 1970 年 1 月 1
日开始。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时:输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
【例 6.x】DATE_TO_<TYPE>示例如下表 6-x 所示。

表 6-x DATE_TO_<TYPE>转换梯形图指令举例
转换指 图形化语言 文本化语言 结果

DATE_T sVarstring:= ‘D#1970
O DATE_TO_STRING(D#1970 -01-01’
-01-01);
iVarint:= 29952
DATE_TO_INT(D#1970-
01-01);

8. DT_TO_<TYPE>日期时间类型转换指令
功能:把日期时间型数据转换为其它类型数据,日期在内部以秒为单位存储,时间从 1970 年
1 月 1 日开始。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时: 输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
【例 6.x】DT_TO_<TYPE>示例如下表 6-x 所示。

表 6-x DT_TO_<TYPE>转换梯形图指令举例
转换 图形化语言 文本化语言 结果
指令
DT_TO byVarbyte:= 129
DT_TO_BYTE(DT#1970-
01-15-05:05:05);
sVarstr:= DT_TO_ ‘DT#1998-
STRING (DT#1998-02- 02-13-
13-05:05:06); 05:05:06’

9.TOD_TO_<TYPE> 时间类型转换指令
功能:把时间型数据转换为其它类型数据,日期在内部以毫秒为单位进行转化。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
 输出为 BOOL 时:输入不等于 0 时,输出为 TRUE。输入等于 0 时,输出为 FALSE。
【例 6.x】TOD_TO_<TYPE>示例如下表 6-x 所示。

表 6-x TOD_TO_<TYPE>转换梯形图指令举例
转换 图形化语言 文本化语言 结果
指令
TOD_T iVarusint:=TOD_TO_USINT(T 96
O OD#10:11:40);

tVartime:=TOD_TO_TIME(TOD T#611m40s0m
#10:11:40); s

dtVardt:=TOD_TO_DT(TOD#10 DT#1970-01-
:11:40); 01-10:11:40

rVarreal:=TOD_TO_REAL(TOD 3.67e+007
#10:11:40)

10. STRING_TO_<TYPE> 字符类型转换指令


功能:把字符串转换为其它类型数据,字符串型变量必须包含一个有效的目标变量值,否则转
换结果为 0。
支持数据类型:BOOL、BYTE、WORD、DWORD、SINT、USINT、INT、UINT、DINT、
UDINT、REAL、TIME、DATE、TOD、DT 和 STRING。
【例 6.x】STRING_TO_<TYPE>示例如下表 6-x 所示。
表 6-x STRING_TO_<TYPE>转换梯形图指令举例
转换指令 图形化语言 文本化语言 结果
STRING_T wVarword:=STRING_TO_WORD(' 0
O CoDeSys');

tVartime:=STRING_TO_TIME(' T#128m
T#128ms'); s

11. 取整 TRUNC
功能:将数据截去小数部分,只保留整数部分。
支持数据类型:输入为 REAL 型,输出为 INT、WORD、DWORD 型。
【例 6.x】TRUNC 取整指令示例如下表 6-x 所示。

表 6-x 取整指令
取整指令 图形化语言 文本化语言 说明
TRUNC iVarint:=TRUNC(1.7) 1

iVarint:=TRUNC(-1.2) -1

注意:
● 当从较大数据类型转为较小数据类型时,有可能丢失信息。
● 本指令只是截取整数部分,如果想四扌舍五入取整,可使用 REAL_TO_INT 指令。
第7章 程序结构
本章主要知识点
 了解 POU 的作用
 理解 CoDeSys 系统程序和用户程序
 掌握程序(PRG),函数(FUN)和功能块(FB)的使用方法。

7.1 系统程序和用户程序

CoDeSys 系统程序和用户程序

7.2 用户程序结构
7.2.1 常用的编程方法

常用的编程方法主要有流程化编程、模块化编程和结构化编程。如图 7-x 所示。


流程化编程 模块化编程 结构编程
PLC_PRG PLC_PRG PLC_PRG
POU1
FB1 FB1
电机控制 工序 1
电机控制 主

POU2
程 FB2 程 FB2
主流程控制 主流程控制 工序 2
序 序
POU3 FB3 FB3
数据统计 工序 3
数据统计

图 7.x 用户程序的三种编程方法

1. 流程化编程
所有的指令都在一个主程序 PLC_PRG 内
2. 模块化编程
每个设备的控制指令都在各自的功能块内。主程序按顺序调用每个块。

3. 结构编程
1) 概念
结构化程序设计(Structured Programming)是进行以模块功能和处理过程设计为主的详细设计
的基本原则。结构化程序设计是过程式程序设计的一个子集,它对写入的程序使用逻辑结构,使得
理解和修改更有效更容易。
其概念最早由 E.W.Dijikstra 在 1965 年提出的,是软件发展的一个重要的里程碑。它的主要观
点是采用自顶向下、逐步求精及模块化的程序设计方法;使用三种基本控制结构构造程序,任何程
序都可由顺序、选择、循环三种基本控制结构构造。结构化程序设计主要强调的是程序的易读性。
2) 基本结构
结构化程序设计的三种基本结构是:顺序结构、选择结构和循环结构。
 顺序结构
顺序结构表示程序中的各操作是按照它们出现的先后顺序执行的。图 7.x 的结构称为顺序结构。

图 7.x 顺序结构
 选择结构
选择结构表示程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执
行。选择结构有单选择、双选择和多选择三种形式。图 7.x 的结构称为选择结构。
图 7.x 选择结构
 循环结构
循环结构表示程序反复执行某个或某些操作,直到某条件为假(或为真)时才可终止循环。
图 7.x a)表示的结构称为“当型”循环。当给定的条件满足时执行 A 块,否则不执行 A 块而直
接跳到下面部分执行。图 7.x b)表示的结构称为“直到型”循环,它的 含义是:执行 A 块直到满足
给定的条件为止(满足了条件就不再执行 A 块)。这两种循环的区别是:当型循环是先判断(条件)
再执行,而直到型循环是先执行后判 断。

a) b)

图 7.X 循环结构
a )当型循环 b )直到型循环
3) 设计方法
 自顶向下
程序设计时,应先考虑总体,后考虑细节;先考虑全局目标,后考虑局部目标。不要一开始就
过多追求众多的细节,先从最上层总目标开始设计,逐步使问题具体化。
 逐步细化
对复杂问题,应设计一些子目标作为过渡,逐步细化。
 模块化
一个复杂问题,肯定是由若干简单的问题构成。模块化是把程序要解决的总目标分解为子目标,
再进一步分解为具体的小目标,把每一个小目标称为一个模块。
 结构化编码
所谓编码就是把已经设计好的算法用计算机语言表示,即根据已经细化的算法正确写出计算机
程序。结构化文本的语言都有与三种基本机构对应的语句。
4) 优缺点
 优点
由于模块相互独立,因此在设计其中一个模块时,不会受到其它模块的牵连,因而可将原来较
为复杂的问题化简为一系列简单模块的设计。模块的独立性还为扩充已有的系统、建立新系统带来
了不少的方便,因为我们可以充分利用现有的模块作积木式的扩展。
按照结构化程序设计的观点,任何算法功能都可以通过由程序模块组成的三种基本程序结构的
组合:顺序结构、选择结构和循环结构来实现。
结构化程序设计的基本思想是采用“自顶向下,逐步求精”的程序设计方法和“单入口单出口”
的控制结构。自顶向下、逐步求精的程序设计方法从问题本身开始,经过逐步细化,将解决问题的
步骤分解为由基本程序结构模块组成的结构化程序框图;“单入口单出口”的思想认为一个复杂的
程序,如果它仅是由顺序、选择和循环三种基本程序结构通过组合、嵌套构成,那么这个新构造的
程序一定是一个单入口单出口的程序。据此就很容易编写出结构良好、易于调试的程序来。
a) 整体思路清楚,目标明确。
b) 设计工作中阶段性非常强,有利于系统开发的总体管理和控制。
c) 在系统分析时可以诊断出原系统中存在的问题和结构上的缺陷。
 缺点
a) 用户要求难以在系统分析阶段准确定义,致使系统在交付使用时产生许多问题。
b) 用系统开发每个阶段的成果来进行控制,不能适应事物变化的要求。
c) 系统的开发周期长。

不同的功能块调用可重复利用的代码。主程序调用这些功能块并传递相应的参数。
第8章 基础编程
本章主要知识点
 新建项目、程序下载和调试
 程序监控及程序仿真

8.1 基本编程操作
编程操作时编程软件最基本的功能,一般来说,前期工作都是离线完成的,当有了系统的整体
控制方案后,要离线为控制器创建项目,建立相应的程序和数据,I/O 组态,控制工艺的逻辑代码,
在线调试,最终将项目程序下载至控制器。编程软件不但能离线完成前期的大量工作,还能在线完
成编程、调试、诊断和排除故障工作。
CoDeSys 离线和在线所做的编程工作大都是相似的,却在不同的环境下进行,离线编程在计算
机的实时核中进行;在线编程在控制器内存中操作,所修改的内容在接收之前存放在控制器内存的
缓冲区,接收过程与控制器的工作状态有关,控制器在程序状态接收较快,但仍需要一个个梯级的
接收,运行状态的编辑是受限的,并且必须经过测试,才能最终确认。

8.1.1 启动 CoDeSys

1. 设置管理员权限
在 Win7 系 统 下 需 要 以 管 理 员 权 限 打 开 软 件 , 在 CoDeSys 的 默 认 安 装 路 径 下 找 到
CODESYS.EXE 文件,选中该 文件后点击 鼠标右键, 选择属性, 将“ Run This Program as an
administrator”的勾选上,点击“OK”确认,如图 8.x 所示。
确认后每次运行 CoDeSys 系统则会默认以管理员权限自动进入 CoDeSys。
2. 启动 CoDeSys
从开始菜单选择>程序 > 3S CoDeSys > CoDeSys > CoDeSys V 3.5 或直接双击桌面上的图标

启动 CoDeSys。
图 8.x 管理员权限

3. 创建工程项目
在文件菜单中选择新建工程命令,创建一个新的工程,如图 9.x 所示。
1) 选择项目
用户可以新建一个库项目,空项目及标准
程序项目。并为工程文件输入名称及路径,点
击“确定”。
2) 新建程序及选择编程语言
根据向导对话框,选择目标设备及主程序
PLC_PRG 的编程语言,如图 9.x 所示。

目标设备 项目名

编程语言 程序名

图 9.x 目标设备及编程语言选择 图 9.x 新建工程

8.1.2 PLC 程序文件的建立

PLC 程序文件的建立,是运行结构的运行顺序的建立,也是编程模式的建立,甚至包括了数据
区域的分割。在建立程序文件之前,应当对运行结构进行详细的划分,确定连续型、周期型和时间
触发型任务,并对周期型和事件触发型任务安排优先级别。
新建一个 CoDeSys 项目后,自动生成一个默认的连续性任务,任务下有一个默认的程序,及
PLC_PRG。
1. 创建任务
首先,在“任务配置”中管理任务,通常的项目应用中,可以分为主逻辑任务,通讯任务,通
讯由于要更新数据源,会将它放在比较高的任务优先等级及较短的循环时间。此外,如项目中涉及
到运动控制,也会将其独立出一个任务,并将其放在最高的任务优先等级,如图 9.x 所示。

图 9.x 任务管理
具体任务的配置及说明在本书 2.3 节中有详细介绍,在此不再说明。
2. POU 的建立
选中“Application”-->右键选择“添加对象”,选择“程序组织单元”进行 POU 的添加。
1) 声明变量
在设备视窗中,默认 POU 为“PLC_PRG”,双击设备树中“PLC_PRG”,自动在 CoDeSys
用户界面中部的 ST 语言编辑器中打开。
语言编辑器包含声明部分(上部),实现部分(下部),由一个可调的分割线分开。
声明部分包括:显示在左侧边框中的行号、POU 类型和名称(如“PROGRAM PLC_PRG”) ,
以及在关键字“VAR”和“END_VAR”之间的变量声明,如图 8.x 所示。
在编辑器的声明部分,将光标移到 VAR 后,点击回车。插入新的空行,声明 INT 类型变量
“ivar” ,INT 类型变量“erg”,FB1 类型变量“fbinst”。

图 9.x 变量声明
PROGRAM PLC_PRG
VAR
Ivar: INT;
Fbinst: FB1;
Erg: INT;
END_VAR
另外,也可以使用自动声明功能,在编辑器执行部分直接输入指令。
2) 输入程序
在声明区域下的程序编辑区域输入如下代码。
ivar := ivar+1; // counter
fbinst (in:=11, out=>Erg); // call function block of type FB1
3) 自定义函数/功能块
在变量声明区可以看到,调用了功能块“FB1”,但“FB1”并不是标准功能块,故需要自定
义功能块。
功能作用是在输入变量“in”的基础上上加“2”赋值给输出“out”。
从工程菜单中选择“添加对象”命令。在“添加对象”对话框左侧选择“程序组织单元”,输
入名称:FB1,在类型选项中激活“功能块(B)”选项。实现语言选择“结构化文本(ST)”。点
击“打开”按钮确认对象设置。
用于新功能块 FB1 的编辑窗口打开。与 PLC_PRG 的变量声明一样,在此对以下变量声明:
FUNCTION_BLOCK FB1
VAR_INPUT
in:INT;
END_VAR
VAR_OUTPUT
out:INT;
END_VAR
VAR
ivar:INT:=2;
END_VAR
在程序编辑器实现部分输入以下内容:
out:= in+ivar ;

8.2 定义资源对象

8.2.1 启动 Gateway Server 和 PLC

Gateway Server 主要起到通讯网关的作用,再给 CoDeSys 下载程序之前,必须先使用 Gateway


Server,此外,当 PLC 通过如 OPC 协议与其他设备连接时,也需要设置 Gateway Server。该服务程
序由 CoDeSys 安装程序提供。
1) 启动 Gateway Server
Gateway Server 作 为 服 务程 序在系 统启动 时自 动启 动,请 确认在 系统 托盘 处是否 有指示
Gateway Server 运行的图标 。如果图标为 ,则表明 Gateway Server 当前未启动。
2) 启动 PLC
系统启动时,PLC(CoDeSys SP Win V3)作为服务程序在系统启动时自动加载。其图标会显
示在系统托盘中, 代表“停止”状态, 代表“运行”状态。若系统许可,PLC 服务程序将
在系统启动时自动启动。否则需要手动点击图标右键菜单中的“启动 PLC”命令启动服务。
1. 激活“Application”
点击 Standard project 设备视窗中的 MainTask,打开包含任务设置的编辑器视图,则如图 9.x 所
示。

图 8.x MainTask 设置
在设备视窗中,“Application”显示为黑色字体,表明该应用处于激活状态。这样,所有与
PLC 通讯相关的命令和动作都关联于该应用。在设备视窗中选择应用,从右键菜单中选择 “设置
当前的应用” 命令将激活此应用。
2. 网关组态
网关(Gateway)的作用:网关给了应用者使用计算机进入控制器网络的功能,如图 9.x。通常
接入的是本地主设备并且可以扫描接入主设备的所有其他设备,如图 8.x 所示。

图 8.x 网关组态界面
1) 扫描网络
可以选择“Scan network”搜索在同一网段内的 PLC,找到后点击确定,如图 8.x 中的 PLC 的
设备名为“CCN525399”。

图 8.x 选择找到的 PLC


在设备视窗中双击 Device (CoDeSys SP Win V3),打开通讯设置子对话框。根据以下步骤,可
以在此处安装 PLC (目标设备)和编程系统的连接。连接将被输入到“给控制器选择网络路径”的下
一行。
2) 网关组态:
网关组态的视图如图 8.x 所示。
可以为网关输入名称,驱动选择“TCP/IP”,IP 地址设置为“local host”(鼠标双击可以进行
编辑),端口使用默认设置,点击“确定”关闭对话框。网关被添加到通讯对话框左侧,网关名称
被添加到“给控制器选择网络路径”选项列表。
图 8.x 网关设置
当配置完成后,可在图 8.x 的中央看见绿色的原点,当网关正常运行时,Gateway 前面会显示
绿色圆点,红色则表示异常。
3) 设备修改
该选项可以选择常用的设备。

8.3 程序下载
8.3.1 编译

程序编写完成后,在下载之前需要对程序进行编译。编译命
令对编写的程序进行语法检查,并且只编译添加到任务中的程序。
如果创建的 POU 没有添加到任务中,编译命令不对该 POU 进行
语法检查。
编译指令不生成任何代码,只针对 POU 的语法进行检查。
直接执行设备登录命令,系统也将默认执行编译指令( 等同
于先手动执行编译命令),再编译检查没有语法错误后执行连接
登录指令。同样,在编译中不对没有添加到任务中的 POU 进行语
法检查。执行登录命令同时会生成代码。CoDeSys 编译菜单如图
9.x 所示。
1) 编译:对当前的应用进行编译。 图 9.x 编译菜单
2) 重新编译:如果需要对已经编译过的应用再次编译,
可以通过重新编译指令进行。
3) 生成代码:执行此命令后生成当前应用的机器代码,执行登录命令时,生成代码默认执行。
4) 清 除:删除当前应用的编译信息,如果再次登录设备时需要重新生成编译信息。
5) 清除全部:删除工程中所有的编译信息。
执行编译命令后可以看到,添加到任务里面的“PLC_PRG”显示为蓝色,没有添加到任务里
面的则显示为灰色,如图 9.x 所示。编译指令不会对灰色的 POU 进行语法检查,因为该程序单元没
有处于活动状态,编译指令只针对于处于活动状态的 POU 进行语法检查。
如果在编译的过程中发现需要运行的程序单元显示为灰色,可以检查该程序单元是否已经被成
功的添加到了所需要运行的任务当中。

图 9.x 编译信息
编译命令执行完成之后可以在消息栏看到编译生成的信息,其中可以看到编译的程序是否有错
误或者警告,以及错误和警告的数量。如果有错误和警告产生可以通过消息窗口进行查看和查找,
根据提示信息对程序进行修改。

8.3.2 登入下载

1. 登入
登陆使应用程序与目标设备建立起连接,并进入在线状态。能正确登陆的前提条件是要正确配
置设备的通讯设置并且应用程序必须是无编译错误的。
对于以当前活动应用登录,生成的代码必须没有错误和设备通信设置必须配置正确。登入后,
系统会自动选择程序下载。
2. 下载
下载命令,在在线模式下有效。它包括对当前应用程序的编译和生成目标代码两部分。除了语
法检查(编译处理)外,还生成应用目标代码并装载到 PLC。

图 9.x 下载对话框
(1) 在线修改后登入
用户选择此选项后,项目的更改部分被装载到控制器中。使用“在线修改后登入”操作,可以
防止控制器进入 STOP 状态。

注意:
用户之前至少执行过一次完整的下载。
指针数据会更新最近一个周期的数值,如果改变了原变量的数据类型,无法确保数据的准确性,此时,需
要重新分配指针数据。

(2) 登入并下载
选择“登入并下载”后,将整个项目重新装载到控制器中。与“在线修改后登入”最大的区别
是当完成下载后,控制器会停留在 STOP 模式,等待用户发送 RUN 指令,或重启控制器程序才会
运行。
(3) 没有变化后的登入
登录时,不更改上次装载到控制器中的程序。
当完成下载后,需要将程序每次启动时运行,还需要点击“创建启动应用”
已编译的项目在控制器上以这种方式创建引导,即控制器再启动后,可以自动装入项目程序运
行。引导项目的存储方式不同,取决于目标系统。

注意:
下载命令使得除持续型变量之外的所有变量都将被重新初始化。
(4) 细节
通过消息窗口中的“细节”按键可以获得项目中中改变的变量数量以及具体清单,如图 9.x 所
示。

图 9.x 在线改变细节视图

3. 创建启动应用
创建启动应用命令是在在线或者离线状态下创建启动工程,也称为“创建启动应用”。启动工
程为 PLC 中运行应用提供服务,当 PLC 启动时,自动装载程序。否则,重启控制器后,之前下载
的程序会丢失。在 “在线”-->“创建启动应用”,系统则自动会将程序写入控制器的 FLASH
ROM 区域,具体步骤如图 9.x 所示。
图 9.x 创建启动应用
此外,用户也可以设置自动下载启动应用,每一次更新过程序后,下载至控制器后都会自动完
成启动应用的下载。具体步骤为主:点击应用右键选择“属性”,在“创建你应用设置”选项中,
在“下载创建默认应用”前打上勾,点击确定,如图 9.x 所示。

图 9.x 设置默认创建启动应用

4. 源代码下载
CoDeSys 出于对程序员源代码的保
护,下载时默认不自动下载源代码,如
需下载源代码则需要进行手动设置,点
击“在线” --> “下载源代码到连接设
备上”。
用户也可以在“工程” --> “工程
设置 ”-->“下载源代码” --> “计时”
选项中对该属性进行设置,如图 8.x 所
示。
计时:
1) 使用选项 “隐含在程序下载中”
能使所选择的文件范围, 通过命令“在
线” --> “下载”,会自动地装载到控
制系统内。
2) 使用选项“程序下载时提示”
提供一个对话框,当使用命令“在线”
图 8.x 源代码下载
--> “ 下 载 ”命 令时 ,会 提出 问题
“你是否需要将源代码装载到控制系统内?”按 “是”,则自动地将所选择的文件范围装载到控
制系统内;按“否”,结束提问。
3) 使用选项“隐含创建启动工程中”,通过命令“在线” --> “创建启动应用”能够允许选择
的文件自动装载到控制系统内。
4) 当使用选项 “只按要求”时, 所选择的文件范围必须通过命令“在线”--> “下载源代码
到连接设备上”,确定装载到控制系统内。
5. 读取程序
在“文件” > “源上传”命令打开
一个设备选择对话框,用户选择连接
PLC 的网络路径,点击“确定”按钮。
此时出现工程存档文件对话框,如
图 8.x 所示。用户可以选择文件的哪些
内容需要解压并上载,并选择要复制文
件的路径。此对话框是进行工程存档/解
压存档文件的。点击“确定”按钮确认
后,完成存档文件的复制。如果用户选
择的路径下已经存在存档文件,给出是
否覆盖提示。

这里需要注意的是,在读取程序
之前需要确保在前一次的下载过程中 图 8.x 源上载
已经做过“下载源代码到连接设备
上”。否则不能读出控制器中的数据。

8.3.3 在线监控

使用以下三种方法,可以在线监控应用程序中的变量:
1) POU 的在线监控;
2) 特殊变量的在线视图;
3) 写入和强制变量。
1. POU 的在线监控
POU 的示例视图提供了该示例的所有监控表达式,并在声明部分以表格显示,若激活“在线
监控”功能,在程序实现部分也同样会显示。
双击在设备窗口里的执行程序“PLC_PRG”,或选择该项右键菜单点击 “编辑对象”命令,
打开在线视图,出现如下图 8.x 中的对话框,这里,可以选择 POU 以在线模式或是离线模式进行
查看。程序双击默认以在线模式登入。
如图 8.x 所示 PLC_PRG 在线视图被打开:上半部分显示对应于 PLC_PRG 中变量表达式的状
态,以表格的形式来显示。下半部分显示 PLC_PRG 的监控表达式,也是程序的逻辑主体,由每一
个变量后的内部监控窗口显示实际的值。
图 8.X 编辑对象

图 8.x 程序登入视图
此外,用户如想要同时监控多个 POU,可以自行配置观察表,把需要在同一情况要观察的变
量集合起来,一并进行比较,如图 8.x 的 a)所示,在“视图”中找到“监视”栏,在其中可以配
置 4 个监控列表,如点击“监视 1”则程序自动建立监控 1 列表。
a) b)

图 8.X 创建监视列表
a ) 视图监视窗口 b )输入助手
打开监视 1 后,点击表达式下的空栏,会出现输入助手,如图 8.x 的 b)所示。通过输入助手
选择要监视的变量,组成列表。在线登入控制器后,就可对变量进行强制,如图 8.x 所示。

图 8.x 变量监视列表视图

2. 特殊变量的在线视图
1) 监视功能块实例
在监视 IN 和 OUT 变量时,输出为间接引用的值。点击“+”将其扩展可以看到功能块实例内
所有变量的具体数值,如图 8.x 所示。

图 8.x 功能块在线监控视图
2) 监视指针变量
在监视指针变量时,将在声明部分输出指针和间接引用的值。在程序部分则只有指针输出:
另外,还相应地显示间接引用值的指针。点击“+”将其扩展可以看到指针所指向地址里的具
体数值,如图 8.x 所示。

图 8.x 指针变量在线监控视图
3) 监视数组变量
除了以常数索引数组部件外,还可显示由变量索引的部件,如图 8.x 所示:

图 8.x 数组变量在线监控视图

注意:
若索引由表达式由变量加运算表达式,如 [i+j] 或 [i+1]组成,则不能显示部件。

3. 写入/强制变量赋值
CoDeSys 中有 2 种强制赋值的方式供选择,如图 8.x 所示,一种为“写入值”,另一种是“强
制值”。
1) 写入值:只下一周期将变量改为准备值中的数据。如该变量未被其他程序赋值,则保持该
数据,否则变量根据实际程序里的赋值语句进行执行。通过“写入值”赋值的数据显示正常的黑色
或蓝色。
2) 强制值:从下一周期开始,在每个循环后再次设定为某个强制值。如果系统中有程序给该
变量赋值,该变量仍为强制的数据,“强制值”优先级较高。通过该方式写入的数值在变量列表中
可以见到其左侧有红色的“ ”标识。强制值可以通过“调试”-->“释放值”命令将其释放还原。

图 8.x 强制变量
强制值写到“准备值”项中,然后通过以下快捷键完成写入。
写入值:[Ctrl]+[F7] ,
强制值:[F7] ,
释放值:[Alt] +[F7] 。
8.4 程序调试

8.4.1 复位

CoDeSys 程序复位有如下三种方式,在在线菜单中进行
选择,详见图 8.x 所示。
1. 热复位
热复位后,除了保持型变量(PERSISTENT 和 RETAIN
变量)外,其它当前的应用的变量都被重新初始化。如果设
置了初始值的变量,热复位后这些变量值还原为设定的初始
值,否则变量都会被置为标准初始值 0。
为了安全起见,当所有变量在初始化之前,CoDeSys 会
给出提示,提示用户是否确认热复位操作,如图 8.x 的 a)所
示。此情形只有在程序正在运行时断电,或者通过控制开关
闭控制器,然后再打开(热复位)时出现。
2. 冷复位
图 8.x 程序复位
与“热复位'”不同的是,冷复位命令不但将普通变量的
值设置为当前活动应用程序的初始值,而且将保持型变量(PERSISTENT 和 RETAIN 变量)的值也
设置为初始值 0。冷复位发生在程序下载到 PLC 之后,运行之前(冷启动),同样,执行冷复位命
令之前,为了安全考虑,系统也会弹出提示框,如图 8.x 的 b)所示。

a) b)

图 8.X 复位
a )热复位 b )冷复位
3. 初始化复位
当在设备树中选择一个可编程设备时,无论是在离线还是在在线状态下都可以使用此命令。使
用此命令将使设备复位到初始状态,即设备中的任何应用、引导工程和剩余变量都将被清除。
由于所有工程信息被清除,重新登入后,需要重新“下载”程序,并“启动”运行,如图 8.x
所示。

图 8.X 初始化复位后重新启动
8.4.2 程序调试

在 CoDeSys 中“调试”菜单的视图如图 9.x 所示。主要的操作涉及断点设置及单循环。

图 8.x 程序调试菜单

1. 断点
断点是程序内处理停止的功能,当程序停止后,程序研发人员可以借此观察程序到断点位置时
其变量及 I/O 等相关变量的内容,有助于深入了解程序运行的机制,发现及排除程序故障。
在 CoDeSys 中所有的编程语言都可以设置断点。在文本编辑器 ST 语言中中,断点设置在行上;
在 FBD 和 LD 编辑器中设置在网络号上;而在 SFC 中,设置在步上。
1) IL 中断点位置的几行代码在内部被组合成一个单行的 C 代码,断点不能在每个行都进行设
置。断点位置可以包括在一个程序内的所有变量值可以改变的位置,或者在程序流程分支闭合处。
(例外:功能调用。如有必要,必须在此设置功能的断点)。如果在中间位置安放一个断点,则该
断点没有意义,这是因为从前面断点位置以来,数据不会有任何改变。可以在 IL 中以下位置设置
断点:
2) 结构化文本 ST 允许以下位置设置断点:
 在每个赋值处
 在每个 RETURN 和 EXIT 指令处
 正在评估的条件处(WHILE,IF,REPEAT)
 在 POU 结束处。
在一个项目中只能设置一个断点,针对任务进行设定,断点参数通过“调试”-- > “切换断点”
进行设置的,或是通过“新断点”指令进行设置。
图 8.x 新断点设置界面
(1) 设置断点
为了设置一个断点,在你需要设置断点的行中点击行号字段。如果所选择的字段恰好是一个断
点位置,点击菜单“调试” -->“ 切换断点”完成,也可以使用功能键 [F9],或使用工具条中的符
号完成。则该行号字段的颜色就会从深灰色变成浅蓝色,并在 PLC 中被激活。
(2) 删除断点
相应地,要删除一个断点,可以在需要删除断点的行号字段上点击。设置和删除断点还可以通
过菜单菜单“调试”-->“切换断点”完成,也可以使用功能键[F9]或使用工具条中的符号完成。
(3) 在断点处发生了什么?
如果 PLC 程序到达一个断点,则在屏幕上显示相应行的断点,PLC 会处于停止模式。并且
PLC 确定的行号字段将显示为红色,具体的状态如表 9-x 所示。

表 9-x ST 中断点状态显示
模式下有效断点的图标 无效断点的图标 程序停在断点处时的图标

PLC 中的用户程序被停止。如果该程序处于断点位置,可以通过先删除断点,再通过使用“调
试” -->“ 切换断点”释放该过程。
3) 连续功能图 CFC 允许以下位置设置断点
在 POU 中,变量值能发生变化的地方或者程序运行到其他的 POU 分支。如图 9.x 中可能的位
置。
图 8.x CFC 程序中的断点设置

注意:
在函数/功能块中不能设置断点。
断点时,需要针对任务,断点只能针对一个任务进行设置。

2. 单步执行
设置断点后,可以进行单步执行程序,该功能可以让程序一步一步的运行,方便编程人员进行
调试,以便检查程序中的逻辑错误,单步指令如图 8.x 所示。

图 8.x 单步执行指令
(1) 跳过
该命令会执行程序中当前的一条指令,执行完停止。在不调用 POU 时,跳过和跳入命令效果
是一样的。但如果是调用 POU,那么跳过不会进入这个 POU,而是把这个 POU 调用当作完整的一
步,一次执行完;跳入则会进入该 POU。如果用的是 SFC 语言,那么跳过会把一个动作当作完整
的一步,一次执行完。
如果想要实现跳到被调用的 POU 中单步调试,就必须用跳入。
(2) 跳入
执行时,当前的指令位置由一个黄色箭头表示。如果当前指令没有调用 POU,那么使用该命
令和使用跳过命令的效果一样。
(3) 跳出
当正在一个 POU 中单步调试时,用跳出会把这个 POU 剩下的指令一次执行完,然后返回到这
个 POU 被调用处的下一条指令。所以,如果是一层一层向下调用 POU,那么跳出就会一层一层向
上返回,每次返回一层。
如果程序中不包含任何 POU 调用,那么跳出无法向上层返回,就会返回到程序的开头处。
3. 单循环
在“调试”—>中选择“单循环”,这样程序进行单步运行。即按一次运行,程序执行一个周
期即停止并等待下一次运行指令,如图 8.x 所示。也可使用快捷键[Ctrl]+[F5]进行程序运行。如果
不点击“启动”,则程序一直处于停止模式。
图 8.x 单循环启用菜单
通过不断使用该功能,使之一步一步地执行以查看程序是否按照设计进行工作。
如图 8.x 所示,程序有一句表达式为 cnt:= cnt+1;每次执行单循环指令后,cnt 的数值则会逐渐累加。

图 8.x 单循环执行效果

8.5 仿真
CoDeSys 编程软件集成了 PLC 的仿真功能,可以实现使用 PC 仿真实际的 PLC 程序,应用在
现场安装前,就可以进行完整的测试,可以及早发现程序中的逻辑错误,提高开发的效率,缩短程
序的开发。仿真过程中,不需要提供 PLC 实际硬件,只需一台安装有 CoDeSys 的 PC 机即可。

8.5.1 离线仿真

在菜单 “在线”中选择“ 仿真”,便进入了仿真模式下的程序运行过程。确认选项“仿真”


前已打上 后,编译程序,没有错误后,即可进入仿真模式。如图 9.x 所示。
图 9.x 仿真模式开启
进入仿真界面,启动 PLC 程序运行仿真,确认图 9.x 中框出部分显示状态为“仿真”时,此时
可以直接下载程序,点击菜单栏的“调试”-->“启动”即可。

图 9.x 仿真模式视图

8.5.2 仿真示例

开始下载时,对话框提示仿真器中没有程序,点击“是”,继续,如图 9.x 所示。

图 9.x 提示没有程序对话框
程序体上方的变量声明部分在仿真在线时,作为程序准备、修改、强制变量的部分,是调试程
序中使用最多的功能,常用的功能包括变量采用修改值“写入值”,快捷键[Ctrl]+[F7] ,对输入点
变量采用“强制值”,快捷键[F7],强制变量后“取消强制”。程序编写部分在先后成为在线程序
显示区,程序中的布尔变量会显示运行时的实际值,如 TRUE 或 FALSE,数值型变量或枚举型变
量会显示当前值,如图 9.x 所示。

图 8.x 程序在线后各功能区
8.6 PLC 脚本功能
该 PLC 脚本是一个基于文本的控制监视(终端)。从控制器中得到的具有特定信息的命令以
一个输入行进行输入并且作为一个字符串发送到控制器,返回相关的字符串在浏览窗口中的结果显
示,这个功能用于诊断和调试目的。

图 8.x 脚本画面
PLC 脚本具体的命令如表 8-x 所示,鼠标双击选中“Device”,在右边视图中找到“PLC
shell”,在下方的命令输入框中输入相应指令即可。输入“?”,按回车键即可显示所有该控制器
支持的命令。

表 8-x 脚本命令
命令 描述
? 显示所有可使用的脚本命令
getcmdlist 内部使用显示所有可获得命令
mem <address> [<size>] 显示十六进制特定内存范围
applist 显示当前加载的应用列表
pid [<app name>|<app index>] 一个特定的跳转或者所有加载的应用
pinf [<app name>|<app index>] 一个特定的跳转工程信息或者所有加载的应用
startprg [<app name>|<app index>] 启动一个特定的或者所有的应用程序
stopprg [<app name>|<app index>] 停止一个特定的或者所有的应用程序
resetprg [<app name>|<app index>] 复位一个特定的或者所有的应用程序
resetprgcold [<app name>|<app index>] 针对特定的或者加载的应用执行冷复位
reload[<app name>|<app index>] 重新加载一个特定的或者从启动工程中的加载的应用
getprgstat [<app name>|<app index>] 获得一个特定或者加载应用的状态
plcload 获得加载到 PLC 中的负载率
rtsinfo 显示实时核运行系统信息

注意:
如需使用脚本功能必须先登入 PLC 才能使用相应指令。

【例 8.x】使用 PLC 脚本指令查看 PLC 的运行负载量。


例如,使用 PLC 脚本指令“plcload”来实时的 PLC 负载率。

图 8.x plcload 示例
如图 8.x 所示,得到的 5%则为当前实时的 PLC 负载率。通常,建议将 PLC 的负载率控制在 80%
以下。如果超出该百分比建议优化程序。
【例 8.x】启动/停止应用中的程序。
实现该功能需要使用 startprg 和 stopprg 功能,在命令行输入“?”,根据提示,按照指令格式
输入命令+应用程序的名字,命令如下:
startprg [application]
stopprg [application]

图 8.x 脚本命令执行启动/停止程序
执行上述两条命令后的结果如图 8.x 所示,分别对该应用程序执行了启动和停止程序的功能。
第9章 可视化界面建立及应用
本章主要知识点
 可视化界面的介绍
 可视化界面的编辑
 可视化界面的实际应用

当在编辑一些复杂程序时,我们对程序或功能块的执行结果还不一定有把握时,我们可以先不
用编辑复杂的程序,而可以使用可视化界面来操作功能块或程序,使用可视化界面来观察执行状态,
达到验证操作的目的。该功能能够方便调试人员减少调试时间,提高效率。
可视化对象可以在对象管理器中的“可视化界面”中进行管理,它包含可视化元件的管理并且
对不同的对象可以根据个人需要进行管理。一个 CoDeSys 工程文件中可以包含一个或多个可视化
对象,并且相互之间可以通讯连接。

图 9.x CoDeSys 可视化界面


通过图形编辑器,可以把程序内部变量的数值实时的显示在界面中,如图 9.x 所示,通过这些
变量在图形中的变化,能直观的观察到程序运行的状况。
9.1 CoDeSys 可视化界面
采用可视化编辑器,可以把内部变量的数值动态的显示在界面中,如图 9.x 的 a)所示,通过
这些变量在图形中的变化,就能直观的观察到程序运行的状况。
此外,CoDeSys 还在特定的库文件中提供了一些专用的模板,如图 PLCopen 的可视化界面,
如图 9.x 的 b)所示。

a) b)

图 9.X 可视化界面视图
a )可视化界面简单应用 b ) PLCopen 可视化界面模板
如上所示的这些界面的编辑都是通过 CoDeSys 系统自带的工具箱来完成的,如图 9.x 所示。

图 9.x CoDeSys 可视化界面编辑工具箱


在工具箱界面内,可以看到五类,基本的,通用控制、报警管理、测量控制、灯/开关/位图及
特殊控制这六类,个类别作用如表 9-x 所示。可以通过鼠标将这五大类下的元素拖拽至编辑区,既
可以打开这个元素的属性编辑框来编辑各种属性。

表 9-x 常用工具箱的作用
工具分类 描述
基本工具 提供了如矩形框,圆框等
通用控制工具 通用控制工具
报警管理 报警显示工具
测量控制 提供了如电位器、也为表等显示工具
等/开关/位图 提供了指示灯及不同类型的开关按钮工具
特殊控制 提供了特殊控制工具如趋势图,ActiveX 插件等

9.2 基本操作
可视化编辑器的基本操作包括创建可视化界面、添加工具、对齐工具及删除工具等,在以下内
容中将会对这几种操作进行讲解。

9.2.1 创建可视化界面

“添加对象”-->“视图”,如图 8.x 中的 a)所示。在弹出的视图对话框中输入可视化视图名


称,如“Visualization”,如图 8.x 中的 b)所示。

a) b)
图 9.X 创建视图
a )添加对象 b )输入视图名称
确认打开,则完成添加可视化编辑器。

9.2.2 添加工具

可以通过“编辑区直接绘制工具”及“将工具拖拽到编辑区上”这 2 种方式添加工具。
编辑区直接绘制工具
a) 编辑区直接绘制工具
在工具箱中选择要添加的工具,然后在画面编辑区选择要放置的位置,工件按指定的大小和位
置添加到视图编辑区中。
b) 将工具拖拽到编辑区上
在工具箱中电机要添加的工具并将其拖拽至画面编辑区上,工具以其默认大小添加到画面编辑
区指定区域。

9.2.3 对齐工具

选定一组工具,这些工具需要对其。在执行对齐之前,首先选定主导工具(首先被选定的工具
就是主导工具)。最终位置取决于主导工具的位置,再选择菜单中的对齐方式。如图 9.x 所示。
左对齐

图 9.X 对齐工具快捷按钮
a) 左对齐:将选定的工具沿它们的左边对齐。
b) 水平居中对齐:将选定的工具沿它们的中线点水平对齐。
c) 右对齐:将选定的工具沿它们的右边对齐。
d) 顶对齐:将选定的工具沿它们的顶边对齐。
e) 垂直居中对齐:将选定的工具沿它们的中心点垂直对齐。
f) 底对齐:将选定的工具沿它们的底边对齐。

9.2.4 删除工具

删除工具的方法很简单,可以选中相应工具,电机鼠标右键,选择“删除”,或者直接选中,
按下[Delete]键即可。

9.3 工具
9.3.1 基本工具

基本工具主要包括一些常用的图形制作工具,可以用这些工具制作文本输入/显示框、颜色显
示框及图像等,基本工具视图如 9.x 所示。
图 9.X 基本工具视图

1. 文本输入/显示框
在 CoDeSys 中没有独立的文本框,如要需要制作文本或者数值的显示/输入可以通过添加“矩
形/圆角矩形/椭圆”框来实现,如图 9.x 所示。如下详细介绍矩形框的一些常用设置。

图 9.X 矩形/圆角矩形/椭圆
1) 创建显示文本框
如要实现数据的显示,需要有两个步骤,第一,建立变量映射关系,第二,为显示的变量类型
做设置,如下详细介绍了这两个步骤。
a) 变量映射
通过设置属性中的“文本变量”,点击输入助手进行相关变量的映射。设置完成确认即可,如
图 9.x 所示。

图 9.X 变量触发方式选择
b) 显示类型
如果在文本中包含%s,则在线模式时,该位置将被变量分类中的“文本”字段中的变量值所
替代。除了“s”之外,还可以使用标准 C-库函数 sprintf 中相同的其他格式化字符串,如表 9-x 所
示。

表 9-x 文本显示命令
字符 描述
d,i 十进制数
o 无符号八进制数
x 无符号十六进制数
u 无符号十进制数
c 单个字符
s 字符串
f 实数,%<对齐格式><最小宽度><精度>|f 精度定义了都好之后的个数(默认值:6)
注意:
如果想显示一个百分号%并与上面提到的格式化字符串进行组合,则必须输入“%%”,例如输入“Rate
in %%:%s“,则在线模式时,将显示“Rate in %%:12“(加入文本显示的变量当前值为”12“)。
【例 9.x】创建一个文本显示框,用于显示室内的温度。
首先先在属性中添加变量的映射,如图 9.x 所示。

图 9.X 设置映射变量
其次,在属性的“文本”项中输入“Temperature : %4.2f deg”,如图 9.x 所示。“% 4.2f”为
变量的显示所设置,根据表 9-x 所示,%4.2 表示保留宽度为 4 位,小数点后 2 位的实数。其余的均
为固定文本。

图 9.X 设置文本显示类型
程序的运行结果如图 9.x 所示。

图 9.X 实际运行结果视图
2) 创建输入文本框
同文本显示一样,需要设置前两个步骤,此外还需额外增加一个步骤,即设置事件触发。在属
性中“输入配置”中点击“配置”进行事件触发设置,如图 9.x 所示。

图 9.X 设置文本输入
当点击“配置”后,系统自动弹出如下 9.x 的对话框,分别按如下步骤进行设置:
(1) 选择触发的类型,在此需要触发后对变量进行写操作,即“写变量”。
(2) 添加至右边。
(3) 设置输入类型,可以直接使用键盘输入或者可以通过虚拟键盘及虚拟数字小键盘等。
如图 9.x 所示。

a) b)

图 9.X 虚拟键盘
a )虚拟数字小键盘 b ) 虚拟全键盘
(4) 可以选择相关联的输入变量,可以是当前输出显示的变量,也可以在重新关联一个其
他变量。
(5) 处于安全因素的考虑,在此可以设置输入值的上限/下限值保护。
(6) 设置完成,点击“确定”。
2. 颜色指示框
基本工具不仅能作为文本输入及显示,此外,还能作为一个简易的颜色变化框作为指示灯。当
程序内对应的变量为 ON 后,可以通过修改文本框的报警填充颜色从而实现文本框变色的效果。
【例 9.x】创建一个文本框,用红黄绿三种不同的颜色作为交通信号灯的不同状态。
先创建一个可视化界面,用交通灯。
1) 创建图形框
首先,先添加图形,分别添加“矩形”、“圆角矩形”和“椭圆”工具插件,按图 9.x 的方式
进行排布。

图 9.X 创建图形
2) 变量映射及设置
通过设置属性中的“文本变量”,点击输入助手进行相关变量的映射。设置完成确认即可,如
图 9.x 所示。
由于程序运行后最终的效果是要当对应的变量置为 ON 后,相应的指示灯亮起相应的颜色。
首先先在属性中设置触发填充颜色变化的变量,如图 9.x 的 a)所示,例如将中间的圆形图案
的触发变量设置为 PLC_PRG.b_YE 后,当该变量在程序中被置位 ON 后,则会根据默认的填充颜
色进行变化。
如图 9.x 的 b)设置的是其报警状态的填充颜色,所谓报警状态即当变量变为 1 的状态。由于
在此应用中,需要当 PLC_PRG.b_YE 置为 ON 后,需要亮黄色,则在“填充颜色”中将其设置为
黄色即可。

a) b)
图 9.X 设置颜色变量
a ) 设置触发颜色 b )设置报警状态填充颜色
根据上述步骤,对 3 个指示灯依次进行设置。当运行程序后,分别将程序中的三个变量置为
ON,图 9.x 为实际运行后的结果。

图 9.X 交通指示灯

9.3.2 通用控制工具

通用控制工具主要包括一些常用的图形制作工具,可以用这些工具制作标签、组合框、表格控
制、按钮等,通用控制工具如 9.x 所示。下文会对这些工具进行逐一讲解。

图 9.X 通用控制工具

1. 标签
标签控件主要用于显示用户不能编辑的文本,标识窗体上的对象(例如,给文本框、列表框等
添加描述信息)。在工具箱中找到“ ”,进行添加。
1) 设置标签文件
直接在标签控件(Label 控件)的属性面板中设置“文本”属性。
图 9.X 标签属性
2) 显示/隐藏控件
可以通过设置“不可见”来设置显示/隐藏标签控件,如果 Invisable 对应的变量属性为 True,
则隐藏控件,反之如为 False,则显示控件。
2. 组合框
组合框分为组合框整数和组合框数组两种,下文会对这两种组合框依次进行介绍。
1) 组合框整数
允许用户根据下拉菜单选择想要写入的整型数据,该数据最终会被写入到变量中。
(1) 建立整形数据
在 POU 程序中首先先建立一个整型数据,具体内容如下。
PROGRAM PLC_PRG
VAR
iAmp:BYTE;
END_VAR
(2) 创建组合框整数
在可视化编辑画面区打开工具箱中,找到 “通用控制”大类,添加其中的
“ ”。
a) 变量映射
通过设置属性中的 “变量”,映射最终写入程序的的整型数据。可以通过输入助手进行编辑,
如图 9.x 所示。此外可以通过对“最大值”的设置显示该整型数据的输入最大显示数量。
a) b)

图 9.X 整数下拉菜单
a )变量映射 b ) 显示视图
(3) 设置子范围
如果不设置子范围,该下拉菜单的默认其实数值为 0,可以通过设置“子范围”来进行更改。
如图 9.x 中所示,首先先开启子范围使能选项,并将开始索引设置在 11,结束索引设置在 15,
点击“确定”。如图 9.x 的 a)图所示,最终程序的运行结果如图 9.x 的 b)所示。

a) b)

图 9.X 子范围设置
a )子范围设置 b ) 最终视图
2) 组合框数组
允许用户选择数组列表中的数据,选中后会将数组中的行数据写入到该变量中。
【例 9.x】定义一个二维数组,通过在可视化界面中选择相应的行数,将该行数据写入程序中。
(1) 建立数组数据
在 POU 程序中首先先建立一个二维数组变量,并赋予相应初值,并建立对应写入的行数据整
形变量,具体内容如下。
PROGRAM PLC_PRG
VAR
iFactor:BYTE;
arrFactor: ARRAY [0..2, 0..4] OF STRING := ['BMW','Audi','Mercedes','VW','Fiat',
'150','150','150','150','100','blau','grau','silber','blau','rot'];
END_VAR
(2) 创建组合框数组
在可视化编辑画面区打开工具箱中,找到 “通用控制”大类,添加其中的“ ”。
其次设置数据组变量映射及行信息变量的映射关系。
a) 变量映射
通过设置属性中的“数据组”将数组变量的映射关系给建立起来。“变量”为最终写入程序的
的行数据。两个属性都可以通过输入助手进行编辑,如图 9.x 所示。
图 9.X 组合框数组变量映射
b) 设置数组列
该属性可以自动根据所链接的数组里来判断有多少个列,并将每个列的属性逐一显示,可以将
其都使能。打开扩展“+”符号,可以设置其宽度等相关信息,如图 9.x 所示。

图 9.X 设置列显示信息
(3) 程序运行
完成上述步骤后,所以设置已经完成,可以执行程序,在可视化界面中选择“Fiat,100,rot”这
一组数据,相对应数组是第 5 行元素,但数组号是 4,最终结果如图 9.x 所示。

图 9.X 组合框数组选择

3. 表格控制
表格控制可以添加多个选项卡,然后再选项卡上添加子控件。这样就可以把窗体设计成多页,
是窗体的功能划分为多个部分。表格控制中可包含图片或其他控件。
添加该工具后,可以配置其属性,配置界面如图 9.x 所示,可使用该工具调用其他可视化界面。
图 9.X 表格控制框架配置界面
修改属性中的“标题”,可以更改可视化界面中标题的名称。

图 9.X 设置引用标题
设置完成后,即可直接运行程序,图 9.x 即为实际的运行结果,可以通过左上角选择不同的选
项卡从而实现画面的切换功能。

图 9.X 表格控制运行效果

4. 按钮
按钮控件允许用户通过单击来操作执行。按钮控件既可以显示文本,也可以显示图像。当该控
件被单击时,可以通过属性选择其触发方式。
在工具箱中,找到“通用控制”,找到其中的“ ”,并将其添加至可视化编辑区。
打开按钮的输入配置属性,如图 9.x 所示。

图 9.x 按钮属性
下面介绍按钮控件常用的设置。
1) 响应按钮的事件触发
【例 9.x】创建一个按钮,当单击按钮控件时,执行一段特定的 ST 代码。
通过按钮属性选择“输入配置”-->找到“OnMouseDown”,即当鼠标点击此元素时,则执行
此事件。在写变量中选择编辑类型 VisuDialogs.Keypad。如图 8.x 所示。

图 9.x 输入配置
点击“配置”,弹出对话框如图 9.x 所示,找到“执行 ST 代码”指令,并在右侧输入对应的
ST 代码即可。
图 9.x 按钮触发事件
2) 将按钮设置为“点动、触发”型按钮
通过设置按钮的“切换”或“触发”属性,可以将其设置为点动或触发类型按钮。
【例 9.x】在可视化界面中创建两个按钮,将他们作为点击的正反转 JOG 点动按钮作,当按下
正转按钮时,电机进行正转,放掉按钮时,电机停止。按反转按钮时,点击反转,放掉按钮,电机
停止。
在工具栏中添加两个按钮至可视化界面的编辑区域,在属性的“文本”中可编辑在按钮上需要
显示的标记,如“++”或“--”,如图 8.x 所示。

图 9.X Visualization 中的视图


根据要求,最终要实现的效果为点动,即当按下按钮时有信号,松开按钮时,该信号自动消失,
此种方式在属性的“输入配置”中选用“切换”的输入方式,在其“变量”中通过输入助手找到与
其相关联的映射变量,点击确认完成设定,如图 9.x 所示。
图 9.X 变量触发方式选择
如果想要换一种按钮的触发方式,即当按钮被按下时,该变量一直被置为 ON,如果想要让他
变为 FALSE,需要手动再触发一下按钮。此时,需要在图 8.x 中的 2)中对其“触发”属性进行设
置,在其子索引下的“变量”中与想要的变量关联即可。
5. 复选框
复选框用来表示是否选取了某个选项条件,常用于为用户提供具有是/否或真/假值的选项。
下面介绍复选框的基本使用方法。
(1) 创建复选框
在可视化编辑画面工具箱中,找到 “通用控制”大类,添加其中的“ ”。
a) 创建程序变量
首先需要建立与可视化界面相对应的程序变量,具体变量定义如下所示:
PROGRAM PLC_PRG
VAR
bBool1,bBool2,bBool3:BOOL;
END_VAR
b) 变量映射
在可视化界面的编辑区选中复选框,通过设置其属性中的 “变量”建立与程序映射关系,通
过设置属性中的 “变量”,映射最终写入程序的的布尔变量数据。

图 9.X 设置映射变量
(2) 程序运行
将上述的三个变量都与可视化界面中的三个复选框连接后,最终可视化中的复选框相应的打上
勾后,如图 9.x 的 a)所示,在其中的 Var1 前打上勾后,程序中对应的布尔变量也被置位 TRUE,
如图 9.x 的 b)所示。

a) b)

图 9.X 复选框
a ) 复选框 b )程序变量状态
6. 单选按钮
单选按钮为用户提供由两个或多个互斥选项组成的选项集,用户选中某个单选按钮时,同一组
中的其他单选按钮将不能被同时选定。
下面介绍单选按钮的基本使用方法。
(1) 创建单选按钮
在可视化编辑画面工具箱中,找到 “通用控制”大类,添加 “ ”。添加后在编
辑区的视图如图 9.x 所示。

图 9.X 添加单选按钮
a) 创建程序变量
首先需要建立与可视化界面相对应的程序变量,具体变量定义如下所示:
PROGRAM PLC_PRG
VAR
nSelect:INT;
END_VAR
b) 变量映射
单击选中“单选按钮”,打开其属性,如图 9.x 所示。
首先,先与程序中的变量进行映射,该变量的类型为整型,使用输入助手,点击确定。
其次确定实际需要有多少个单选按钮,如图 9.x 的 2)中所示,添加单选按钮,最终在“文本”
选项中更改名字。
图 9.X 设置单选按钮映射变量
(2) 程序运行
如图 9.x 的 a)中所示,共有 5 个选项,任一时刻只能选中其中的一个,如程序运行后选中
“Mercedes”,程序中将自动将其对应为 2(该计数从 0 开始)。如果选择“VW”,则“nSelect”
为 3。

a) b)
图 9.X 单选按钮
a ) 单选按钮选择 b )程序对应变量状态
7. 数值调节钮控件
数值调节按钮控件是一个显示和输入数值的控件。该控件提供一个上下箭头,用户可以单击上
下箭头选择数值,也可以直接输入。该控件的属性可以设置数值的最大值,如果输入的数值大于这
个属性的值,则自动把数值改为设置最大值。反之,如果输入的数值小于这个属性的值,则自动把
数值改为设置的最小值。
下面介绍单数值调节钮控件的基本使用方法。
(1) 创建数值调节钮
在可视化编辑画面工具箱中,找到 “通用控制”大类,添加 “ ”。添加后
在编辑区的视图如图 9.x 所示。

图 9.X 添加数值调节钮
a) 创建程序变量
首先需要建立与可视化界面相对应的程序变量,具体变量定义如下所示:
PROGRAM PLC_PRG
VAR
nSelect:INT;
END_VAR
b) 变量映射
先与程序中的变量进行映射,该变量的类型为整型,使用输入助手,点击确定。

图 9.X 添加数值调节钮变量映射
(2) 创建事件触发
也可以通过点击数值框直接输入具体数值来实现更改程序内的数据,但需要通过设置属性中的
事件触发来实现此功能,如图 9.x 中,首先选择“输入配置”中的“OnMouseDown”,点击“配
置”,连接最终的变量,并可以设置允许的最大值及最小值。

图 9.X 添加触发事件
(3) 程序运行
如图 9.x 的 a)中所示,可以通过上下按键进行程序内的数值更改,修改完,程序内的变量也
会做相应的更改,如图 9.x 的 b)所示。
a) b)

图 9.X 数值调节钮控件
a ) 数值调节钮 b )程序变量状态
此外也可以通过点击空白处的数值显示框,由于已经设置了事件触发,当按下鼠标后,系统会
自动弹出数值键盘,可在其中输入具体数值,如图 9.x 所示。

图 9.X 数值输入

8. 组块
组块工具主要是为了其他工具提供分组,按照工具的分组来细分可视化界面的功能。其在所包
含的工具集周围总是显示边框,并且可以显示标题,但是组块工具中不能使用滚动条,图 9.x 的 b)
为组块工具的视图。
如下,新建一个分组框控件,在工具箱中找到 “ ”工具,并将添加至画面编辑区域,
鼠标选中该工具,在属性的“文本”中可以更改名字,如图 9.x 的 a)所示,最终运行结果如图 9.x
的 b)所示。将需要分组的工具拖拽至该组块中,即能实现工具的的分组。

a) b)

图 9.X 组块工具
a ) 文本属性修改 b )显示效果
9. 文本区域
通过这个元素可以进行文本显示,文本是通过直接在元素属性中输入或者通过“文本变量”的
帮助实现。不同于矩形框,此工具与普通的矩形框相比,它的优势在于可以逐渐变化。
其主要功能与矩形框类似,可参照 9.3.1 的内容。

9.3.3 测量控制

测量控制工具主要包括一些常用的图形指示工具,例如显示图像栏,仪表盘显示和直方图显示
等。测量控制工具如图 9.x 所示。下文会对这些工具进行逐一讲解。

图 9.X 测量控制工具

1. 显示图像栏
显示图像栏,也可以称其为条状图,在工具箱选择“测量控制”中的“ ”,其
效果图如图 9.x 所示,通常可以它来显示在一个固定区间活动的数值,如液位的显示,气源输入的
压力显示即温度的显示等。

图 9.X 显示图像栏
该命令能显示指定变量的值,并以柱(条)状图来表明其值的变化。当按按下鼠标左键并拖动
后,将形成一个选定大小的区域,图形显示前先会弹出一个属性对话框'配置棒图显示',在其中可
以定义表中要显示的变量参数,并在确认插入前预览完成定义后的图形。
下面介绍显示图像栏工具的基本用法。
(1) 创建显示图像栏
在工具箱选择“测量控制”中的找到添加的显示图像栏,将其添加至可视化编辑区中。
(2) 变量映射
该显示图像栏的变量映射需要进行设置,在属性中的“值”中进行定义,可以使用输入助手进
行设置,如图 9.x 所示。
(3) 设置刻度范围
可以设置里程表的“刻度始段”、“刻度末端”和“子刻度”,设置选项在 9.x 中所示。
图 9.X 显示图像栏的属性设置
完成上述设置,就能够使用基本的显示图像栏工具了,根据上述设置,程序运行,实际运行效
果如图 9.x 所示。

图 9.X 显示图像栏运行视图

2. 仪表
根据已设定的上限值、下限值对应的相对值,以仪表(针摆)显示变量数值的功能。在 CoDeSys
V3 的版本中,共有 3 种仪表盘可供选择,90°、180°和 360°。
下面介绍仪表盘工具的基本使用方法。
(1) 创建仪表
在工具箱选择“测量控制”中的找到想要添加的里程表。在此例中介绍其中的 90°的里程表。
将其添加至可视化编辑区中。
(2) 设置刻度范围
可以设置里程表的“刻度始段”、“刻度末端”和“子刻度”,设置选项在 9.x 的 a)中所示,
其定义可以在 9.x 的 b)中所示。
a) b)

图 9.X 刻度设置
a ) 刻度设置 b )刻度视图
(3) 变量映射
该仪表盘指针的变量映射需要进行设置,在属性中的“值”中进行定义,可以使用输入助手进
行设置,如图 9.x 的 a)所示。
(4) 设置显示精度
刻度格式(C-语言语法):依据 C 语言语法定义刻度标号的格式;参看属性中“标签”中的
“刻度格式(C-语法)”,其默认值为“%1.1f” ,则表示刻度值用一位小数的浮点数表示。如
“12.1” 。如图 9.x 的 b)所示。

a) b)

图 9.X 变量设置
a ) 变量映射 b )显示精度
3. 直方图
直方图又称质量分布图,是一种几何形图表,柱状图,它是表示数据变化情况的一种主要工具。
用直方图可以比较直观地看出产品质量特性的分布状态,对于分布状况一目了然,便于判断其总体
质量分布的情况。
下面介绍直方图工具的基本使用方法。
(1) 创建直方图
在工具箱中的“测量控制”中添加直方图“ ”,并将其拖拽至画面编辑区,如图
9.x 所示。
(2) 变量声明
程序变量定义,在程序中需要根据定义一个数组变量,如下所示:
PROGRAM PLC_PRG
VAR
arrnOut:ARRAY [0..6] OF INT;
END_VAR
(3) 变量设置
首先在属性中找到“数据组”,使用输入助手将其与程序中的变量做映射。

图 9.X 直方图属性设置
其次,使能使用子范围,在“使用子范围”上打上勾即可。修改“数据子范围”中的“开始索
引”和“结束索引”可以设置在该直方图中显示的变量的数量。
将上述的参数设置后,可以修改图形显示的类型,暂时将其设置为“栏”,也可以设置为“行”
及“曲线”,具体区别如表 9-x 所示。

表 9-X 直方图显示类型
显示类型 图例

曲线

(4) 设置报警颜色
当数值超过/少于某个设定值,既可以使用报警颜色。如图 9.x 所示的参数,即当其中的数值大
于等于 60 时,则启用报警颜色来对直方图进行显示。

图 9.X 直方图颜色设置
按上述步骤设置完成后,即可运行程序,手动将数组中的子索引数值进行赋值,最终的效果如
图 9.x 所示。

图 9.X 直方图运行效果图

4. 电位器
电位器是当电刷沿电阻体移动时,在输出端即获得与位移量成一定关系的电阻值或电压,在此,
根据滑动的位置,将其转换为对应的数值。
下面介绍电位器工具的基本使用方法。
(1) 创建电位器
在工具箱中的 “测量控制”中找到“ ”,将其添加至画面编辑区域。
(2) 变量声明
程序变量定义,在程序中需要根据定义一个数组变量,如下所示:
PROGRAM PLC_PRG
VAR
nInput:INT;
END_VAR
(3) 变量映射
首先先打开属性设置,对变量进行映射,如图 9.x 中的第 1)步所示。
其次,展开“刻度”子属性,可以对电位器的“刻度始端”和“刻度末端”数值进行设置修改,
主刻度和子刻度的长度也可以在该属性中进行相应的修改,如图 9.x 中的第 2)步所示。

图 9.X 电位器参数设置
(4) 程序运行
设置完对刻度进行设置,该旋钮作为输入左右可以设置。

a) b)

图 9.X 电位器旋转
a ) 电位器旋钮 b )变量视图
图 9.x 中的 a)为最终显示的效果图,在程序中的实际变量的数值如 9.x 的 b)所示。

9.3.4 灯/开关/位图

灯/开关/位图控制工具主要包括一些常用的开关和指示灯。灯/开关/位图工具如图 9.x 所示。下


文会对这些工具进行逐一讲解。
图 9.X 灯/开关/位图工具

1. 位接触开关
在 CoDeSys V3 的工具箱中可以选择的位接触开关有很多种形式,有拨码开关、遥感开关和旋
转开关等,汇总表如表 9-x 所示。

表 9-x 位接触开关
开关类型 开关图示 开关类型 开关图示
拨码开关 带 LED 的按
键开关

电源开关 摇杆开关

按键开关 旋转开关

(1) 创建开关
在工具箱中找到“灯/开关/位图”,在其中添加想要选择的接触开关,将其拖拽至画面编辑区
域,由于开关的设置基本相同,在此不做重复介绍,只以其中的一种按钮做详细介绍,下文的介绍
以拨码开关为例。
(2) 变量映射
如图 9.x 所示,在属性中的“变量”中可以设置拨码开关的映射变量。

图 9.X 变量映射
至此,拨码开关的基本设置已经完成。用户可以根据实际的需要在“背景”属性中的“背景图
像”中设置想要的颜色。
2. 位指示灯
根据布尔型变量的 ON/OFF 使对应的指示灯亮/灭的功能。位指示灯的显示如图 9.x 的 a)所示。

a) b)

图 9.X 位指示灯属性
a )指示灯显示 b )指示灯属性
(1) 创建指示灯

在工具箱中找到“灯/开关/位图”,在其中添加 “ ”按钮,将其拖拽至画面编辑
区域。
(2) 变量映射及颜色设置
如图 9.x 的 b)所示,在属性中的“变量”中可以设置指示灯的映射变量,在背景图像中可以
设置指示灯的默认颜色。。
至此,拨码开关的基本设置已经完成。用户可以根据实际的需要在“背景”属性中的“背景图
像”中设置想要的背景颜色。

9.3.5 特殊控制

特殊控制工具主要包括一些常用的图形指示工具,例如趋势图、ActiveX 元素等。特殊控制工
具如图 9.x 所示。下文会对这些工具进行逐一讲解。

图 9.X 特殊控制工具

1. 趋势图
分析控制系统故障常常需要了解控制器数据的变化,有时数据变化是一闪而过的,不容易看出
产生故障的原因,利用趋势图可以实现对数据的快速捕获。
1) 在画面编辑区域添加趋势图插件
在工具箱中找到“特殊控制”,添加“ ”,左键鼠标将其选中,将其拖拽至画面编
辑区,如图 9.x 所示。
图 9.X 添加趋势图 Trace
2) 配置趋势图
选中 Trace 插件,单击鼠标右键,选择“Configure trace”,如图 9.x 所示,单击后即可以进入
趋势图配置界面,图 9.x 为趋势图的配置界面。

图 9.X 趋势图配置选择菜单
图 9.X 趋势图配置
首先,先选择任务,任务的刷新频率决定了数据采样的频率。
其次,选择要查看曲线的变量,选择“添加变量”,弹出如图 9.x 所示的提示框,点击红色阴
影部分,使用输入助手选择对应程序中的变量。在其中可以选择变量对应曲线颜色,线的类型及采
样点的类型等。

图 9.X 变量配置
针对此例,选择“PLC_PRG.iOut”作为输出,按该 GEN 的功能块输出,最终在可视化界面中
应该看到的是他的正弦波形。
设置完映射的变量后,需要设置 X 与 Y 坐标的最小值与最大值,可以使用默认的自动方式,
编程人员也可以使用固定长度的方式设置 X 与 Y 轴的数值。
a) b)

图 9.X 设置的 X 轴和 Y 轴的最大值与最小值


a )X 轴配置界面 b ) Y 轴配置界面
配置缓存,用来设置采样频率,频率越高,则在可视化界面中采集的点越多,越能清楚的描述
实际情况,但带来的影响则是会造成系统过多的消耗内存。设置界面如图 9.x 所示。
如图 9.x 中所示,在此界面中可以设置采样的频率,选择 X 经过多少个周期进行一次采样,在
此配置中,采用每 10 个周期进行一次数据的采样。

图 9.X 缓存配置界面
在主配置界面中的“从跟踪中复制选项”能将在跟踪中的变量配置信息复制至趋势图中。
当上述设置都完成时,此时已经能在程序中显示数据的趋势图了,保存之前的程序,点击“在
线”-->“登入到”,“调试”-->“启动”程序即可,如图 9.x 为运行的实际结果。
图 9.X 趋势图显示
3) 配置趋势图控制插件
选中趋势图,单击鼠标右键选择“Insert elements for controlling trace…”,如图 9.x 所示,进行
添加控制插件。

图 9.X 右键选择“Insert elements for controlling trace…”


点击后,会弹出 9.x 中 a)的对话框,可以选择要添加的按钮及显示框,默认参数将所有控制
按钮就选上,点击“OK”,系统自动弹出如图 9.x 中 b)所示的按钮及显示框。

a) b)

图 9.X 添加趋势图插件
a )插件配置界面 b )插件视图
2. ActiveX 元素
ActiveX 在 一 个 可 视 化 中 被 服 务 于 现 实 ActiveX 控 制 。 该 元 素 可 用 于 Windows32 系 统
Visualization 中。
双击插入的元素可以打开配置对话框,并提供有三个字对话框,分别用于选择初始调用,循环
调用及条件调用,具体区别如下所示。
 初始调用:初始化时要进行调用的方法可以在这里进行定义,只在第一个周期进行处理。
 循环调用:可视化中周期调用的方法可以在该属性下进行定义,可以在每个可视化执行周
期事件中进行更新。
 条件调用:附加的一个“条件调用”可以被关联。条件方法调用可以在可视化事件更新的
时候进行调用。不同于初始或者循环调用,条件调用可以关联到属性方法。只在条件调用
的上升沿进行处理。
下面介绍 ActiveX 元素的基本使用方法。
1) 在画面编辑区域添加“ActiveX 元素”插件
在“特殊控制”中添加“ ”的 ActiveX 插件,将其拖拽至画面编辑区域;在
“控制”中,如图 9.x 的 a)中所示,可以通过输入助手来选择不同的插件类型,如图 9.x 的 b)所
示。

a) b)

图 9.X 添加 ActiveX 属性
a )控制属性 b )可选择的控制插件
2) 配置 “ActiveX 元素”的属性
在属性中有共有三种触发方式可供选择,初始、循环及条件调用的方式,如图 9.x 所示。

图 9.X ActiveX 的触发方式选择


3) 进行变量映射
点击“ ”创建新的触发方式,当期菜单展开后,将必要的参数填写至其中。
【例 9.x】通过 ActiveX 功能,当相应变量收到上升沿触发信号后播放视频。
添加 ActiveX 空间,并将其属性中的“控制”选择为“WMPlayer.OCX.7”,如图 9.x 所示
a) b)

图 9.X 设置 ActiveX 属性
a )画面编辑区域 b )条件调用属性
该示例选用“条件调用”的方式调用该 ActiveX 插件,具体的参数如图 9.x 的 b)所示,“调
用条件”—>“变量”为触发变量,当该变量有上升沿信号触发时,调用该 Active 插件。“参数”
—>“变量”为 strPara 作为系统的参数,可以将该视频文件的物理地址存放在该参数内,以便程序
运行后导入该视频。
在程序中内部的变量声明为:
PROGRAM PLC_PRG
VAR
bStart:BOOL;
strPara:STRING:='C:\Windows\Performance\WinSAT\Clip_1080_5sec_VC1_15mbps.wmv';
END_VAR
在程序中将 bStart 置为 True,运行程序后,最终的效果图如图 9.x 所示。

图 9.X ActiveX 播放视频示例


示例程序可以在 Sample\第九章\ActiveX\下进行查看。
3. 路径 3D
路径 3D 能够显示一个 3D 路径 。该元素用于显示一个机床或机器人的运动路径。如果是一个
机床工具/CNC 编辑器,该路径为理想轨迹,同时这个元素也可以被用于多个其他的应用中。
除了显示路径,所有的命令轨迹点数组将会被显示。如果是机床工具/CNC 编辑器,轨迹将会
显示 所有的真实的轨迹。
(1) 创建路径 3D
在工具箱中找到“灯/开关/位图”,在其中添加“ ”,将其拖拽至画面编辑区域。
路径 3D 需要配置的属性参数如图 9.x 所示。
图 9.X 路径 3D 配置
在主程序中,声明了 VISUStruct3Dcontrol 及调用了 PathGenerator 的功能块,该功能块的作用
是用于产生 3D 路径及跟踪轨迹,该轨迹可以存放 2200 个点。这两个变量都与该工具的属性有相应
关系。

(2) 程序编写

FUNCTION_BLOCK VisuStruct3DTrack
VAR_INPUT
pData: POINTER TO ARRAY[0..0] OF VisuStruct3DPathPoint;
udiNumberOfPointsInArray: UDINT;
udiFirstPoint: UDINT;
udiNumberOfPointsToDraw: UDINT;
pProjection: POINTER TO Projection;
END_VAR

pData 指 向 一 个 VisuStruct3DPathPoint 元 素 数 组 。 这 个 数 字 必 须 至 少 含 有
udiNumberOfPointsInArray 个元素。数组必须包含在应用中并且数据指针必须通过应用进行设置。
一个点的说明

TYPE VisuStruct3DPathPoint :
STRUCT
v: Vector3;
udiSourceElementID: UDINT;
dwAddInfo: DWORD;
END_STRUCT
END_TYPE

(3) 变量映射
如图 9.x 所示,在属性中的“变量”中可以设置拨码开关的映射变量。

图 9.X 变量映射

程序最终的运行效果如图 9.x 所示。


图 9.X 路径 3D 示意图
示例程序可以在 Sample\第九章\ActiveX\下进行查看。

9.3.6 报警管理

报警管理工具主要包括报警表格和报警条。报警管理工具视图如图 9.x 所示。

图 9.X 报警管理工具视图

1. 报警表格
用户可以自定义可视化报警,但必须在 CoDesys 报警配置中预先进行定义。在可视化编辑器中,
用户可以通过在工具箱中添加“ ”,将其拖拽至画面编辑区域;
故需要完成报警显示需要有两部分的设置,第一,需要在“Application”中设置报警配置,第
二,需要在可视化编辑器中进行设置。如下对这两个步骤分别作介绍。
1) “Application”添加报警配置
在配置可视化报警列表前需要先配置报警信息,先在“Application”中添加报警配置,右键选
择添加对象,点击“报警配置”,点击确定,如图 9.x 所示。
图 9.x 添加报警配置
所有的报警内容及触发机制均在该报警配置中进行设置,在“Alarm Configuration”中,如图
9.x 的 a)所示,右键选择“添加对象”,选择“报警类别”及“报警组”等信息,如图 9.x 的 b)
所示。

a) b)

图 9.X 添加报警配置
a )报警配置视图 b )添加报警配置对象
a) 设置故障类型
默认添加报警管理后,自动会将报警分为三类,分别为“Error”,“Info”和 “Warning”。
他们的主要区别在于报警的优先级及确认方式,如下会详细介绍配置的具体说明。配置图如图 9.x
所示。

图 9.x 报警配置
Priority:
定义想要显示的所有报警的优先级。允许的范围:0~255,最高优先级是“0”,最低有效优
先级是“255”。较高或中等优先级的报警通常要求立即确认,而优先级非常低的报警则可能不作
要求。尽管生成报警的条件可能已消失(例如,温度上升得过高,然后又降了下来),但在确认之
前,报警本身并不会被认为已得到解决。在 CoDeSys 中通常有如下的确认方法:
Acknowledgement:
报警发生时,运行时操作员(或系统)必须确认报警。确认只是表示有人注意到该报警。这与
采取修正操作没有关系,后者可能不会立即发生。它同报警条件是否返回到正常也没有什么关系–
有时即便没有任何外界干预,它也可能自行恢复正常,可供选择的确认方式如下所示:
 REP:移除导致的原因后报警不激活
 ACK :确认后不激活。时间段确认方法
 REP_ACK:经过(单个)修复和确认后报警不激活
 ACK_REP:经过确认和修复后报警不激活
 ACK_REP_ACK :接收、修复后经过选择性的确认报警不激活
 NO_ACK: 不确认
Notification actions:
报警动作有变量,执行和调用三种动作可供选择,如图 9.x 所示。

图 9.x 报警动作
变量:选择“变量”,在右侧输入另一个变量或表达式来设置影响报警的分配。通过 可以
调用输入助手进行选择。对于布尔型变量用占位符“ALARM”,整形变量用占位符“STATE”,
字符串变量任意符合 IEC 语法(例如‘to high’)的可以输入来定义一个文本消息。
调用:输入要调用的“功能块实例” 的名字。
执行:输入当报警出现时的 “执行文件”名。 在 “Details”中,可直接键入任意参数调用。
Display option for alarm table/alarm banner:
设置报警时显示字体及颜色。
b) 报警组
鼠标选中 “Alarm Configuration”,右键选择添加“报警组”,可以对报警信息进行设置,可
以在“Observation type”中可以选择报警触发的类型,在 CoDeSys V3.x 的版本中可以选择如图 9.x
中所显示的几种类型。具体说明详见表 9-x 所示。

图 9.X 设置报警观察类型

表 9-x 报警触发类型
触发类型 说明
数码 左侧输入要监视的表达式,右侧输入你要检查的表达式,中间选择想用的操作符 (=
or <>)。
上限 像上述“数码”一样,但是对于比较操作符> 或>=, 有选择的使用“滞后%” 的定义。
下限 像上述“数字”一样,但是对于比较操作符 < 或 <= ,有选择的使用 “滞后%” 的定义。
内范围 键入要监视的表达式。 “区域:”当监视的表达式到达定义的内范围值时,报警出现。在
左侧输入表达式表示下极限,在右侧输入上极限。被监控的表达式显示在不可编辑区
域。合理设置操作符,有选择的使用“滞后%”的定义。
外范围 键入要监视的表达式。 “区域:”当监视的表达式到达定义的外范围值时,报警出现。在
左侧输入表达式表示下极限,在右侧输入上极限。被监控的表达式显示在不可编辑区
域。合理设置操作符,有选择的使用“滞后%”的定义。
更改 “表达式”:键入要监视的表达式。当它的值发生变化时报警出现。
事件 这种情况下报警通过应用触发,使用 AlarmManager.library 的函数。

注意:
“滞后%”:如果使用了滞后,那么报警情况会保持 TRUE,直到达到一个具体的滞后值后才改变。滞后的
大小以极限值的百分比计。例如:上极限: "i_temp >= 30", "滞后 10%,即为 0.1"。当变量 i_temp 达到或
超过 30,报警出现。直到它的值降到 27,报警情况才消失。
例: " PLC_PRG. i_temp > (0.1 * 30) ",此表达式应用了 10%的滞后功能。
2) 可视化编辑区添加报警表
在可视化界面中,添加报警表插件,选中“报警管理”,添加“ ”,将其拖拽至
画面编辑区域,如图 9.x 所示。

图 9.X 报警表格视图
 添加列
如图 9.x 所示,默认添加的报警表只有 2 列信息,用户可以根据实际需要添加更多的列,在属
性中的“列”信息中可以添加列,每加完一个列,可以打开列数组信息修改其宽度及列显示的名字,
具体步骤如图 9.x 所示。
列中需要显示的内容是可选的,在数据类型列中的下拉菜单中可以选择。
图 9.X 列信息修改
修改完的列属性如图 9.x 所示。

图 9.X 添加列后的报警表视图
 控制变量
报警列表中显示的报警需要操作人员的确认,与确认相关的变量在控制变量中可以进行设置。

图 9.x 控制变量
确认所选变量:如果变量为 TRUE,在报警列表中所选中的报警将会被确认。
确认所有可见变量:如果变量为 TRUE,位于警报表格中所有的警报都会被确认。
历史:如果变量为 TRUE,警报表格将会转化为历史模式。这意味着将会按照日期顺序将所有
警报表格降序排列。任何新事件将会被添加到当前表格中。
冻结滚动位置:如果变量为 TRUE,在历史模式下滚动条的当前位置将会被锁定即使有新的警
报被激活。否则,在这种情况下滚动条会跳转到警报表格的第一行
至此,报警相关设置已经结束,以下通过实际的例程来测试一下报警功能。
【例 9.x】设置一个温度报警,当实际温度大于 50 度时,报温度过高报警;当温度小于 10 度
时,报温度过低。
首先,在程序中需要添加实际温度变量,rTemperature_Machine1,类型为实数类型,此外需要
添加确认布尔类型变量 bConfirm。
PROGRAM PLC_PRG
VAR
rTemperature_Machine1:REAL;
bConfirm:BOOL;
END_VAR
在“Application”中添加报警配置并新建报警组,报警组内容设置为上,下限的触发方式,表
达式分别为,并在“Message”添加相应文字报警信息,具体如图 9.x 所示。
PLC_PRG.rTemperature_Machine1 < 10
PLC_PRG.rTemperature_Machine1 > 50

图 9.X 设置上下限
其次,在可视化界面中添加报警表格,添加列属性,默认只有 2 列,可以适当的添加更多的报
警显示信息。此外,还要在属性中设置确认变量,找到“控制变量”,在其中的“确认所有可见变
量”中使用输入助手对应程序中的“bConfirm”作为其确认信号。

图 9.X 设置确认变量
通过强制更改变量 rTemperature_Machine1 的数值,可以模拟实际的报警输出,当故障消失后,
可以强制 bConfirm 信号作为确认故障。最终的实际效果图如图 9.x 所示。

图 9.X 实际运行效果图
该样例程序存放在\Sample\第九章\报警\。
2. 报警条
警报条是警报表格的简单版本。它只可用于报警组和类的单一的警报可视化,并且特殊类别条
元素属性的“警报配置”。
用户在工具箱中选择“ ”,将其拖拽至画面编辑区域,即可实现报警条的工
具添加。
具体操作及设置可参考报警表格的设置。
9.4 视图的建立及编辑
9.4.1 应用举例

本节会通过一些小的例程让读者了解到如何建立。
1. 创建一个开关量
【例 9.x】制作两个输入开关,开关 1 使用旋转开关,开关 2 使用拨码开关;当开关 1 被打开
时,亮红色指示灯;开关 2 打开时,指示灯亮绿色。
1) 新建可视化视图,并打开视图编辑器,如图 9.x 所示。

图 9.X 视图编辑区

2) 添加工具,点击左侧工具箱,在“通用控制”中选择“ ”及
“ ”,按住鼠标左键,把选中的图标拖到视图编辑器中,此外,在“灯/开关
/位图”中选择“ ”,将指示灯也添加至视图编辑区,如图 9.x 所示。
图 9.X 添加工具
3) 编辑程序,新建 POU,使用 ST 语言进行编程,具体程序如下。
程序变量声明区:
PROGRAM PLC_PRG
VAR
bSwitch_1: BOOL;
bLED_1: BOOL;
bSwitch_2: BOOL;
bLED_2: BOOL;
END_VAR
程序代码编辑区:
IF bSwitch_1 THEN
bLED_1:=TRUE;
ELSE
bLED_1:=FALSE;
END_IF

IF bSwitch_2 THEN
bLED_2:=TRUE;
ELSE
bLED_2:=FALSE;
END_IF
如下的程序只要实现,当开关 1ON 是,指示灯 1 也 ON,开关 OFF 时,指示灯也为 OFF。开
关 2 的逻辑与开关 1 相同。
4) 修改控制开关属性
依次设定拨码开关及旋转开关属性中的“变量”,将开关与程序内的布尔变量产生关联,根据图
9.x 中的框出部分所示,使用输入助手,找到程序中对应的布尔变量。
图 9.X 设置控制开关属性
5) 修改指示灯属性
两个指示灯分别需要设定 ON 和 OFF 的颜色,及设定映射关系,具体操作方法如下所示。
鼠标在编辑器中选中已添加的“指示灯”,在属性中找到“背景”,选择 “背景图像”的下
拉菜单,将指示灯 1 选择为红色,2 选择为绿色,如图 9.x 的 a)所示,最终的结果如图 9.x 的 b)
所示。

a) b)

图 9.x 设置指示灯颜色属性
a )设置指示灯背景属性 b )指示灯最终输出效果
设置完颜色后,需要对两个指示灯进行变量的关联设置,将红色指示灯的“变量”属性通过点
击图 9.x 中的框出部分的按键,弹出输入助手,与程序中的 bLED_1 相关联。

图 9.x 设置指示灯关联变量属性
6) 程序仿真
当完成上述设置后,即可开启 CoDeSys 的仿真模式,开始运行程序,图 9.x 为程序运行后的最
终结果。样例程序可在 Sample\第九章\开关量\中打开。

图 9.x 指示灯 1 处于 ON 状态

2. 创建一个显示和输入界面
【例 9.x】在程序中通过 GEN 功能块生成 SIN 正弦曲线,制作一个画面显示,可以实时的查看
功能块的输出数据,此外,需要一个参数输入接口可以更改输出数据峰值。
1) 在主程序中添加 GEN 功能块,在程序中实例化后的名字为 FB_Gen1,具体代码如下:
程序变量声明区:
PROGRAM PLC_PRG
VAR
FB_Gen1: GEN;
iOut: INT;
iAmp: INT: =100;
bBase: BOOL;
END_VAR
程序代码编辑区:
FB_Gen1(
MODE:= SINe,
BASE:=bBase ,
PERIOD:=T#1S ,
CYCLES:=1000 ,
AMPLITUDE:=iAmp ,
RESET:= ,
OUT=>iOut );
在程序中,由于需要输出的波形为 SIN,故根据手册,需将 MODE 输设置为“SINe”,程序
中默认的输出区间为-100 至 100。
2) 在可视化编辑器中添加工具,点击左侧工具箱,在“基本的”中添加两个“ ”,
一个作为输出数据实时显示,另一个作为输入,可以修改该功能块输出的工作区间。按住
鼠标左键,把选中的图标拖到视图编辑器中,如图 9.x 所示。

图 9.x 添加矩形框
3) 修 改“矩 形”的 属性, 添 加其关 联的两 个变量, 输出数 据“ iOut”及输 出数据 区间
“iAmp”。
在矩形框属性中的“文本变量”中的“文本变量”选择浏览按键,使用输入助手将变量与
程序中的 PLC_PRG.iOut 相关联,另一个则与 iAmp 关联,如图 9.x 所示。

图 9.x 显示变量映射
4) 数据显示,如要显示固定字符,只需在输入框中直接输入即可;如想要在文本中显示变量,
则需要使用 “%”+固定字符的搭配,例如,要显示字符变量,则在文本显示框中输入%s,
s 是 String 的简称,在此,需要将两个文本框中“文本”属性中的“文本”都输入“%s”,
如图 9.x 中所示。

图 9.x 文本显示属性
至此,数值的显示功能已经完成。如下需要设置事件触发,当按钮被按下时,需要弹出数字输
入键盘。
5) 事件触发,当鼠标按下时,触发该事件,需要自动弹出数字输入键盘,如图 9.x 中所示。

图 9.x 文本显示属性
修改文本显示属性中的“输入配置”,事件选择当鼠标按下时,则为“OnMouseDown”,电
机配置,则系统自动会弹出如图 9.x 所示的对话框。
图 9.x 输入按钮事件触发配置
根据弹出的对话框,依次选择事件触发的类型,将其设定为“写变量”;其次,确定输入的类
型,针对此例程的应用,选择数字键盘,如图 9.x 中的 2)所示,为 Numpad。最终,即 3),选择
与输入数值相关联的变量,使用输入助手,选择程序中的 PLC_PRG.iAmp 作为关联。
在“文本变量”中的 “变量”中,使用输入助手,找到与其相关联的变量,点击确定。
6) 插入文本标签
在工具箱中添加“文本标签”,在“通用控制”中找到“ ”,使用鼠标拖拽至画面编
辑器中,编辑属性中的“文本”元素。

图 9.X 修改文本属性
7) 至此,所有程序及属性参数已经完成,开始仿真程序进行测试。
打开仿真模式,将程序“在线”,“登入到”本地计算机,运行程序。点击“Input Value”的
输入框,键入输出范围,将原来的“100”改为“1000”。

a) b)

图 9.X 可视化输出结果
a )数字键盘输入 b )最终输出结果
3. 创建一个趋势图
【例 9.x】在程序中通过 GEN 功能块生成 SIN 正弦曲线,制作一个画面显示,可以实时的查看
功能块的输出数据,此外,需要一个参数输入接口可以更改输出数据峰值。
1) 在画面编辑区域添加趋势图插件
在工具箱中找到“特殊控制”,添加“ ”,左键鼠标将其选中,将其拖拽至画面编
辑区,如图 9.x 所示。

图 9.X 添加趋势图 Trace


2) 配置趋势图
选中 Trace 插件,单击鼠标右键,选择“Configure trace”,如图 9.x 所示,单击后即可以进入
趋势图配置界面,图 9.x 为趋势图的配置界面。
图 9.X 趋势图配置选择菜单

图 9.X 趋势图配置
首先,先选择任务,任务的刷新频率决定了数据采样的频率。
其次,选择要查看曲线的变量,选择“添加变量”,弹出如图 9.x 所示的提示框,点击红色阴
影部分,使用输入助手选择对应程序中的变量。在其中可以选择变量对应曲线颜色,线的类型及采
样点的类型等。
图 9.X 变量配置
针对此例,选择“PLC_PRG.iOut”作为输出,按该 GEN 的功能块输出,最终在可视化界面中
应该看到的是他的正弦波形。
设置完映射的变量后,需要设置 X 与 Y 坐标的最小值与最大值,可以使用默认的自动方式,
编程人员也可以使用固定长度的方式设置 X 与 Y 轴的数值。

a) b)
图 9.X 设置的 X 轴和 Y 轴的最大值与最小值
a )X 轴配置界面 b ) Y 轴配置界面
配置缓存,用来设置采样频率,频率越高,则在可视化界面中采集的点越多,越能清楚的描述
实际情况,但带来的影响则是会造成系统过多的消耗内存。设置界面如图 9.x 所示。
如图 9.x 中所示,在此界面中可以设置采样的频率,选择 X 经过多少个周期进行一次采样,在
此配置中,采用每 10 个周期进行一次数据的采样。
图 9.X 缓存配置界面
在主配置界面中的“从跟踪中复制选项”能将在跟踪中的变量配置信息复制至趋势图中。
当上述设置都完成时,此时已经能在程序中显示数据的趋势图了,保存之前的程序,点击“在
线”-->“登入到”,“调试”-->“启动”程序即可,如图 9.x 为运行的实际结果。

图 9.X 趋势图显示
3) 配置趋势图控制插件
选中趋势图,单击鼠标右键选择“Insert elements for controlling trace…”,如图 9.x 所示,进行
添加控制插件。
图 9.X 右键选择“Insert elements for controlling trace…”
点击后,会弹出 9.x 中 a)的对话框,可以选择要添加的按钮及显示框,默认参数将所有控制
按钮就选上,点击“OK”,系统自动弹出如图 9.x 中 b)所示的按钮及显示框。

a) b)

图 9.X 添加趋势图插件
a )插件配置界面 b )插件视图
点击“Start trace”和“Stop trace”可以控制趋势图的开始和停止,“Reset trigger”可以将触
发信号复位。该例程可以在“\第九章\趋势图\”中打开。
第10章 常用库函数介绍?
第11章 控制系统工程实例
本章主要知识点
 实际工程案例的应用

本章节会针对实际工程来给读者作介绍,从简单的控制系统开始讲解,深入浅出,重点讲解实
例编程的思想、程序执行过程和编程体会,使初学 CoDeSys 的读者能够尽快的掌握编程技巧。

11.1.1 圆盘 180°正反转控制

1. 控制要求
圆盘由电动机拖动,当按下启动按钮后,控制转盘正转 180°后,停留 30s,再反转 180°,并不
断重复上述过程。按下停止按钮,转盘应转 180°到原位,碰到限位开关并停止。若整个过程中有意
外,按下急停按钮后,要求转盘立即停止。
反转 0° 正转

限位开关

圆盘
中控台

启动 停止 急停

图 11.X 圆盘控制示意图
系统的 I/O 地址分配表如表 11-x 所示。

表 11-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 限位开关 bLimited %QX0.0 正转接触器 bCW
%IX0.1 启动按钮 bStart %QX0.1 反转接触器 bCCW
%IX0.2 停止按钮 bStop
%IX0.3 手动开关 bManual
%IX0.4 急停按钮 bEMO
2. 编程
整个圆盘 180°正反转控制系统的变量声明如下:
VAR
bLimmited AT%IX0.0:BOOL;
bStart AT%IX0.1:BOOL;
bStop AT%IX0.2:BOOL;
bEMO AT%IX0.3:BOOL;
bCW AT%QX0.0:BOOL;
bCCW AT%QX0.1:BOOL;
bStarted:BOOL;
bStopped:BOOL;
nCounter:INT;
fb_30Delay: TON;
END_VAR
具体梯形图程序如图 11.x 所示。

图 11.X 圆盘 180°正反转控制梯形图程序
在初始状态时,转盘在原位时限位开关 bLimited 触点受压接通。系统启动时,当按下按钮
bStart,输入信号有效,启动信号 bStarted 为 ON,同时输入信号 bStart 的上升沿执行一次计数加 1,
该计数值的最低位如为“1”,则控制输出信号 bCW 为 ON,触发电机使其正转。转动后行程开关
bLimited 复位,转动 180°后,bLimited 触点又受压接通,在输入信号 bLimited 上升沿产生一个脉冲,
计数器再执行一次自加 1 计算,计数器的最低位变为 OFF,控制输出信号 bCW 复位,圆盘停止转
动。
此时,定时器 fb_30Delay 开始工作,经过 30 秒后,其触点 fb_30Delay.Q 被置为 ON,开始动
作,控制输出信号 bCCW 为 ON,圆盘反转,开始转动后,限位开关 bLimited 被复位,转动 180°后,
bLimited 触点有受压接通,输入信号 bLimited 上升沿再一次产生脉冲,执行一次计数器加 1 指令,
计数器的最低位再次被置为“1”,将输出 bCCW 复位,输出信号 bCW 重新被置为 ON,转盘正转。
正常运行时,程序将重复上述过程。
如果按下按钮 bStop,正常停止信号 bStopped 为 ON,圆盘无论是正转还是反转,碰到限位开
关后将会停止转动。
如果按下按钮 bEMO 后,程序会断开启动信号 bStarted,输出信号 bCW 及 bCCW 都会被置为
OFF,圆盘立即停止。完整的样例程序可在\Sample\第十一章\圆盘 180°正反转控制\中打开。

11.1.2 火警报警系统

火灾报警系统是火灾自动报警系统的中枢,它接受信号并作出分析判断,一旦发生火灾,它立
即发出火警信号并启动相应消防设备。该示例为了说明程序的使用,在实际应用中,控制系统会复
杂的多。
1. 控制要求
图 11.x 是火警区域示意图。该区域内有 3 个火警烟雾探测器,分别由 Device 1、Device2 和
Device 3 这 3 个烟雾探测器监视。当发生报警时,用户可以通过手动按钮用于清除火警报警。为避
免火警监视器的不可靠而错误发生报警信号,该系统采用两个或两个以上的监视器翻换时才报警的
控制手段,该系统被统称为 3 取 2 出连锁系统。

报警清除
Device1 Device2 手动按钮

火警警告
Device3

报警

图 11.X 火警区域示意图
当报警消除后,为了清除报警,应设置清除报警的按钮“报警清除”。系统的 I/O 地址分配表
如表 11-x 所示。

表 11-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 火警烟雾探测器 Device1 %QX0.0 报警 bAlarm
%IX0.1 火警烟雾探测器 Device2 %QX0.1 火警警告 FireWarning
%IX0.2 火警烟雾探测器 Device3
%IX0.3 手动开关 bManual
%IX0.4 报警清除 bClearAlarm
2. 编程
整个火警控制系统的变量声明如下:
PROGRAM PLC_PRG
VAR_INPUT
Device1 AT%IX0.0: BOOL;
Device2 AT%IX0.1: BOOL;
Device3 AT%IX0.2: BOOL;
bManual AT%IX0.3: BOOL;
bClearAlarm AT%IX0.4: BOOL;
END_VAR
VAR_OUTPUT
bAlarm AT%QX0.0: BOOL;
FireWarning AT%QX0.1: BOOL;
END_VAR
VAR
SR1: SR;
END_VAR
图 11.X 火警控制系统的梯形图程序
图 11.x 中,如果任意两个烟雾探测器如果被检测为 ON,则标准双稳态功能块 SR 的实例 SR1
报警功能块的输出 Q1 则会被置位 ON,它将驱动报警线圈“报警”bAlarm 被置位 ON。
只有通过按“报警清除”bClearAlarm 按钮才能消除报警。由于该信号采用上升沿触发方式来
采集信号,故能保证保持在按下时,如有新的报警,系统仍会继续报警。标准双稳态功能块 SR 是
置位优先与复位的双稳态功能块,他能确保在“报警清除”bClearAlarm 信号发生而两个或多个检
测器是 ON 时报警认可继续在 ON。
在该系统中,任何一个烟雾探测器被置位 ON 后,火警警告的指示灯“火警警告”FireWarning
会被置位 ON。如果在报警被清除后,它仍保持点亮状态,则极可能是检测器烟雾探测器故障,此
外,也可能是仍然有一个火警。
上述程序中的“报警清除”bClearAlarm 按钮产生的跳变脉冲信号也可用边沿检测功能块
R_TRIG 的输出 Q 来获取。样例程序可在\Sample\第十一章\火警报警器 中打开。
11.1.3 抢答控制系统

知识竞赛时,需要有抢答器。控制要求是主持人先按清除按钮,熄灭各抢答者出的信号灯,并
宣读有关试题,当支持人宣布开始抢答时按下清除按钮,最早抢答者的信号被点亮。如图 11.x 所
示。
抢答器 1 抢答器 2 抢答器 3 抢答器 4

PLC
开始按钮

图 11.X 抢答器示意图
1.控制要求
假设抢答系统有 4 位抢答者,则系统有 4 个抢答输入,记为 bInput1~bInput4,有 4 个抢答输
出,记为 bLamp1~bLamp4,有一个清除兼开始按钮,记为 bStart。
抢答器系统当主持人按钮释放时开始抢答,因此,可采用下降沿触发的但按钮启停控制抢答的
开始。为此,需要 RUN 这 3 个内部变量。系统的 I/O 地址分配表如表 11-x 所示。

表 11-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 抢答器 1 输入 bInput1 %QX0.0 抢答器 1 指示灯 bLamp1
%IX0.1 抢答器 2 输入 bInput2 %QX0.1 抢答器 2 指示灯 bLamp2
%IX0.2 抢答器 3 输入 bInput3 %QX0.2 抢答器 3 指示灯 bLamp3
%IX0.3 抢答器 4 输入 bInput4 %QX0.3 抢答器 4 指示灯 bLamp4
%IX0.4 开始按钮 bStart
%IX0.5 清除按钮 bClear
2. 编程
整个抢答器控制系统的变量声明如下:
PROGRAM PLC_PRG
VAR
bInput1 AT%IX0.0:BOOL;
bInput2 AT%IX0.1:BOOL;
bInput3 AT%IX0.2:BOOL;
bInput4 AT%IX0.3:BOOL;
bStart AT%IX0.4:BOOL;
bRun :BOOL;
bLamp1 AT%QX0.0:BOOL;
bLamp2 AT%QX0.1:BOOL;
bLamp3 AT%QX0.2:BOOL;
bLamp4 AT%QX0.3:BOOL;
END_VAR
图 11.X 抢答器控制系统的梯形图程序
如图 11.x 的梯形图程序中,当主持人按下“开始按钮”bStart 后,程序中的内部变量 bRun 被
置位 ON。
当 bRun 被置位 ON 后,执行程序中的第 3 行,只要“抢答输入”bInput1~bInput4 中的任一按
钮被按下后,对应的指示灯 bLamp1~bLamp4 被置位 ON,程序只会输出对应最早按下的那个输入
按钮,误差是一个程序的任务周期,通常在 10ms~20ms 之间,抢答器可以忽略相应误差。输出被
置 ON 的同时会将 bRun 置位 OFF。
在该系统中,当 bStart 按钮从 ON 变为 OFF 后,程序才会自动采集其下降沿,将所有输出指示
灯复位。详细的样例程序可在\Sample\第十一章\抢答器\中打开。
11.1.4 交通灯信号控制程序

1. 控制要求
图 11.x 所示为某十字路口交通信号灯的布置图,由于东西方向车流量较小,南北方向车流量
较大。 因此设置东西方向的放行(绿灯) 时间较长为 20s,而南北方向的放行时间为 10s。当东西
(或南北)方向的绿灯灭时,该方向的黄灯与另一方向的红灯一起亮,以提醒司机和行人注意。然
后,立即开始另一方向的放行。

图 11.X 十字路口车道信号布置图
程序中,根据红绿灯的功能分为了三个子程序,分别为 TRAFFICSIGNAL、WAIT 和 MAIN 程
序。
1) 在 TRAFFICSIGNAL 中,其主要功能是分配各自的信息状态。例如要保证红灯在红和黄/
红状态应该变红和黄灯在黄和黄/红状态变黄等。
2) 在 WAIT 中,其主要功能是负责交通信号灯的延时控制,当时间段完成时,它的输出端将
产生 TRUE 值。
3) 而 MAIN 中,所有的状态都组合在这里,相当于该系统的主程序。
2. 编程
1) TRAFFICSIGNAL 功能
先看一下 TRAFFICSIGNAL,在声明编辑器中定义输入变量 STATUS 为 INT 整型变量,
STATUS 有四个状态,当 STATE 为 1 时输出绿灯,2 或 4 时输出黄灯,3 或 4 时输出红灯,当为 5
时没有输出。这 4 个状态足以用来反映 TRAFFICSIGNAL 状态中绿、红、黄/红、红中的任意一种。
功能块 TRAFFICSIGNAL 声明部分如下,其 I/O 地址分配表如表 11-x 所示:
VAR_INPUT
STATE:INT;
END_VAR
VAR_OUTPUT
GREEN:BOOL;
YELLOW:BOOL;
RED:BOOL;
OFF:BOOL;
END_VAR

表 11-x I/O 地址分配表


地址 说明 地址 说明
%QX0.0 东西红灯 %QX0.3 南北红灯
%QX0.1 东西黄灯 %QX0.4 南北黄灯
%QX0.2 东西绿灯 %QX0.5 南北绿灯
TRAFFICSIGNAL 的程序如图 11.x 所示。
图 11.X TRAFFICSIGNAL 的功能块程序
2) WAIT 功能
WAIT 功能块可用来作为一个计时器来决定每一个 TRAFFICSIGNAL 状态的时间长短。WAIT
可以接收一个 TIME 类型的时间变量作为输入变量,而输出变量 OK,当到达期望设定时间时,它
会被置为 TRUE。
该功能块内部由一个还需要 TP 类型时钟实现。TP 时钟的工作原理在之前的内容中已做了详细
介绍,在此不再重复。
假设 IN 是 FALSE,那么 ET 是 0,并且 Q 是 FALSE。只要 IN 为 TRUE,输出端 ET 以 ms 开
始计算时间值,当 ET 达到了 PT 的设定值,就不再计时。只要 ET 的值比 PT 小,Q 就会保持
TRUE。当 ET 的值达到 PT 值时,Q 产生 FALSE。
WAIT 的声明部分如下:
FUNCTION_BLOCK WAIT1
VAR_INPUT
TIME1:TIME;
END_VAR
VAR_OUTPUT
OK:BOOL:=FALSE;
END_VAR
VAR
TEL:TP;
END_VAR
为了创建期望的计时器,该 WAIT 功能块的程序主如图 11.x 所示:
图 11.X WAIT 的语句表程序
首先检查定时器的 Q 是否为 TRUE(即使已经开始计时),在这样情况下,不改变 TEL 的值。
但是调用 TEL 模块不需要输入,否则设置将该定时器复位,将其 IN 值置为 FALSE,程序相应的会
自动将其 ET 和 Q 都置为 0。
现在读取输入变量 TIME,并将该时间值赋值给功能块的 PT,并调用 TEL。在功能块 TEL 中
变量 ET 开始计时,当它达到 TIME 的时间值,随后 Q 会被置为 TRUE。
3) MAIN 主程序
首先声明需要的变量。LIGHT1 和 LIGHT2 是 TRAFFICSIGNAL 功能块的实例化对象,
DELAY 为 WAIT 功能块实例化后的具体对象。 MAIN 主程序的声明部分如下:
PROGRAM MAIN
VAR
LIGHT1:TRAFFICSIGNAL;
LIGHT2:TRAFFICSIGNAL;
COUNTER: INT;
DELAY: WAIT;
END_VAR
创建一个顺序功能图,在 SFC 中一个 POU 的开始图表经常包含一个动作“Init”和一个伴随转
移“Switch1”和返回 Init 的跳转。在此详细讲述一下:
在编写各个动作和转移之前,先决定一下图表的结构。需要为每个 TRAFFICSIGNAL 状态分
配一个步,选中标志“Switch1”并右键选择“插入后步转移”,重复这个动作来插入三个步。
如果在每个步或转移名字上单击,就可以改变它。
当 START 的值为 TRUE,并且其它所有开关通过 OK 中的 DELAY 都输出 TRUE 时,第一个
变换开关接通,例如,当设定的时间段结束。
从上到下的步依次命名为 Switch1、Counting、OFF、Green2、Switch2 和 Green1。只有初始化
过程保留它的名字,“Switch”应当包括一个黄色的状态,在“Green1”,LIGHT1 将变为绿色,
在“Green2”,LIGHT2 将变为绿灯。最后在开关 Switch1 后返回到初始化的值。顺序功能图程序
程序如图 11.x 所示。
图 11.X MAIN 的顺序功能图程序
动作和转变条件
在 Init 步的动作中,变量被初始化。LIGHT1 的 STATUS 应该是 1 (GREEN ),LIGHT2 的状
态应该是 2(YELLOW)。程序如图 11.x 所示:

图 11.X INIT 步中的语句表程序


在 SWITCH1 步 的 动 作 中 , 变 量 被 初 始 化 。 TRAFFICSIGNAL1 的 STATUS 应 该 是 2
(YELLOW),TRAFFICSIGNAL2 的状态应该是 4(YELLOW)。程序如图 11.x 所示:

在 GREEN2 步的动作中,变量被初始化。TRAFFICSIGNAL1 的 STATUS 应该是 3 (RED ),


TRAFFICSIGNAL2 的状态应该是 2(YELLOW)。程序如图 11.x 所示:
图 11.X GREEN2 步中的语句表程序
在 SWITCH2 步的动作中,变量被初始化。TRAFFICSIGNAL1 的 STATUS 应该是 4 (RED ),
TRAFFICSIGNAL2 的状态应该是 2(YELLOW)。程序如图 11.x 所示:

图 11.X SWITCH2 步中的语句表程序


在 GREEN1 步 的 动 作 中 , 变 量 被 初 始 化 。 TRAFFICSIGNAL1 的 STATUS 应 该 是 1
(GREEN ),TRAFFICSIGNAL2 的状态应该是 3(RED)。程序如图 11.x 所示:

图 11.X GREEN1 步中的语句表程序


完整的 SFC 程序如图 11.x 所示。
在该样例程序中,已经添加了相应的可视化界面,用户可以通过点击打开可视化界面对交通灯
进行直接的观察,效果图如图 11.x 所示。样例程序请参考\Sample\第十一章\交通灯\。

图 11.X 交通信号灯运行效果
11.1.5 停车场管理

1.控制要求
停车场容量为 100 辆车,不允许进入更多;当停车场车停满后,系统显示车位已满信号,不允
许在车辆再进入。
当进入一辆车时,入口传感器向 PLC 发送一个信号,入口门开启(开启时间为 3s),停车场
的当前车辆总数加 1,10s 后入口门关闭(关闭时间为 3s)。
每当出去一辆车时,出口传感器向 PLC 发送一个信号,出口门开启(开启时间为 3s),停车
场的当前车辆总数减 1,10s 后入口门关闭(关闭时间为 3s)。

图 11.X 停车场管理系统
整体系统图如图 11.x 所示,入口处和出口处均有地感线圈,用来感应是否有车辆在入口/出口
处。此外入口/出口的闸机分别由两台电动机控制,有一个输出指示灯,用来显示车位已满。

表 11-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 入口传感器/ bInputSensor %QX0.0 入口闸机电动机正转/ bInputOpen
%IX0.1 出口传感器/ bOutputSensor %QX0.1 入口闸机电动机反转/ bInputClose
%QX0.2 出口闸机电动机正转/ bOutputOpen
%QX0.3 出口闸机电动机反转/ bOutputClose
%QX0.4 车辆已满信号灯/ bFull
2. 编程
整体程序的声明部分如下:
VAR
bInputSensor AT%IX0.0:BOOL;
bOutputSensor AT%IX0.1:BOOL;
bInputOpen AT%QX0.0:BOOL;
bInputClose AT%QX0.1:BOOL;
bOutputOpen AT%QX0.2:BOOL;
bOutputClose AT%QX0.3:BOOL;
bFull AT%QX0.4:BOOL;
FB_CarCounter:CTUD;
fb_3sTP_1: TP;
fb_3sTP_2: TP;
fb_3sTP_3: TP;
fb_3sTP_4: TP;
fb_10sTOF_1: TOF;
fb_10sTOF_2: TOF;
END_VAR
程序采用连续功能图 CFC 来实现,如图 11.x 所示。

图 11.X 停车场管理程序
程序中,两个输入信号分别为 bInputSensor 和 bOutputSensor,他们分别是分布在地上的地感线
圈,用来感应车辆是否在停车区的传感器。当车辆经过地感线圈时,传感器给 PLC 发出 TRUE 信
号,在程序中首先和计数器的当前值进行比较,如果当前计数小于 100,则将该辆车放行,否则由
于车库已满,不打开闸机直至车库内的车辆总量低于 100。
计数器采用 CTUD 的双向计数器,该计数器能够自动检测信号灯上升沿并进行计数,PV 是设
定值,再次应用中将其设定为 100,当当前计数达到 100 时,其输出信号 QU 会置为 ON,并赋值
给信号灯 bFull 告诉用户其车库已满。
车辆进入输入信号 ON 后,fb_3sTP_1 采集传感器的上升沿出发信号,收到信号后,使输入闸
机的正转信号置为 ON,使闸机向上打开,3 秒后,闸机打开信号 OFF,此时,闸机已处于完全打
开状态,车辆此时可以经过,闸机打开后,程序进入另外一个计时状态,此时间维持 10s,在此时
间内,车辆可以通过。10 秒后,闸机反转信号为 ON,此时将闸机下放,3 秒后闸机停止,此时可
以进入下一辆车。
车辆驶出使用与车辆进入相同的程序结构,最终的示例程序可参阅\Sample\第十一章\停车场管
理\。

11.1.6 恒压变频供水控制系统

对高楼层的用户而言,在白天或在用水的高峰期,供水系统的电机负载经常需要满负荷或超负
荷运行,夜间或休闲的时候,需要的用水量减少了很多,但电机依然是在功率全开的状态,所以这
势必浪费了大量的资源,同时也给供水系统的电机造成了极大的损耗。我们要通过调整电机的转速,
来应对不同的要求,以达到恒压供水的目的。
1. 控制要求
在恒压变频供水系统中,以 PLC 为控制中心。在水泵的出水管道上安装一个远程压力表,用
于检测管道压力,并把出口压力变成 0~10V 或 4~20mA 的模拟信号,送到变频器的输入端,变频
器将实际反馈量与设定的压力值进行比较,经过内部的 PID 计算控制变频器的实际输出频率,以此
达到控制电动机的转速达到控制管道压力的目的。当实际压力小于给定压力时,电动机转速减小,
管道压力降低,最终达到供水压力恒定。系统示意图如图 11.x 所示。
图 11.X 恒压变频供水控制系统
两台水本运行时的变频恒压供水系统控制要求:
1) 系统开始工作时,供水管道内水压为 0,在控制系统作用下,变频器开始运作,1#水泵启
动且转速逐渐提高,当输出的压力值达到设定值时,其供水量与用水量相平衡时,1#水泵
的电机转速达到稳定值,在此期间该水泵工作在调速运行状态。
2) 当用水量增加,水压减少时,通过液压力阀调节水泵按设定速率加速到另一个转速。反之,
当用水量减少,水压增加时,水泵按设定的速率减速到一个新的恒定转速。
3) 当水量继续增加时,变频器输出频率增加至设定频率上线时,水压仍低于设定值,控制器
控制 1#水泵切换至工频 50Hz 运作,于此同时,第二台水泵 2#投入运行,系统恢复对水压
的闭环调节,直到水压达到设定值为止。
4) 当用水量下降水压升高,变频器输出频率降至启动频率时,水压仍高于设定值,系统将工
频运行的第二台水泵关掉,恢复一台水泵系统供水,对水压进行闭环调节,是压力重新达
到设定值。
根据要求,列出所需要用到的 I/O 点,并为其分配相应地址,表 11-x 为具体的分配票。

表 11-x I/O 地址分配表


地址 说明 地址 说明
%IX0.0 启动按钮/bStart %QX0.0 1#水泵工频接触器/bPump1_50HzOutput
%IX0.1 停止按钮/bStop %QX0.1 1#水泵变频接触器/bPump1_FROutput
%IX0.2 手动/自动切换开关/bAutoManual %QX0.2 2#水泵工频接触器/bPump2_50HzOutput
%IX0.3 1#水泵启动/bPump1Start %QX0.3 2#水泵变频接触器/bPump2_FROutput
%IX0.4 1#水泵停止/bPump1Stop %QX0.4 自动模式运行灯/bAutoRun
%IX0.5 2#水泵启动/bPump2Start %QX0.5 1#水泵变频运行/bPump1FR
%IX0.6 2#水泵停止/bPump2Stop %QX0.6 2#水泵变频运行/bPump2FR
%IX0.7 变频器故障/bError %QX0.7 水泵过载运行/bPumpOverRunErr
%IX0.8 变频器运行信号/bRun
%IX0.9 变频器上线达到/bUppperReached
%IX0.10 变频器下达到/bLowerReached
%IX0.11 水泵电机过载/bOverRun
对于同一水泵来说,既能以工频工作又能变频工作;既可以手动切换又可以自动切换。其工作
原理图如图 11.x 所示。
图 11.X 恒压变频供水系统的水泵电动机原理图
2. 编程
整个恒压变频供水系统的变量声明如下:
PROGRAM PLC_PRG
VAR
bStart AT%IX0.0:BOOL;//启动信号
bStop AT%IX0.1:BOOL;//停止按钮
bAutoManual AT%IX0.2:BOOL;//手动/自动切换开关
bPump1Start AT%IX0.3:BOOL;//1#水泵启动
bPump1Stop AT%IX0.4:BOOL;//1#水泵停止
bPump2Start AT%IX0.5:BOOL;//2#水泵启动
bPump2Stop AT%IX0.6:BOOL;//2#水泵停止
bError AT%IX0.7:BOOL;//变频器故障
bRun AT%IX0.8:BOOL;//变频器运行信号
bUppperReached AT%IX0.9:BOOL;//变频器上线达到
bLowerReached AT%IX0.10:BOOL;//变频器下线达到
bOverRun AT%IX0.11:BOOL;//水泵电机过载
bPump1_50HzOutput AT%QX0.0:BOOL;//1#水泵工频接触器
bPump1_FROutput AT%QX0.1:BOOL;//1#水泵变频接触器
bPump2_50HzOutput AT%QX0.2:BOOL;//2#水泵工频接触器
bPump2_FROutput AT%QX0.3:BOOL;//2#水泵变频接触器
bAutoRun AT%QX0.4:BOOL;//自动模式运行灯
bPump1FR AT%QX0.5:BOOL;//1#水泵变频运行
bPump2FR AT%QX0.6:BOOL;//2#水泵变频运行
bPumpOverRunErr AT%QX0.7:BOOL;//水泵过载运行
fb_ConvertProtect:ton;
fb_UppperReachedTimer:ton;
bUppperReachedTemp:BOOL;
fb_LowerReachedTimer:ton;
bLowerReachedTemp:BOOL;
bConvertStatus:BOOL;
fb_ConvertStatus: TON;
END_VAR
根据控制要求设计梯形图程序,如图 11.x 所示。
1) 手动模式方式
将转换开关旋转至断开位置上,输入信号 bAutoManual 为 OFF,变频调速恒压供水系统工作在
手动状态。两个水泵可以独立工频工作,但不要同时工作。
2) 自动模式
 水泵变频工作。将转换开关转换至接通的位置上,输入信号 bAutoManual 为 TRUE,变频
调速恒压供水系统工作在自动状态。按下自动工作按钮,由程序控制 bPump1_50HzOutput
输出,控制接触器 KM2 接通,变频器接通到运行信号,输入变频控制 1 号水泵变频工作。
系统开始工作时,供水管道内水压力为 0,在控制系统作用下,变频器开始运行,1 号水
泵 M1 启动且转速逐渐升高,当输出压力达到设定值后,其供水量与用水量达到平衡,
M1 转速才稳定达到某一定值,这期间 M1 工作在变频运行状态。当用水量增加水压减少
时,通过变频器的 PID 闭环控制,水泵按设定速率加速到另一个稳定转速;反之,当用水
量减少水压增加时,水泵按设定速率减速到新的稳定转速。
 1 号水泵变频切换到工频控制。当水量继续增加,变频器输出频率增加至设定最高频率
(达到上限)时,水压如仍低于设定值,此时变频器通过输入信号 bUppperReached,切断
bPump1_FROutput 变频输出信号,经过延时,将 bPump1_50HzOutput 信号置为 TRUE,1
号水泵 M1 由变频工作状态切换至工频运行状态,系统恢复对水压的闭环调节,直到水压
达到设定值为止。
 2 号水泵切除 1 号水泵由工频切换至变频工作状态。当用水量下降,水压升高,变频器输
出频率降至设定的频率下限时,水压仍高于设定值,此时变频器的频率下限输出信号,介
入至 PLC 对应 bLowerReached 信号为 TRUE,切断输出信号 bPump2_FROutput,2 号水泵
M2 停止运行;系统由 1 号水泵变频运行,恢复对水压的闭环调节,使压力重新达到设定
值。
图 11.X 恒压变频供水系统的梯形图程序(一)

图 11.X 恒压变频供水系统的图梯形图程序(二)
 系统的停止。系统停止时,按下按钮 bStop,输出信号断开,切断接触器线圈的控制回路,
系统停止工作。
当水管压力减小时,将 2 号水泵电动机关断,1 号水泵电动机进入变频工作状态,以维持实际
水压的平衡。最终的示例程序可参阅\Sample\第十一章\恒压变频供水控制\。
第12章 CoDeSys 通信网络
本章主要知识点
 了解常用工业网络通讯概念
 了解 CANopen、PROFIBUS 及工业以太网的应用场合及优缺点
 掌握 CANopen、PROFIBUS 及工业以太网通讯技术
 了解在 CoDeSys 中如何配置不同网络

12.1 通信基础
近二十多年由于通信技术、计算机技术、网络技术的迅速发展,工业自动化控制领域也随之得
到了迅速的提高和改革。由于一台机器通常有不同生产厂商的不同设备构成,设备间通常需要交换
数据实现各自的功能,不同生产厂商的不同设备间的相互配合离不开通讯。因此,通信是控制发展
到一定阶段不可或缺的产物。

12.1.1 数据传送方式

1.并行通讯和串行通讯
在数据通信中按每次传送的数据位数,通信方式可以分为并行通讯和串行通讯。
1) 并行通信
并行通信的传输方式是在计算机和终端之间的数据传输通常是靠电缆或信道上的电流或电压变
化实现的。如果一组数据的各数据位在多条线上同时被传输,这种传输方式称为并行通信。
并行通信是传送数据的各个位同时进行发送或接受的通信方式,如图 12.x 所示。
D0
D1
D2
D3
计算机 D4 外部设备
D5
D6
D7

图 12.X 并行通信图
并行接口的三个方面的功能,第一方方面是实现与系统总线的连接,提供数据的输入/输出功
能。第二方面是实现与外设连接,确保输入/输出采用中断的方式来实现。
并行通信的特点如下
 各数据位同时传输,传输速度快、效率高,多用在实时、快速的场合。
 并行传递的信息不要求固定的格式。
 并行接口的数据传输率比串行接口快 8 倍,标准并口的数据传输率理论值为 1Mbps(兆比
特/秒)。
 并行传输的数据宽度可以是 1~128 位,甚至更宽,但是有多少数据位就需要多少根数据
线,因此传输的成本较高。
 并行通信抗干扰能力差。
 以计算机的字长,通常是 8 位、16 位或 32 位为传输单位,一次传送一个字长的数据。
 适合于外部设备与微机之间进行近距离、大量和快速的信息交换。
 并行数据传输只适用于近距离的通信,通常传输距离小于 30 米。
2) 串行通信
串行通信是计算机上一种非常通用设备通信的协议(不要与通用串行总线 Universal SerialBus
或者 USB 混淆)。串行通信使用一条数据线,将数据一位一位的依次传输,每一位数据占据一个
固定的时间长度,其只需要少数几条线就可以在系统间交换信息。串行通信的特点是通信线路简单,
成本较低,但传输速度比并行通信慢,串行通信如图 12.x 所示。

0100010

计算机 外部设备

图 12.X 串行通信图
在通用串行通信接口中,常用的有 RS-232, RS-422 及 RS-485,通过串行通信模块可与之通信。
串口通信使用的是点对点通信方式,CoDeSys 中主要用于和第三方的 PC 或仪器仪表进行通讯。
串行通信技术的标准是 EIA -232,EIA-422 和 EIA485,通常也称之为 RS-232,RS-422 和 RS-
485。
 RS-232 接口
RS-232C 标准(协议)的全称是 EIA-RS-232C 标准,其中 EIA(Electronic Industry Association)
代表美国电子工业协会,RS(Recommended Standard)代表推荐标准,232 是标识号,C 代表
RS232 的最新一次修改(1969),在这之前,有 RS232B、RS232A。它规定连接电缆和机械、电气
特性、信号功能及传送过程。
目前较为常用的串口有 9 针串口(DB9)和 25 针串口(DB25),通信距离较近时(<12m),可
以用电缆线直接连接标准 RS-232 端口(RS-422,RS-485 较远),若距离较远,需附加调制解
调器(Modem)。最为简单且常用的是三线制接法,即地,接收数据和发送数据三脚相连,这里只
涉及到最为简单的接法。
RS232C 接口有两种物理连接器(插头)。DTE 端(插针的一面)为公,接它的为母;DCE 端
(针孔的一面)为母,接它的为公。实际使用时,计算机的串口都是公插头,而 PLC 端为母插头。
与它们相连的插头正好相反。 图 12.x 所示的为两个 DB9 的公连接器。

图 12.X RS-232 DB9 公连接器外观


由于 RS-232C 通讯距离较近,当传输距离较远时,可采用 RS-485 串行通信接口。
 RS-422/485 接口
RS-422、 RS-485 与 RS-232 相比,数据信号采用差分传输方式,也称为平衡传输。其最大传
输距离约为 1219m,最大传输速率为 10Mb/s。平衡双绞线的长度与传输距离成反比,在 100Mb/s
速率以下,才可使用规定最长的电缆长度,而只有在很短的距离下才能获得最高速率传输。一般
100m 长双绞线最大传输速率仅为 1Mb/s。 RS-422 和 RS-485 允许在相同传输线上连接多个接收节
点,RS-422 最多可以接 10 个节点,RS-485 最多可以接到 32 个设备。
RS-485 实际上是 RS-422 的变型。RS-422 采用两对差分平衡线路,而 RS-485 只用一对。差分
电路的最大优点是抑制噪声。由于在它的两根信号线上传递着大小相同、方向相反的电流,而噪声
电压往往在两根导线上同时出现,一根导线上出现的噪声电压会被另一根导线上出现的噪声电压抵
消,因而可以极大的削弱噪声对信号的影响。
差分电路的另一个优点是不受节点间接接地电平差异的影响。在非差分(即单端)电路中,多
个信号共用一根接地线,长距离传输时,不同节点接地线的电压差异可能相差好几伏,甚至会引起
信号的误读。差分电路则完全不会受到接地电压差异的影响。
RS-232C、RS-422 与 RS-485 的主要技术参数的比较详见表 12-x 所示。

表 12-x RS-232C、RS-422、RS-485 重要参数比较


规范 RS-232C RS-422 RS-485
最大传输距离 15m 1200m 1200m
最大传输速度 20Kbit/s 10Mbit/s 10Mbit/s
驱动器最小输出/V ±5 ±2 ±1.5
驱动器最大输出/V ±15 ±10 ±6
接收器敏感度/V ±3 ±0.2 ±0.2
最大驱动器数量 1 1 32
最大接收器数量 1 10 32
传输方式 单端 差分 差分
由表 12-x 可见,RS-485 更适用于多台计算机或带微机控制器的设备之间的远距离数据通信。
2.同步/异步传输
无论是 RS232 接口还是 RS422/485 接口,均可以采用串行异步通信数据格式。如下介绍同步传
输和一部传输的区别。
1) 同步传输
采用同步传输时,将许多字符组成一个信息组,字符可以一个接一个地传输,但是,在每组信
息(通常称为帧)的开始要加上同步字符,在没有信息要传输时,要填上空字符,因为同步传输不
允许有间隙。在同步传输过程中,一个字符可以对应 5-8bits。当然对同一个传输过程更,所有字符
对应同样的比特数,比如说 n 比特。这样,传输时,按每 n 比特划分为一个时间片,发送端一个时
间片中发送一个字符,接收端则在一个时间片中接受一个字符。同步传送的数据格式如图 12.x 所
示。

图 12.X 同步通信数据格式
同步传输时,一个信息帧中包含许多字符,每个信息帧用同步字符作为开始,一般将同步字符
和空字符用作同一个代码。在整个系统中,由统一的时钟控制发送端的发送和空字符。接收端当然
是应该能识别同步字符的,当检测到有一串比特和同步字符相匹配时,就认为开始一个信息帧,于
是,把此后的比特作为实际传输信息来处理。
2) 异步传输
异步传输方式是指比特被划分成小组独立传送。发送方可以在任何时刻发送这些比特组,而接
收方不知道他们会在什么时候到达。异步传输存在一个潜在的问题,即接收方并不知道数据会在什
么时候到达。他在检测到数据并作出响应之前,第一个比特已经过去了。因此,这个问题需要通过
通信协议加以解决。每次异步传输都以一个开始比特开头,他通知接收方数据已经达到了。这就给
了接收方响应、接受和缓存数据比特的时间。在传输结束时,一个停止比特表示依次传输的终止。
异步传输被设计用于低速设备,比如键盘和某些打印机等。另外,它的开销也比较多。如使用
终端与一台计算机进行通信。按一个字母键、数字键或特殊字符键就发送一个 8bit 的 ASC 码。在
这种情况下,为解决接收问题每 8bits 就多传送 2bits。这样,总的传输负载就增加 25%,对于数据
传输量很小的低速设备来说,这影响不大。但对于那些数据传输量很大的告诉设备来说,多出的
25%的负载就相当严重了。
串行异步收发通信的数据格式如图 12.x 所示。
图 12.X 异步通信数据格式
传送开始前,发收双方把所采用的起止式格式(包括字符的数据位长度,停止位位数,有无校
验位以及是奇校验还是偶校验等)和数据传输速率作统一规定。传送开始后,接收设备不断地检测
传输线,看是否有起始位到来。当收到一系列的“1”(停止位或空闲位)之后,检测到一个下跳
沿,说明起始位出现,起始位经确认后,就开始接收所规定的数据位和奇偶校验位以及停止位。经
过处理将停止位去掉,把数据位拼装成一个并行字节,并且经校 验后,无奇偶错才算正确的接收
一个字符。一个字符接收完毕,接收设备有继续测试传输线,监视“0”电平的到来和下一个字符
的开始,直到全部数据传送完毕。
3) 两种通讯方式的比较
从通信效率的角度看,同步传输方式接收方不必对每个字符进行开始和停止的操作,因此同步
传输通信效率高,异步传输效率低、小。异步传输只适用于点到点的数据传输,而同步传输可用于
点和多点之间的数据传输。
3. 数据传输方向
在串行通信中,数据通常是在两个站(如终端和微机)之间进行传送,按照数据流的方向可分
成三种基本的传送方式:全双工、半双工、和单工。
1) 单工(Simplex)方式
单工通信使用一根导线,信号的发送方和接收方有明确的方向性。也就是说通信只能在一个方
向上进行。如图 12.x 的 a)所示,信息只能由一方 A 传到另一方 B。
2) 半双工(Half-duplex)方式
若使用同一根传输线既作接收又作发送,虽然数据可以在两个方向上传送,但通信双方不能同
时收发数据,这样的传送方式就是半双工制。采用半双工方式时,通信系统每一端的发送器和接收
器,通过收/发开关转接到通信线上,进行方向的切换,因此,会产生时间延迟。收/发开关实际上
是由软件控制的电子开关。
当计算机主机用串行接口连接显示终端时,在半双工方式中,输入过程和输出过程使用同一通
路。有些计算机和显示终端之间采用半双工方式工作,这时,从键盘打入的字符在发送到主机的同
时就被送到终端上显示出来,而不是用回送的办法,所以避免了接收过程和发送过程同时进行的情
况。如图 12.x 的 b)所示,信息既可由 A 传到 B,又能由 B 传 A,但只能由一个方向上的传输存在。
3) 全双工(Full-duplex)方式
当数据的发送和接收分流,分别由两根不同的传输线传送时,通信双方都能在同一时刻进行发
送和接收操作,这样的传送方式就是全双工制。在全双工方式下,通信系统的每一端都设置了发送
器和接收器,因此,能控制数据同时在两个方向上传送。全双工方式无需进行方向的切换,因此,
没有切换操作所产生的时间延迟,这对那些不能有时间延误的交互式应用(例如远程监测和控制系
统)十分有利。这种方式要求通讯双方均有发送器和接收器,同时,需要 2 根数据线传送数据信号。
(可能还需要控制线和状态线,以及地线)。如图 12.x 的 c)所示,线路上存在 A 到 B 和 B 到 A
的双向信号传输。

A B
A B A B
A B

a)单工 b)半双工 c)全双工


图 12.X 通讯方式比较
4.数据传送介质
在 PLC 通信网络中,传输介质的选择是很重要的一个环节。连接网络首先要用的东西就是线
缆,它是所有网络中最小的组成单元。
传输媒介决定了网络的传输速率,网络的最大长度及可靠性,抗干扰性等。常见的传输线有三
种类型:双绞线、同轴电缆和光纤。每一种都有其特点及使用的场合,如下对这三种传输介质做详
细介绍。
1) 双绞线
双绞线(Twisted Pair,TP)是一种综合布线工程中最常用的传输介质,是由两根具有绝缘保
护层的铜导线组成的。把两根绝缘的铜导线按一定密度互相绞在一起,每一根导线在传输中辐射出
来的电波会被另一根线上发出的电波抵消,有效降低信号干扰的程度。
双绞线一般由两根 22~26 号绝缘铜导线相互缠绕而成,“双绞线”的名字也是由此而来。实
际使用时,双绞线是由多对双绞线一起包在一个绝缘电缆套管里的。如果把一对或多对双绞线放在
一个绝缘套管中便成了双绞线电缆,但日常生活中一般把“双绞线电缆”直接称为“ 双绞线”,
普通双绞线的视图如图 12.x 所示。

图 12.x 双绞线视图
双绞线可分为屏蔽双绞线(Shielded Twisted Pair,STP)与非屏蔽双绞线(Unshielded Twisted
Pair,UTP)。
屏蔽双绞线在双绞线与外层绝缘封套之间有一个金属屏蔽层。屏蔽双绞线分为 STP(Shielded
Twisted-Pair)和 UTP(Unshielded Twisted-Pair),STP 指每条线都有各自的屏蔽层,而 UTP 只在
整个电缆有屏蔽装置,并且两端都正确接地时才起作用。所以要求整个系统是屏蔽器件,包括电缆、
信息点、水晶头和配线架等,同时建筑物需要有良好的接地系统。屏蔽层可减少辐射,也可阻止外
部电磁干扰的进入,使屏蔽双绞线比同类的非屏蔽双绞线具有更高的传输速率。STP 和 UTP 的主
要区别如图 12.x 所示。

图 12.x STP 与 UTP 双绞线的比较


通过 12.x 可以看到,两根导线绞在一起主要是为了防止干扰,对线上信号具有共模抑制干扰
的作用。
当使用 RJ45 连接头的双绞线连线时,有两种连接方式供选择,直接连接和交叉连接。
 交叉线:一头是 T-586A 的标准,另一头是 T-586B 的标准才可以两台计算机直接连接。
 直连线:两头都是用 T-586A 或都是 T-586B 的标准。
详细接线图如图 12.x 所示。

图 12.x 双绞线的连接方式
双绞线的性能指标:
对于双绞线,使用者最关心的是表征其性能的几个指标。这些指标包括衰减、近端串扰、阻抗
特性、分布电容、直流电阻等。
 衰减(Attenuation)
衰减是沿链路的信号损失度量。衰减与线缆的长度有关系,随着长度的增加,信号衰减也随之
增加。衰减用“db”作单位,表示源传送端信号到接收端信号强度的比率。由于衰减随频率而变化,
因此,应测量在应用范围内的全部频率上的衰减。
 近端串扰
串扰分近端串扰和远端串扰(FEXT),测试仪主要是测量 NEXT,由于存在线路损耗,因此
FEXT 的量值的影响较小。近端串扰(NEXT)损耗是测量一条非屏蔽双绞线链路中从一对线到另
一对线的信号耦合。对于非屏蔽双绞线链路,NEXT 是一个关键的性能指标,也是最难精确测量的
一个指标。随着信号频率的增加,其测量难度将加大。
 直流电阻
直流环路电阻会消耗一部分信号,并将其转变成热量。它是指一对导线电阻的和,11801 规格
的双绞线的直流电阻不得大于 19.2 欧姆。每对间的差异不能太大(小于 0.1 欧姆),否则表示接触
不良,必须检查连接点。
 特性阻抗
与环路直流电阻不同,特性阻抗包括电阻及频率为 1~100MHz 的电感阻抗及电容阻抗,它与
一对电线之间的距离及绝缘体的电气性能有关。各种电缆有不同的特性阻抗,而双绞线电缆则有
100 欧姆、120 欧姆及 150 欧姆几种。
 衰减串扰比(ACR)
在某些频率范围,串扰与衰减量的比例关系是反映电缆性能的另一个重要参数。ACR 有时也
以信噪比(SNR:Signal-Noice ratio)表示,它由最差的衰减量与 NEXT 量值的差值计算。ACR 值
较大,表示抗干扰的能力更强。一般系统要求至少大于 10 分贝。
 电缆特性
通信信道的品质是由它的电缆特性描述的。SNR 是在考虑到干扰信号的情况下,对数据信号强
度的一个度量。如果 SNR 过低,将导致数据信号在被接收时,接收器不能分辨数据信号和噪音信
号,最终引起数据错误。因此,为了将数据错误限制在一定范围内,必须定义一个最小的可接收的
SNR 。
2) 同轴电缆
同轴电缆由里到外分为四层:中心铜线(单股的实心线或多股绞合线),塑料绝缘体,网状导
电层和电线外皮。中心铜线和网状导电层形成电流回路。因为中心铜线和网状导电层为同轴关系而
得名。同轴电缆实物图详见 12.x。

a) b)

图 12.X 同轴电缆实物图
a )同轴电缆实物图 b )同轴电缆结构图
同轴电缆以硬铜线为芯,外包一层绝缘材料。这层绝缘材料用密织的网状导体环绕,网外又覆
盖一层保护性材料。有两种广泛使用的同轴电缆。一种是 50 欧姆电缆,用于数字传输,由于多用
于基带传输,也叫基带同轴电缆;另一种是 75 欧姆电缆,用于模拟传输,即宽带同轴电缆。这种
区别是由历史原因造成的,而不是由于技术原因或生产厂家。
 基带同轴电缆
基带同轴电缆具有高带宽和极好的噪声抑制特性。同轴电缆的带宽取决于电缆长度。1km 的电
缆可以达到 1Gb/s~2Gb/s 的数据传输速率。还可以使用更长的电缆,但是传输率要降低或使用中间
放大器。目前,同轴电缆大量被光纤取代,但仍广泛应用于有线和无线电视和某些局域网。
 宽带同轴电缆
使用有线电视电缆进行模拟信号传输的同轴电缆系统被称为宽带同轴电缆。“宽带”这个词来
源于电话业,指比 4kHz 宽的频带。然而在计算机网络中,“宽带电缆”却指任何使用模拟信号进行
传输的电缆网。
由于宽带网使用标准的有线电视技术,可使用的频带高达 300MHz(常常到 450MHz);由于
使用模拟信号,需要在接口处安放一个电子设备,用以把进入网络的比特流转换为模拟信号,并把
网络输出的信号再转换成比特流。
宽带系统又分为多个信道,电视广播通常占用 6MHz 信道。每个信道可用于模拟电视、CD 质
量声音(1.4Mb/s)或 3Mb/s 的数字比特流。电视和数据可在一条电缆上混合传输。
宽带系统和基带系统的一个主要区别是:宽带系统由于覆盖的区域广,因此,需要模拟放大器
周期性地加强信号。这些放大器仅能单向传输信号,因此,如果计算机间有放大器,则报文分组就
不能在计算机间逆向传输。为了解决这个问题,人们已经开发了两种类型的宽带系统:双缆系统和
单缆系统。
双缆系统:
双缆系统有两条并排铺设的完全相同的电缆。为了传输数据,计算机通过电缆 1 将数据传输到
电缆数根部的设备,即顶端器(head-end),随后顶端器通过电缆 2 将信号沿电缆数往下传输。所有
的计算机都通过电缆 1 发送,通过电缆 2 接收。
单缆系统:
另一种方案是在每根电缆上为内、外通信分配不同的频段。低频段用于计算机到顶端器的通信,
顶端器收到的信号移到高频段,向计算机广播。在子分段(subsplit)系统中,5MHz~30MHz 频段
用于内向通信,40MHz~300MHz 频段用于外向通信。在中分(midsplit)系统中,内向频段是
5MHz~116MHz,而外向频段为 168MHz~300MHz。
3) 光纤
光纤是光导纤维的简写,是一种由玻璃或塑料制成的纤维,可作为光传导工具。传输原理是
“光的全反射”。光缆是一种传到光波的光纤介质。光纤和同轴电缆相似,只是没有网状屏蔽层。
光纤的基本结构一般是由缆芯、加强钢丝、填充物和护套等几部分组成,另外根据需要还有防
水层、缓冲层、绝缘金属导线等构件,其结构如图 12.x 所示。

图 12.X 光纤线结构
光纤按照光在光纤中的传输点模数分为单模光纤(Single Mode Fiber)和多模光纤(Multi
Mode Fiber)。
 单模光纤
单模光纤(SingleModeFiber):中心玻璃芯很细(芯径一般为 9 或 10μm),只能传一种模式的光。
因此,其模间色散很小,适用于远程通讯,但还存在着材料色散和波导色散,这样单模光纤对光源
的谱宽和稳定性有较高的要求,即谱宽要窄,稳定性要好。
单 模 光 纤 具 备 10micron 的 芯 直 径 , 可 容 许 单 模 光 束 传 输 , 可 减 除 频 宽 及 振 模 色 散
(Modaldispersion) 的限制,但由于单模光纤芯径太小,较难控制光束传输,故需要极为昂贵的激光
作为光源体,而单模光缆的主要限制在于材料色散 (Materialdispersion),单模光缆主要利用激光才
能获得高频宽,而由于 LED 会发放大量不同频宽的光源,所以材料色散要求非常重要。
 多模光纤
多模光纤容许不同模式的光于一根光纤上传输,由于多模光纤的芯径较大,故可使用较为廉价
的耦合器及接线器,多模光纤的纤芯直径为 50μm 至 100μm。由于多模光纤中传输的模式多达数百
个,各个模式的传播常数和群速率不同,使光纤的带宽窄,色散大,损耗也大,只适于中短距离和
小容量的光纤通信系统。
单模光纤相比于多模光纤可支持更长传输距离,在 100Mbps 的以太网以至这行的 1G 千兆网,
单模光纤都可支持超过 5000m 的传输距离。从成本角度考虑,由于光端机非常昂贵,故采用单模
光纤的成本会比多模光纤电缆的成本高。图 12.x 为多模和单模光纤的传到方式。

图 12.X 单模/多模光纤传到方式
光纤有三种方式连接,永久性连接、应急连接和活动连接。
 永久性光纤连接(又叫热熔)
这种连接是用放电的方法将两根光纤的连接点熔化并连接在一起。一般用在长途接续、永久或
半永久固定连接。其主要特点是连接衰减在所有的连接方法中最低,典型值为 0.01~0.03dB/点。但
连接时,需要专用设备(熔接机)和专业人员进行操作,而且 连接点也需要专用容器保护起来。
 应急连接(又叫)冷熔
应急连接主要是用机械和化学的方法,将两根光纤固定并粘接在一起。这种方法的主要特点是
连接迅速可靠,连接典型衰减为 0.1~0.3dB/点。但连接点长期使用会不稳定,衰减也会大幅度增加,
所以只能短时间内应急用。
 活动连接
活动连接是利用各种光纤连接器件(插头和插座),将站点与站点或站点与光缆连接 起来的
一种方法。这种方法灵活、简单、方便、可靠,多用在建筑物内的计算机网络布线中。其典型衰减
为 1dB/接头。
光纤连接
光纤接口是用来连接光纤线缆的物理接口。其原理是利用了光从光密介质进入光疏介质从而发
生了全反射。通常有 SC、ST、FC 等几种类型。FC 是 Ferrule Connector 的缩写,其外部加强方式
是采用金属套,紧固方式为螺丝扣。ST 接口通常用于 10Base-F,SC 接口通常用于 100Base-FX。
接口方面分为 FC 圆型带螺纹、SC 小方头(直接连接设备 SFP 模块)、ST 卡接式圆型、PC 微
球面研磨抛光、APC 呈 8 度角并做微球面研磨抛光、SC 卡接式方型(市面上应用最多的一种接
口)、MT-RJ 方型,一头双纤收发一体型。所有的接口如图 12.x 所示。

图 12.X 光纤连接头

12.1.2 串口通讯接口标准

在工业控制网络中,PLC 采用 RS-232、RS-485 和 RS-422 标准的串行通讯接口进行数据通信。


1. RS-232
RS-232 是美国电子工业协会 EIA(Electronic Industry Association)制定的一种串行物理接口标
准。RS 是英文“推荐标准”的缩写,232 为标识号。
RS-232 的电气接口电路采取的是不平衡传输方式,即所谓单端通讯,其发送电平与接收电平
的差只有 2~3V,所以共模抑制能力较差,容易受到共地噪声和外部干扰的影响,再加上信号线之
间的分布电容,因此其传送距离最大为约 15 米,最高数据传输速率为 20kb/s。
RS-232 的电气接口是单端、双极性电源供电电路。RS-232 有许多不足之处 :
 数据传输速率低,最高为 20k bit/s
 传输距离短,最远为 15m
 两个传输方向共用一根信号地线,接口使用不平衡收/发器,可能在各种信号成分间产生
干扰。
为了解决这些问题,及对上述问题加以改进。目前工业环境中广泛应用的 RS422\RS485 就是在
此标准下派生出的。
1) 针脚定义:
图 12.x 为 RS-232 的 DB9 连接定义。
a) b)

图 12.X RS-232 DB9 公母头


a ) 公头 b ) 母头
RS-232 的接口定义如图表 12-x 所示。

表 12-x RS-232 针脚定义


9针引脚 方向 符号 功能

3 输出 TXD 发送数据
2 输入 RXD 接收数据
7 输出 RTS 请求发送
8 输入 CTS 为发送清零
6 输入 DSR 设备数据准备好
5 GND 信号地
1 输入 DCD 数据信号检测
4 输出 DTR
9 输入 RI
 从计算机至终端的信号
DTR:数据终端(DTE)准备好,告诉设备计算机已接通电源,并准备好了。
RTS:请求发送,告诉设备现在要发送数据。
 从终端至计算机的信号
DSR:数据设备(DCE)准备好,告诉计算机已经接通电源,并准备好了。
CTS:为发送清零,告诉计算机已经做好了接收数据的准备。
DCD:数据信号检测,告诉计算机设备已经建立了连接。
 数据信号
TXD:发送数据信号。
RXD:接收数据信号。
2) 电气特性
RS232 接口任何一条信号线的电压均为负逻辑关系。即:
逻辑“1”:-3~ -15V;
逻辑“0”:+3~ +15V ,噪声容限为 2V。
传输速率较低,在异步传输时,波特率为 20Kbps;最大传输距离标准值为 50 英尺,实际在 15
米左右。一般在通讯距离近,传送速率和环境要求不高的场合应用广泛。
2. RS-422/485
RS422 和 RS485 电气接口电路,采用的是平衡驱动差分接收电路,其收和发不共地。这可大大
减少共地所带来的共模干扰。RS422 和 RS485 的区别是前者为全双工型(即“收”和“发”可同时
进行),后者为半双工型(即收和发分时进行)。 图 4.2 : 串行通讯的三种电气接口电路
RS-422 和 RS-485 需要 2 个终接电阻,其阻值要求等于传输电缆的特性阻抗。在短距离传输时
可不需要终接电阻,即一般在 300m 以下不需要终接电阻。终接电阻接在传输电线的两端。
RS-422/485 针脚定义
1) 针脚含义
RS-422 有 4 根信号线:两根发送(Y、Z)、两根接收(A、B)。由于 RS-422 的收与发是分
开的,所以可以同时收和发(全双工)。RS-485 有 2 根信号线:发送和接收都是 A 和 B。由于 RS-
485 的收与发是共用两根线所以不能够同时收和发(半双工)。针脚定义如表 12-x 所示。

表 12-x RS-422/485 针脚定义


9针引脚 RS-422 功能 RS-485 功能
1 TX- 发送数据 DATA- 发送数据
2 TX+ DATA+ 接收数据
3 RX+ 接收数据 NC
4 RX- NC
5 GND 信号地 GND 信号地
6 RTS- 发送请求 NC
7 RTS+ NC
8 CTS+ 发送清零 NC
9 CTS- NC
 RS-422 数据信号
TX+/-:发送数据信号。
RX+/-:接收数据信号。
 RS-422 从终端至计算机的信号
RTS+/-:发送请求
CTS+/-:发送数据清零
 RS-485 数据信号
DATA+/-:发送/接受数据信号。
2) 电气特性
RS-485 接口采用二线差分平衡传输,当采用+5V 电源供电时,其信号定义如下:
逻辑“0”,若差分电压信号为-2500~-200mV 时;
逻辑“1”,若差分电压信号为+200~+2500mV 时;
高阻状态,若差分电压信号为-200~+200mV 时。
3. 串口通讯参数
无论是 RS-232 还是 RS422/485,他们都拥有相同的通讯参数设置,主要参数有波特率,数据
位,停止位,奇偶校验位。
 波特率
这是一个衡量通信速度的参数。它表示每秒钟传送的 bit 的个数。例如 300 波特表示每秒钟发
送 300 个 bit。
 数据位
这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是 8 位的,标
准的值是 5、7 和 8 位。如何设置取决于你想传送的信息。比如,标准的 ASCII 码是 0~127(7
位)。扩展的 ASCII 码是 0~255(8 位)。如果数据使用简单的文本(标准 ASCII 码),那么每个
数据包使 用 7 位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际
数据位取决于通信协议的选取。
 起/止位
起始位实际上是作为通信信号附加进来的,当它变为低电平时,告诉收方传送开始。它的到来,
表示下面 接着是数据位来了,要准备接收。而停止位标志一个字符的结束。
 奇偶校验位
在串口通信中一种简单的检错方式。有两种检错方式:奇、偶、无。对于偶和奇校验的情况,
串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例
如,如果数据是 011,那么对于偶校验,校验位为 0,保证逻辑高的位数是偶数个。如果是奇校验,
校验位为 1,这样就有 3 个逻辑高位。
12.2 现场工业总线网络基础
当前,现场工业总线已成为世界自动化领域的一个热点,这一涉及整个自动化和仪表工业革命
并使产品全面换代的新技术,在国际上已经引起人们的广泛关注。现场工业总线技术是一种数字化
的串行双向通信系统。这一技术可将所有的现场设备(传感器、执行机构、驱动器等)与控制器
PAC(ProgramAutomation-Control)或 PLC(Program Logic Control)或 PC(Personali ty-computator)
用一根电缆(光缆或无线)连接在一起,形成现场设备级、车间级的数字化通信网络,可完成现场
状态监测、控制、远程传输等功能。现场工业总线技术使现场级设备的信息作为整个企业信息网的
基础,使企业信息的采集控制直接延伸到生产现场。
使用现场工业总线技术不但大大提高了通信能力和系统运行的可靠性,而且大大节省了系统安
装时的布线费用和硬件费用,并更加容易对系统进行管理和维护。这一技术代表了自动化的发展方
向,是工业现场级设备通信的一场数字化革命。
1) 现场工业总线系统的技术特点:
 现场工业总线是专为工业现场层设备通信设计,是为自动化量体裁衣的技术。
 信息时代的技术发展对测控系统提出了数字化、网络化、信息化的要求,如企业的管理控
制一体化等要求测量控制设备向网络提供多方面的数字信息。
 现场工业总线作为现场控制网络技术,被视为公用数据网络在测控领域的延伸,它的兴起
为自控技术本身的发展提供了新的机遇。
 现场工业总线使测控设备具备了数字计算和数字通信能力,提高了信号的测量、传输和控
制精度,提高了系统与设备的功能和性能。
 现场工业总线被视为基于 PC 、特别是基于工业 PC 的控制技术。
 各种工业控制计算机、测量控制板卡的供应商是现场工业总线技术发展的重要力量。
 以现场工业总线技术提升产品的串行通信能力,发展具有数据通信能力的控制网络新的产
品系列,对推广现场工业总线技术的应用以及测量控制领域的信息化,将起到积极作用。
2) 此外,现场工业总线系统对硬件也有一定要求,需要具备如下特点:
 安装容易:模块化结构,体积小,节省空间;标准导轨安装,即插即用。
 使用灵活:用户可根据需要任意将各种功能模块组合到一起,并可根据需要随时更换总线
适配器和其它功能模块,为将来实现现场工业总线统一提供方便。
 功能齐全:能适应多种现场工业总线通讯方式及串行口通讯;功能模块品种多,功能齐全,
包含有适用于各种电压等级信号的开关量输入/输出模块和模拟量输入/输出模块、继电器
模块、计数器模块、电源模块、接口模块等。
 设计经济:每个模块上的通道数量少,为经济的设计现场工业总线节点提供了条件。
 连接快速简单:通过总线适配器将现场工业总线输入/输出系统快速连接到主控系统 PLC
或 PC 。
 防护箱可达 IP65 防护等级:为适应工业现场工业总线系统的发展,例如化工业、食品业
等系统防护需求,以及冶金、化工等工矿企业恶劣的现场环境,提供了具有 IP65 防护等
级的产品。
12.2.1 总线数据通讯模式

当前的网络中有三种通讯模式:单播、广播、组播,其中的组播出现时间最晚但同时具备单播
和广播的优点,最具有发展前景。
1. 源/ 目的通信模式
源/ 目的通信模式是传统的控制系统采用的模式,在同一时间,网络中只有一台设备与另一台
设备之间传送数据,其余设备处于闲置或等待状态,每次信息的传送要经历的环节是:
一台设备(来源)启动信息的传送,另一台设备(目标)的应答,开始传送数据,完成。
考设备之间的呼应构成临时的连接,实现数据传送。
他的数据包由来源设备地址、目标设备地址、数据和校验部分构成,如下所示。
标识符 目标 数据 校验
该模式的特点是:
 每个传输的数据块有各自独立的数据源和目标区域。
 数据在不同时间达到各站点,站和站之间的同步非常困难。
 当目标地址不同时,需多次传送。
 这类网络无需管理,以来令牌传递的方式安排来源设备的信息发动时间和顺序,而这种顺
序往往就是站号。
2. 生产者/消费者的通信模式
生产者/消费者的通信模式是最大范围的数据传送模式,它可以在同一时间,网络中实现一台
设备与多台设备之间数据传输,一台设备播出自己的数据之后,其他设备将同时接收到数据,并靠
识别标识符号来决定获取或舍弃数据,标识符将说明该数据包是否与本设备相关,或数据的那部分
与本设备相关。通常他的数据包由标识符、数据和校验部分组成,如下所示。
标识符 数据 校验
该模式的特点是:
 所有网络节点同步,信息吞吐量大、速度快、网络效率高
 稳定性高和
 特别适用于对时间有苛刻要求的复杂场合的信息传输
这类网络具有管理功能,正是网络管理才能使得信息传送的优先权得到照顾,尽管站好也能构
成信息传送的顺序,但不起主导作用。由于网络的设备之间能够实现建立起固定的连接,不需要在
每次发送信息是都耗用时间来确定双方的通信。

12.2.2 工业控制网络的拓扑结构

工业控制网络主要可以分为总线型、环型、星型和树型等。如下对这几种常用的拓扑结构作分
别作介绍。
1. 总线型网络
总线型拓扑结构是指采用单根传输线作为总线,所有工作站都共用一条总线。当其中一个工作
站发送信息时,该信息将通过总线传到每一个工作站上。工作站在接到信息时,先要分析该信息的
目标地址与本地地址是否相同,若相同则接收该信息;若不相同,则拒绝接收。总线型拓扑结构的
优点是电缆长度短,布线容易,便于扩充;其缺点主要是总线中任一处发生故障将导致整个网络的
瘫痪,且故障诊断困难。
优点:
 结构简单:
网络各接点通过简单的搭线器(T 头)即可接入网络,施工类似接电视天线。
 走线量小:
星型网络需要从中心集线器向每个网络接点单独甩线,如果不用线巢走线的话,地面上经常爬
满一捆一捆的网线。对于装修考究的网吧,必须要用线巢、接线盒走线,这会大量增加布线成本和
工作量,在需要移动接点位置时,更是麻烦。而总线型网络所有接点共用一条电缆,走线量要比星
型小许多倍,并且看起来很规整,除个别处外,可以不用线巢。所以这种布线方式最适合对网速要
求不高,单个房间内有大量接点相临摆放的网吧使用。
 成本较底:
总线型网络因用线量小,无需集线器等昂贵的网络设备,不用线巢、接线盒等结构化布线材料,
成本要大大低于星型网络。如果再采用无盘工作站,是网吧最廉价的解决方案。
 扩充灵活:
星型网络在增加接点数目时有时是一件极其痛苦的事,如果在网络最初规划时留的空间较小,
可能会遇到下列情况可能会因为只增加一个接点而必须购买一个集线器; 要将线槽打开重新下线;
如果线槽已满或用胶沾死,就要重新布线。 而总线型网络只需增加一段电缆和一个 T 头就可增加
一个接点。
缺点:
 最高速度为 10M。
 无法应用交换技术。
 网络无法采用分层结构。
总线型结构网络示意图,如图 8-10 所示。

图 12.X 总线型结构网络示意图

2. 环形网络
环型结构由网络中若干节点通过点到点的链路首尾相连形成一个闭合的环,这种结构使公共传
输电缆组成环型连接,数据在环路中沿着一个方向在各个节点间传输,信息从一个节点传到另一个
节点。
这种结构的网络形式主要应用于令牌网中,在这种网络结构中各设备是直接通过电缆来串接的,
最后形成一个闭环,整个网络发送的信息就是在这个环中传递,通常把这类网络称之为“令牌环网”
实际上大多数情况下这种拓扑结构的网络不会是所有计算机真的要连接成物理上的环型,一般
情况下,环的两端是通过一个阻抗匹配器来实现环的封闭的,因为在实际组网过程中因地理位置的
限制不方便真的做到环的两端物理连接。其拓扑结构图如图 12.x 所示。

图 12.X 环型结构网络示意图
这种拓扑结构的网络主要有如下几个特点:
优点:
 这种网络结构一般仅适用于 IEEE 802.5 的令牌网(Token ring network),在这种网络中,
“令牌”是在环型连接中依次传递。所用的传输介质一般是同轴电缆。
 这种网络实现也非常简单,投资最小。可以从其网络结构示意图中看出,组成这个网络除
了各工作站就是传输介质--同轴电缆,以及一些连接器材,没有价格昂贵的节点集中设备,
如集线器和交换机。但也正因为这样,所以这种网络所能实现的功能最为简单,仅能当作
一般的文件服务模式;
 传输速度较快:随着以太网的广泛应用和以太网技术的发展,以太网的速度也得到了极大
提高,目前普遍都能提供 100Mbps 的网速。
缺点:
 维护困难:从其网络结构可以看到,整个网络各节点间是直接串联,这样任何一个节点出
了故障都会造成整个网络的中断、瘫痪,维护起来非常不便。另一方面因为同轴电缆所采
用的是插针式的接触方式,所以非常容易造成接触不良,网络中断,而且这样查找起来非
常困难,这一点相信维护过这种网络的人都会深有体会。
 扩展性能差:也是因为它的环型结构,决定了它的扩展性能远不如星型结构的好,如果要
新添加或移动节点,就必须中断整个网络,在环的两端作好连接器才能连接。
3. 星型网络
星型网络是指网络中的各节点设备通过一个网络集中设备(如集线器 HUB 或者交换机)连接
在一起,各节点呈星状分布的网络连接方式。这种拓扑结构主要应用于 IEEE 802.2、IEEE 802.3 标
准的以太网中。星型拓扑结构相对简单,是目前局域网普遍采用的一种拓扑结构。采用星型拓扑结
构的局域网,一般使用双绞线或光纤作为传输介质,符合综合布线标准,能够满足多种宽带需求。
其拓扑结构图如图 12.x 所示。

图 12.X 星型结构网络示意图
优点:
 容易实现,但安装、维护工作量,成本较大:
它所采用的传输介质一般都是采用通用的双绞线或同轴电缆。但是每个站点都要和中央网络集
中设备直接连接,需要耗费大量的线缆,并且安装,维护的工作量也剧增。
 节点扩展、移动方便:
节点扩展时只需要从集线器或交换机等集中设备中拉一条电缆即可,而要移动一个节点只需要
把相应节点设备移到新节点即可。
 故障诊断和隔离容易:
一个节点出现故障不会影响其它节点的连接,可任意拆走故障节点;中央节点的负担较重,易
形成瓶颈;各站点的分布处理能力较低:中央节点一旦发生故障,则整个网络都受到影响。
缺点:
 需要耗费大量的电缆,安装、维护的工作量也骤增。
 中央节点负担重,形成“瓶颈”,一旦发生故障,则全网受影响。
 各站点的分布处理能力较低。
4. 树型结构
树型结构是分级的集中控制式网络,与星型相比,它的通信线路总长度短,成本较低,节点易
于扩充,寻找路径比较方便,但除了叶节点及其相连的线路外,任一节点或其相连的线路故障都会
使系统受到影响。

图 12.X 树型结构网络示意图
优点:
 易于扩充。树形结构可以延伸出很多分支和子分支,这些新节点和新分支都能容易地加入
网内。
 故障隔离较容易。如果某一分支的节点或线路发生故障,很容易将故障分支与整个系统隔
离开来。
缺点:
 各个节点对根节点的依赖性太大。如果根发生故障,则全网不能正常工作。
5. 网络中转拓展设备
中转设备是将网段连接起来的关键设备,根据不同的应用场合选用不同的设备,他们各自不同
运用的特点简述如下:
1) 中继器(Repeater)
中继器是连接网络线路的一种装置,常用于两个网络节点之间物理信号的双向转发工作。中继
器主要完成物理层的功能,负责在两个节点的物理层上按位传递信息,完成信号的复制、调整和放
大功能,以此来延长网络的长度。由于存在损耗,在线路上传输的信号功率会逐渐衰减,衰减到一
定程度时将造成信号失真,因此会导致接收错误。中继器就是为解决这一问题而设计的。它完成物
理线路的连接,对衰减的信号进行放大,保持与原数据相同。一般情况下,中继器的两端连接的是
相同的媒体,但有的中继器也可以完成不同媒体的转接工作。从理论上讲中继器的使用是无限的,
网络也因此可以无限延长。事实上这是不可能的,因为网络标准中都对信号的延迟范围作了具体的
规定,中继器只能在此规定范围内进行有效的工作,否则会引起网络故障。图 12.x 为使用中继的
拓扑结构图。

图 12.X 中继器拓扑结构
它是最简单的网络互连设备,连接同一个网络的两个或多个网段。如以太网常常利用中继器扩
展总线的电缆长度,标准细缆以太网的每段长度最大 185 米,最多可有 5 段,因此增加中继器后,
最大网络电缆长度则可提高到 925 米。一般来说,中继器两端的网络部分是网段,而不是子网。
使用中继器的优点:
 扩展节点数量
 减少通讯线缆距离,提高通讯速率(如,IXXAT 的中继器可以减少 40m,200ns)
例如,图 12.x 的 a)中两个节点之间最长距离为 300m(节点 1 至 9),故波特率可以设定为
125kBit/s。图 12.x 的 b)中两个节点之间最长距离为 200m(节点 1 至 6),故波特率可以设定为
250kBit/s。

a) b)

图 12.X 使用中继器比较
a )没有使用中继器 b ) 使用中继器
中继器的类型也有很多种,分为交叉线缆中继、无线中继,光中继和红外中继等。图 12.x 中
的 a)和 b)分别为光中继和红外中继。

a) b)

图 12.X 中继器实物图
a ) 光中继 b ) 红外中继
2) 集线器(Hub)
集线器的主要功能是对接收到的信号进行再生整形放大,以扩大网络的传输距离,同时把所有
节点集中在以它为中心的节点上。它工作于 OSI(开放系统互联参考模型)参考模型第一层,即物
理层。
集线器与网卡、网线等传输介质一样,属于局域网中的基础设备,采用 CSMA/CD(即带冲突
检测的载波监听多路访问技术)介质访问控制机制。集线器每个接口简单的收发比特,收到 1 就转
发 1,收到 0 就转发 0,不进行碰撞检测。
集线器属于纯硬件网络底层设备,基本上不具有类似于交换机的“智能记忆”能力和“学习”
能力,它也不具备交换机所具有的 MAC 地址表,所以它发送数据时都是没有针对性的,而是采用
广播方式发送。也就是说当它要向某节点发送数据时,不是直接把数据发送到目的节点,而是把数
据包发送到与集线器相连的所有节点,如图 12.x 所示。

图 12.x 集线器拓扑结构
3) 网桥(Bridge)
网桥(Bridge)像一个聪明的中继器。中继器从一个网络电缆里接收信号, 放大它们,将其送
入下一个电缆。相比较而言,网桥对从关卡上传下来的信息更敏锐一些。网桥是一种对帧进行转发
的技术,根据 MAC 分区块,可隔离碰撞。网桥将网络的多个网段在数据链路层连接起来,如图
12.x 所示。

图 12.x 网桥拓扑结构
网桥是信号通道相互隔离的两个网段之间的沟通设备,连接的网段可以是相同或不同的媒介质,
有选择地将信息包传送到目标地址。确保有足够的带宽,网桥工作在数据链路的层面(第二层),
如图 12.x 所示。
网段 1,波特率 1MBit/s 网段 2,波特率 250kBit/s

图 12.X 网桥的作用
4) 交换机(Switch)
交换机是综合了集线器和网桥优点的高性能设备,有选择地将信息包送到指定的目标地址。交
换机又可以称为多端口的网桥,每台设备都有独立的带宽可使用,适用于需求足够带宽的情形,作
为以太网网络结构的中心设备,是目前特别推荐使用的设备。交换机工作在数据链路层(第二层),
其结构图与 12.x 类似。
5) 路由器(Router)
路由器又称网关设备,是用于连接多个逻辑上分开的网络,所谓逻辑网络是代表一个单独的网
络或者一个子网。当数据从一个子网传输到另一个子网时,可通过路由器的路由功能来完成。因此,
路由器具有判断网络地址和选择 IP 路径的功能,它能在多网络互联环境中,建立灵活的连接,可
用完全不同的数据分组和介质访问方法连接各种子网,路由器只接受源站或其他路由器的信息,属
网络层的一种互联设备。
6) 网关(Gateway)
大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网
络发送信息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway) 就是一
个网络连接到另一个网络的“关口”。也就是网络关卡。
网关又称网间连接器、协议转换器。默认网关在网络层上以实现网络互连,是最复杂的网络互
连设备,仅用于两个高层协议不同的网络互连。
不同的情况下网关可以有不同的含义,即可以指在两种不同协议的网络或应用之间完成转换的
设备,或将一种协议转换到较为复杂的层面,是在传送层以上的功能,这就像路由器完成的功能;
它也可以充当两个或更多的相同协议网络之间的连接作用,并不需要完成协议的转换,这是网关就
像网络的入口或出口。

图 12.x 网关拓扑结构
如图 12.x,网关设备可以使两个 IP 地址不在同一网段的设备连接在一起。
12.2.3 工业通信协议基础

1. 标准协议
国际标准化组织与 1978 年提出了开放系统互联的参考模型 OSI(Open System Interconnection),
OSI 是一个开放性的通行系统互连参考模型,它是一个定义的非常好的协议规范。OSI 模型有 7 层
结构,每层都可以有几个子层。OSI 的 7 层从上到下分别是应用层 、表示层 、会话层 、传输层 、
网络层 、数据链路层和物理层,其中高层,即 7、6、5、4 层定义了应用程序的功能,下面 3 层,
即 3、2、1 层主要面向通过网络的端到端的数据流。其示意图如图 12.x 所示。

图 12.x OSI 参考模型示意图


RS-232,RS-422/485 均为物理层协议。物理层以上的各层都以物理层为基础,在对等层实现直
接开放系统互联。
 应用层:与其他计算机进行通讯的一个应用,它是对应应用程序的通信服务的。例如,一
个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心
OSI 的第 7 层。但是,如果添加了一个传输文件的选项,那么字处理器的程序员就需要实
现 OSI 的第 7 层。例如:Telnet、HTTP、FTP、WWW、NFS 和 SMTP 协议等。
 表示层:这一层的主要功能是定义数据格式及加密。例如,FTP 允许你选择以二进制或
ASII 格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。如果选择
ASII 格式,发送方将把文本从发送方的字符集转换成标准的 ASII 后发送数据。在接收方
将标准的 ASII 转换成接收方计算机的字符 集。例如:加密,ASII 等。
 会话层:他定义了如何开始、控制和结束一个会话,包括对多个双向小时的控制和管理,
以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在
某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。例如:RPC,SQL 等。
 传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对
不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。
例如:TCP,UDP,SPX。
 网络层:这层对端到端的包传输进行定义,他定义了能够标识所有结点的逻辑地址,还定
义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,
网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX 等。
 数据链路层:他定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。
例如:ATM,FDDI 等。
 物理层:OSI 的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织
制定的标准。连接头、针、针的使用、电流、电流、编码及光调制等都属于各种物理层规
范中的内容。物理层常用多个规范完成对所有细节的定义。例如:RJ45,802.3 等。

2. OSI 分层的优点:
(1)人们可以很容易的讨论和学习协议的规范细节。
(2)层间的标准接口方便了工程模块化。
(3)创建了一个更好的互连环境。
(4)降低了复杂度,使程序更容易修改,产品开发的速度更快。
(5)每层利用紧邻的下层服务,更容易记住各层的功能。
OSI 是一个定义良好的协议规范集,并有许多可选部分完成类似的任务。
它定义了开放系统的层次结构、层次之间的相互关系以及各层所包括的可能的任务。是作为一
个框架来协调和组织各层所提供的服务。
OSI 参考模型并没有提供一个可以实现的方法,而是描述了一些概念,用来协调进程间通信标
准的制定。即 OSI 参考模型并不是一个标准,而是一个在制定标准时所使用的概念性框架。

12.2.4 CoDeSys 支持的通信协议

CoDeSys 能支持市面上大部分工业现场总线,其中包括 Profibus DP、CANopen、EtherCAT、


SERCOS III、DeviceNet、PROFINET 及 Ethernet IP 等,主推两种典型的网络架构,一种是基于
TCP/IP 的以太网,另一种是基于普通双绞线的通讯协议。所有支持的总线如下所示。
 PROFIBUS
 PROFINET
 EtherCAT
 CANopen
 J1939
 DeviceNet
 EtherNet/IP
 Sercos
 AS-i
 Modbus
 IO-Link
 BACnet
 IEC 61850

图 12.X CoDeSys 支持的现场总线通信协议


12.2.5 工业以太网线缆

以太网按照传输速率,分为 10,100,1000Mbit/s 三个等级。根据 ISO/IEC 8802-3 标准,100Mbit


的快速以太网物理指标:
 输入 100BASE – TX;
 全双工, 无需防冲突系统 CSMA/CD;
 四绞线中的 2 条信道的使用:1-2 或者 3-6,因此一根四芯电缆完全足够;
 两个智能设备之间使用点到点连接,连接部分动态联系并通过集成电路建立连接。
100 Mbit / s 以太网的数据流使用三重编码
 4-bit/5-bit 编码 (ISO9314,用于时钟恢复) 125 Mbit/s 数据总流量;
 NRZI 编码 (频率降低,每一个电位表示一个数位) 最大达到. 62.5 MHz “中频段”;
 MLT-3 编码 (频率降低,3 电平代替 2 电平)  最大 31.25 MHz 电缆信号频率; 实际频率取
决于数据流,所以是可变的。
考虑到谐波的产生,根据 EN50173-1 D 类/CAT5 标准,信号传送的频率最大达到 100MHZ,整
个电缆段的连接部分的性能完全达到高速以太网的要求。
1000 Mbit/1 Gbit 以太网一般工作在一个中间的信号频率(62.25 MHz)并且需要所有的四绞线。
一般情况下,一个配置好的符合 Class D 标准的 的电缆段是适用于传输的。GBIT 以太网全部使用
了四绞线,所以这种电缆段是全双工工作模式。建议先进行分段验证,以及 固有限定值(串扰,
回波损耗)等 ANSI/TIA/EIA-TSB-6 (TIA Cat. 5e)数据的测试。
1. 传输总线
传统的以太网铜芯绞线(根据 BS EN 50173 标准)有如下特点:
 最长 90 米的固定电缆(根据 EN50288-X-1 标准),以及两个最长 5 米的电缆连接装置
(根据 EN50288-X-2 标准),总共最长达到 100 米;
 中间部分由最多达到 4 个接插口以及两个终端接口;
 线缆符合 EN50288 标准;
 双耦合器(指两个 RJ45 接口的连接)独立,通常数为两个插头连接;
 所有的电缆必须具备相同的标称特性阻抗:100±5W 或 120 ±5 W @ 100 MHz.;
 可以选择现有的整体电缆屏蔽或 单独的绞线屏蔽。建议 EtherCAT 使用专用的屏蔽电缆。
图 12.x 对传输链路部分进行了展示:

图 12.x 传输链路
1) 模型 A
模型 A 根据 EN50173-1,展示了最大的允许模型,其中包括:
 最大达到 90 米的永久链接,电缆按照 EN50288-2-1 标准;
 总共 6 个 C 型插口连接,包括终端连接点;
 最大有两个遵照 EN50288-2-2 标准的连接电缆,跳线。
验收测试的决定性因素是:
 对于永久链路的测试时根据 EN50173-1 标准,附录 A 包含了两个连接点
 通道测量也是根据 EN50173-1 标准,标准中的第五章并没有包含这两个连接点
这个主要针对楼宇网络建设 SO11801/EN50173 ,从结构上(插线台、中间配电盘、楼层配线
设备)越来越明确。最多有 4 个插头连接可以通过电缆分布在其他位置,比如 配线间隔;见模型 B。
2) 模型 B,C
模型 B,C 在工业领域代表了更为经典的传输链路;他们在 EN50173-1 或者 ISO24702 标准中
有规定。
2. 连接器
由于衰减、反射和线间干扰,一个过渡点对整个的传输链路产生不利影响。因此,符合
EN50173 标准的转换过渡点的数量被限制到 6 个以内。
一个插头连接器(物体 C 在图 1)代表了一个过渡点正处于两个插接器之间

a) b)

图 12.X 简单的插接器转换
a )简单的插接器转换图示 b )简单的插接器转换实物
双耦合器的代表 2 个转换点,除非它已被制造商定义为 1 个转换点的插头。

a) b)

图 12.X 双耦合器
a ) 双耦合器图示 b ) 双耦合器实物
12.x 的 a)为双耦合器的图示,b)图中的左边为 CAT5 的塑料材料,右边为 CAT6 的全金属。
目前只有 CAT6 双耦合器是符合 EN50173-3,附录 B 的标准。可以操作的符合 EN50173 D 类
标准传输链路的性能的维护的任务,CAT6 超过 CAT5 类组件的标准。比如墙通孔,可以用一个简
单的插头/插座过渡。
12.3 CANopen 通讯
CANopen 协议是在 20 世纪 90 年代末,由 CiA 组织(CAN-in-Automation)在 CAL(CAN
Application Layer)的基础上发展而来,一经推出便在欧洲得到了广泛的认可与应用。 经过对
CANopen 协议规范文本的多次修改,使得 CANopen 协议的稳定性、实时性、抗干扰性都得到了进
一步的提高。并且 CIA 在各个行业不断推出设备子协议,使 CANopen 协议在各个行业得到更快的
发展与推广。目前 CANopen 协议已经在运动控制、车辆工业、电机驱动、工程机械、船舶海运等
行业得到广泛的应用。

12.3.1 拓扑结构

1. 拓扑结构
如图 12.x 所示为 CANopen 典型的线型网络结构,该网络中有一个主节点,三个从节点以及一
个 CANopen 网关挂接的其它设备。每个设备都有一个独立的节点地址(Node ID)。从站与从站之
间也能建立实时通信,通常需要事先对各个从站进行配置,使各个从站之间能够建立独立的 PDO
通信。

图 12.X CANopen 网络结构


由于 CANopen 是一种基于 CAN 总线的应用层协议,因此其网络组建于 CAN 总线一致,为典
型的总线型结构,从站和主站都挂在该总线上。通常一个 CANopen 网络中只有一个主站和若干个
从站设备。

12.3.2 运行原理

1.通讯模型
从 OSI 网络模型的角度来看同,现场总线网络一般只实现了物理层、数据链路层、应用层。因
为现场总线通常只包括一个网段,因此不需要传输层和网络层,也不需要会话层和描述层的作用。
CAN(Controller Area Network)现场总线仅仅定义了第 1 层和第 2 层;。实际设计中,这两层
完全由硬件实现,设计人员无需再为此开发相关软件或固件。
由于没有规定应用层,本身并不完整,故需要一个高层协议来定义 CAN 报文中的 11/29 位标
识符、8 字节数据的使用。而且,基于 CAN 总线的工业自动化应用中,越来越需要一个开放的、
标准化的高层协议:这个协议支持各种 CAN 厂商设备的互用性、互换性,能够实现在 CAN 网络中
提供标准的、统一的系统通讯模式,提供设备功能描述方式,执行网络管理功能。
 应用层(Application layer):为网络中每一个有效设备都能够提供一组有用的服务与协议。
 通讯描述(Communication profile):提供配置设备、通讯数据的含义,定义数据通讯方式。
 设备描述(Device proflile):为设备(类)增加符合规范的行为。
CANopen 协议是 CAN-in-Automation(CiA)定义的标准之一,并且在发布后不久就获得了广泛的
承认。CANopen 协议被认为是在基于 CAN 的工业系统中占领导地位的标准。大多数重要的设备类
型,例如数字和模拟的输入输出模块、驱动设备、操作设备、控制器、可编程控制器或编码器,都
在称为“设备描述”的协议中进行描述。在 OSI 模型中,CAN 标准、CANopen 协议之间的关系如
下图所示:

图 12.x CAN、CANopen 标准在 OSI 网络模型中的位置框图


2. 对象字典
CANopen 的核心概念是设备对象字典(OD:Object Dictionary),在其它现场总线(Profibus,
Interbus)系统中也使用这种设备描述形式。
对象字典是一个有序的对象组。每个对象采用一个 16 位的索引值来寻址,为了允许访问数据
结构中的单个元素,同时定义了一个 8 位的子索引,对象字典的结构参照表 12-x。一个节点的对象
字典的有关范围在 0x1000 到 0x9FFF 之间。

表 12-x 对象字典的通用结构
索引 对象
0000 保留
0001 - 001F 静态数据类型 (标准数据类型,如 Boolean,Integer 16)
0020 - 003F 复杂数据类型
(预定义由简单类型组合成的结构如 PDOCommPar,SDOParameter)
0040 - 005F 制造商规定的复杂数据类型
0060 - 007F 设备子协议规定的静态数据类型
0080 - 009F 设备子协议规定的复杂数据类型
00A0 - 0FFF 保留
1000 - 1FFF 通讯子协议区域
(如设备类型,错误寄存器,支持的 PDO 数量)
2000 - 5FFF 制造商特定子协议区域
6000 - 9FFF 标准的设备子协议区域
(例如“DSP-401 I/O 模块设备子协议”:Read State 8 Input Lines 等)
A000 - FFFF 保留
每个 CANopen 设备都有一个对象字典,对象字典包含了描述这个设备和它的网络行为的所有
参数,对象字典通常用电子数据文档(EDS:Electronic Data Sheet)来记录这些参数,而不需要把
这些参数记录在纸上。对于 CANopen 网络中的主节点来说,不需要对 CANopen 从节点的每个对象
字典项都访问。
CANopen 协议包含了许多的子协议,其主要划分为以下三类。
1) 通讯子协议(Communication Profile)
CANopen 由一系列称为子协议的文档组成。 通讯子协议描述对象字典的主要形式和对象字典
中的通讯子协议区域中的对象,通讯参数。同时描述 CANopen 通讯对象。这个子协议适用于所有
的 CANopen 设备,其索引值范围从 0x1000~0x1FFF。
2) 制造商自定义子协议(Manufacturer-specific Profile)
制造商自定义子协议,对于在设备子协议中未定义的特殊功能,制造商可以在此区域根据需求
定义对象字典对象。因此这个区域对于不同的厂商来说,相同的对象字典项其定义不一定相同,其
索引值范围为 0x2000~0x5FFF。
3) 设备子协议(Device Profile)
设备子协议,为各种不同类型的设备定义对象字典中的对象。目前已有十几种为不同类型的设
备定义的子协议,例如 DS401、DS402、DS406 等,其索引值范围为 0x6000~0x9FFF。
注意:
一 个 设 备 的 通 讯 功 能 、 通 讯 对 象 、 与 设 备 相 关 的 对 象 以 及 对 象 的 缺 省 值 由 电 子 数 据 文 档 ( EDS :
Electronic Data Sheet)中提供。
单个设备的对象配置的描述文件称作设备配置文件(DCF:Device Configuration File),它和 EDS 有
相同的结构。二者文件类型都在 CANopen 规范中定义。

3. 服务数据对象 SDO
服务数据对象 SDO 为 Service Data Object 的简称,可以用来存储节点的对象字典,读取或设定
其中的数据。
 通过使用索引和子索引,SDO Client 能够访问设备(服务器)对象字典中的数据。在
CANopen 术语中,上传是指 SDO Sever 中读取数据,下载是指设定 SDO Server 的数据。
 协议是确认服务类型:会为每个消息生成一个应答(一个 SDO 需要两个 ID)。SDO 请求
和应答报文均包含 8 个字节。
4. 过程数据对象 PDO
过程数据对象(PDO)在 CANopen 中用于广播高优先级的控制和状态信息。它是用来传输实时数
据的, 数据从一个生产者传到一个或多个消费者。数据传送限制在 1 到 8 个字节(如,一个 PDO
可以传输最多 64 个数字 I/O 值,或者 4 个 16 位的 AD 值)。 PDO 通讯没有协议规定。PDO 数据内
容只由它的 CAN ID 定义,假定生产者和消费者知道这个 PDO 的数据内容,其模型如图 12.x 所示。

图 12.x 生产者消费者模型
每个 PDO 在对象字典中用 2 个对象描述:
 PDO 通讯参数:包含哪个 COB-ID 将被 PDO 使用,传输类型,禁止时间和周期。
 PDO 映射参数:包含一个对象字典中对象的列表,这些对象映射到 PDO 里,包括它们的数
据长度。生产者和消费者必须知道这个映射,以解释 PDO 数据中的具体内容。
1) PDO 参数设置
若要支持 PDO 的传送/接收,则必须在该设备的对象字典中提供此 PDO 的相应参数设置。单个
PDO 需要一组通讯参数(PDO 通讯参数记录)和一组映射参数(PDO 映射记录)。
在其它情况下,通讯参数指出此 PDO 使用的 CAN 标识符以及触发相关 PDO 传送的触发事件。
映射参数指出希望发送的本地对象字典信息,以及保存所接收的信息的位置。
接收 PDO 的通讯参数被安排在索引范围 1400h 至 15FFh 内,发送 PDO 的通讯参数被安排在索
引范围 1800h 至 19FFh 内。相关的映射条目在索引范围 1600h 至 17FFh 和 1A00h 至 1BFFh 内进行
管理。
2) PDO 触发方式
PDO 分为事件或定时器驱动,远程请求、同步传送(周期/非周期)多种触发方式,如图 12.x
所示。
 事件或定时器驱动:设备内部事件触发 PDO 传送(例如温度值超出特定限值;事件定时器
的时间已过, 等等)。
 远程请求:因为 PDO 由单个 CAN 数据帧组成,所以可以通过远程传送请求(RTR)来请求
这些 PDO。
 同步传送(周期性):PDO 的传送可与 SYNC 消息的接收结合进行。可设定在每 1 到 240 个
SYNC 消息后触发。
 同步传送(非周期性):这些 PDO 由所定义的设备特定事件触发,但在接收到下一个同步消
息时才被发送。

图 12.x PDO 触发方式


5. 网络管理 NMT
所有 CANopen 设备都必须支持 CANopen 网络管理(NMT)从站状态机。NMT 状态机定义
CANopen 设备的通讯行为。CANopen NMT 状态机包括初始化状态、试运行状态、运行状态和停止
状态。在上电或复位后,设备进入初始化状态。

图 12-X CANopen NMT 从站状态机


在设备初始化完成后,设备自动转到试运行状态,并通过发送启动消息指出此状态跳转。通过
这种方法,设备指出已做好工作准备。如果保持试运行状态的设备的服务受支持且配置正确,则这
些设备便可开始发送 SYNC 消息、时间戳消息或心跳消息。相对于在此状态下必须禁用的 PDO 通
讯,设备可通过 SDO 进行通讯。PDO 通讯只有在运行状态下才能实现。在试运行状态期间,设备
可以使用所有受支持的通讯对象。已切换到停止状态的 设备只对接收到的 NMT 命令做出反应。此
外,设备通过在停止状态期间支持差错控制协议,指出当前的 NMT 状态。
NMT 消息通过在 CANopen 网络中作为激活 NMT 主站的设备发送。接收到 NMT 消息后,
CANopen 设备被强制转到指定的 NMT 状态。NMT 消息映 射为数据长度为 2 个字节的单个 CAN 帧。
第一个字节包含命令说明符,第二个字节包含必须执行命令的设备节点 ID。NMT 消息的 CAN 标
识符为 0,该消息在基于 CAN 的系统中具有优先级别。

图 12-X NMT 协议
NMT Module Control 消息不需要应答。NMT-Master 至 NMT-Slave(s)指令格式如表 12-x 所示。

表 12-x NMT 指令格式


COB-ID Byte 0 Byte 1
0x000 命令字 节点号
当节点号为 0 时,则所有的 NMT 从设备被广播寻址。命令字对应数据可参考表 12-x:

表 12-x NMT 命令字


命令字 说明
0x01 启动远程节点
0x02 停止远程节点
0x80 进入预操作状态
0x81 复位节点
0x82 复位通讯
6. 设备监控
CANopen 规范中,监控设备(错误控制)的服务和协议用于检测网络中的设备是否在线和设
备所处的当前状态。其中 NMT 指令在应用层中进行确认,CANopen 网络管理系统提供以下几种用
于设备监控的功能:
 Heartbeat:它是一种周期性地发送给一个或多个设备的消息,设备之间可以互相监视。
 Node Guarding:NMT 主机通过远程帧周期性地监控从机的状态。
 Life Guarding:通过收到的用于监视从机的远程帧来间接监控 NMT 主机的状态。
注意:
用户只能采用 Heartbeat 或 Node/Life Guarding 这两种方法中的一种来进行设备监控。建议使用
Heartbeat,因为这种方法能实现更加灵活的监控结构,而且不需要使用远程帧。
若采用心跳机制,CANopen 设备将根据“Producer Heartbeat Time”中所设置的周期来发送心
跳报文,该周期通常以 ms 为单位。
如果采用 Node/Life Guarding 方式,用户必须在 NMT 主站中说何只一个包含 CANopen 设备监
视时间的表格。监视过程中,主机将根据表格中设置的时间,通过远程帧周期性的查询所有设备,
设备会用包含当前设备状态的数据帧来应答主机。对象字典中 Guard Time 规定了两次查询之间的
间隔时间,单位为 ms。Life Time Factor 为寿命系数,该系数与保护时间相乘所得到的时间,就是
主机查询设备的最迟时间。这种机制称为寿命保护,有了这种机制,CANopen 设备识别 NMT 主机
故障就得到了保障。
7. CANopen 启动过程
在网络初始化过程中,CANopen 支持扩展的 Boot-up,也支持最小化 boot-up 过程。可以用节
点状态转换图表示这两种初始化过程,如图 12-x 所示。

图 12-X CANopen 最小化 Boot-up 节点状态转换图


图 12-X 中括号内的字母表示处于不同状态那些通讯对象可以使用。
a. NMT , b. Node Guard , c. SDO , d. Emergency , e. PDO , f. Boot-up
状态转移(1-5 由 NMT 服务发起),NMT 命令字(在括号中)如表 12-x 所示:

表 12-x NMT 状态转移表


状态 说明 命令字
1 Start_Remote_node 0x01
2 Stop_Remote_Node 0x02
3 Enter_Pre-Operational_State 0x80
4 Reset_Node 0x81
5 Reset_Communication 0x82
6 初始化结束后,自动进入 Pre_Operational 状态,发送 Boot-up
在任何时候 NMT 服务都可使所有或者部分节点进入不同的工作状态。NMT 服务的 CAN 报文
由 CAN 头 (COB-ID=0) 和 两 字 节 数 据 组 成 ; 第 一 个 字 节 表 示 请 求 的 服 务 类 型 (NMT command
specifier),第二个字节是节点 ID,或者 0(此时广播寻址所有节点)。
8. CANopen 预定义连接集
CANopen 预定义连接是为了减少网络的组态工作量,定义了强制性的缺省标识符(CAN-ID)
分配表,该分配表是基于 11 位 CAN-ID 的标准帧格式。将其划分为 4 位的功能码和 7 位的节点号
(Node-ID)。如图 12.x 所示,在 CANopen 里也通常把 CAN-ID 称为 COB-ID(通信对象编号)。

图 12-X 预定义连接 ID
其中节点号由系统集成商给定,每个 CANopen 设备都需要分配一个节点号,节点号的范围为
1~127(0 不允许被使用)。预定义连接集定义了 4 个接收 PDO(Receive-PDO)、4 个发送 PDO
(Transmit-PDO)、1 个 SDO(占用 2 个 CAN-ID)、1 个紧急对象和 1 个节点错误控制(Node-
Error-Control)ID。也支持不需确认的 NMT 模块控制服务、同步(SYNC)和时间标志(Time Stamp)
对象报文。

12.3.3 电缆和接头

1. 线缆
CANopen 连接各个设备站点的电缆是带屏蔽的双绞线,传输线的终端电阻为 120 欧。在整个
网 络 中 包括 主 站在 内的站 点 数 ,最 多 不能 超过 127 个 。电 缆 的信 号为 CAN_H, CAN_L 和
CAN_GND。在同一个网络内,各个站点的通信速率要求配置一样。通信波特率为 5Kbps~1Mbps,
在通信的过程中要求每个节点的波特率保持一致(误差不能超过 5%),否则会引起总线错误,出
现通信异常。请参见表 12-x 电缆长度和速率的配置。

表 12-x 波特率与最长通讯距离的关系
波特率kBit/s 1000 800 500 250 125 50 20 10

最大线缆长度m 25 50 100 250 500 1000 2500 5000


终端电阻的作用:终端电阻是为了消除在通信电缆中的信号反射在通信过程中,有两种信号因
导致信号反射:阻抗不连续和阻抗不匹配。
阻抗不连续,信号在传输线末端突然遇到电缆阻抗很小甚至没有,信号在这个地方就会引起反
射。这种信号反射的原理,与光从一种媒质进入另一种媒质要引起反射是相似的。消除这种反射的
方法,就必须在电缆的末端跨接一个与电缆的特性阻抗同样大小的终端电阻,使电缆的阻抗连续。
由于信号在电缆上的传输是双向的,因此,在通讯电缆的另一端可跨接一个同样大小的终端电阻。
引起信号反射的另个原因是数据收发器与传输电缆之间的阻抗不匹配。这种原因引起的反射,主要
表现在通讯线路处在空闲方式时,整个网络数据混乱。 要减弱反射信号对通讯线路的影响,通常
采用噪声抑制和加偏置电阻的方法。

注意:
网络中各节点的支线长度不宜过长,在波特率大于 100bit/s 的情况下,支线总长度不应大于 30m,单个
节点的支线长度不应大于 60cm。

2. 接头
在控制器的 CANopen 总线口被设计为 9 针 D 型口。如图 12.x 的左上角所示。通常 CANopen
在现场中使用带 D 型插头的电缆,它的优点是抗干扰性强,可靠性高。在控制柜中采用 RJ45 接头
进行连接,如图 12.x 中的右上角所示,它的优点是布线简单又快捷。

RJ45 接头
9 针 D 型口

5 针 M12 圆形插头
开放式端子
图 12.X CANopen 不同的总线接头

12.3.4 PDO 通讯示例

在 CANopen 中通常采用过程数据对象 PDO 传输的方式进行控制器和设备的通讯,那么我们需


要怎么的组态呢?
1. 主站配置
当 CoDeSys 所连接的设备作为 CANopen 主站时,需要做如下的配置。
1) 添加 CANopen 总线主站:
首 先 ,在 CoDeSys 中 添 加 CANopen 总 线接 口,如 图 12.x 所 示, 根据 名称 分 类, 由 于
CANopen 属于现场总线,在其中找到 3S 公司的“CANbus”,单击“插入设备”,完成 CANopen
总线接口的添加。如主站为其他供应商所提供,则根据实际情况选择主站。

图 12.x 添加 CANopen 主站卡


2) 添加 CANopen Manager
完成步骤 1)的总线接口添加后,在自动添加的树形结构菜单中找到“CANbus”,右键选择
“添加设备”,添加“CANopen Manager”,CANopen Manager 可以对总线进行参数配置,添加步
骤如图 12.x 所示。
图 12.x 添加 CANopen Manager
(1) CANopen 管理器:
CANopen Manager 添加后,在“CAN 总线配置”中,可以配置 CAN 总线节点的子节点。它通
过内部函数支持 CAN 总线配置,通常被用作 CAN 总线的主站。
CANopen 管理器对话框目前可以为总线上的 PDO 过程数据传输启用同步模式以及及其他总线
相关参数,管理器设置界面如图 12.x 所示。

图 12.x CANopen 管理器主界面


a) 概述:
节点 ID:该 ID 用于设置/识别 CANopen 管理器的站号(即主站站号),默认值为 127,可设
置范围为 1-127。
自动启动 CANopen Manager:如果该选项被激活,如果所有从站都已经准备好,则 CANopen
管理器将会自动启动进入“Operation”模式。否则需要手动启动,比如使用过 CiA405 协议中的
NMT 功能块,通过 CoDeSys 程序来进行程序启动。
启动从站:如果该功能被启用,则由 CANopen 管理器负责自动启动从站,否则则由 CiA405 协
议中的 NMT 功能块来进行程序启动。
可选从站轮询:如果从站没有在 Boot-up 过程中及时响应,则每秒钟都会发送请求直至对方响
应为止。
NMT Error Behaviour:如当 NMT 出现故障时,可以选择重启从站或选择停止从站。
b) 同步:
同步主要功能如下,
 在网络范围内同步(尤其在驱动应用中):在整个网络范围内当前输入值准同时保存,随
后传送(如果需要),根据前一个 SYNC 后接收到的报文更新输出值。
 主从模式:SYNC 主节点定时发送 SYNC 对象,SYNC 从节点收到后同步执行任务。
 在 SYNC 报文传送后,在给定的时间窗口内传送一个同步 PDO。
 用 CAL 中基本变量类型的 CMS 对象实现。
 CANopen 建议用一个最高优先级的 COB-ID 以保证同步信号正常传送。SYNC 报文可以不
传送数据以使报文尽可能短。
COB-ID:发送同步帧的 COB-ID 号。
循环周期:同步帧发送的循环周期时间。
窗口长度:PDO 时间窗口的同步时间。
c) 心跳
使能心跳报文,一个节点可被配置为产生周期性的被称作心跳报文(Heartbeat)。心跳报文是
通过 Heartbeat Producer 发送给 Consumer(s)的,当一个 Heartbeat 节点启动后它的 Boot-up 报文是其
第一个 Heartbeat 报文,心跳报文对应 COB-ID 的内容如表 12-x 所示。

表 12-x 心跳报文状态
状态 定义
0 Boot-up
4 Stopped
5 Operational
127 Pre-operational
节点:Heartbeat Producer 发送的节点号。默认为 127,即 CANopen 主站。
生产时间:心跳报文发送的间隔时间。
d) 时间
时间标记对象 Time Stamp 功能,如果开启后 CANopen 管理器则会根据相关设定发送时间信息。
COB-ID:发送时间戳的 COB-ID,默认由 16#100H。
生产时间:时间戳发送的间隔时间,必须是任务循环时间的倍数关系。
至此,所有的主站通讯参数已经设置完毕。
2. 从站配置
添加完主站后,也要针对从站作相应设置,如下会对此做详细介绍。
1) 安装 EDS 文件
在主菜单中的“工具”按钮中找到“设备库”并点击。会弹出 12.x 的对话框,点击“安装”。

图 12.x 安装设备文件
随即,会弹出 12.x 的如下对话框,在下拉菜单中选择“EDS 和 DCF”文件,然后找到对应
EDS 文件存放地添加即完成 EDS 的添加工作。

图 12.x 选择添加的文件类型
2) 添加 CANopen 从站设备,鼠标单击选中之前添加的主站“CANopen Manager”右键,选择
“插入设备”,弹出如图 12.x 所示的对话框。
图 12.x 添加 CANopen 远程设备
如果所需要连接的设备并未在该列表中罗列,则需要通过手动添加 EDS 文件添加该远程设备。
3) CANopen 远程设备:

图 12.x CANopen 标准远程设备主界面


如图 12.x 所示,为 CANopen 远程设备标准主界面,在该配置对话框中,可设定设备的节点
ID(1-127)。当选中“使能专家设置”选项后,该对话框则会根据设备描述文件(EDS)提供的
参数供用户修改。专家设置如图 12.x 所示。

图 12.x CANopen 专家远程设备主界面


a) 概述:
节点 ID:从站节点号,可设定的范围为 1-127。
创建全部 SDO:所有的对象会被写入从站的对象字典。
使能同步发生器:如果开启,则该从站支持同步传输方式,具体同步时间在 CANopen 管理器
中设置。
可选设备:如果激活该选项,则在 CAN 网络中不会启动该设备。
未初始化:如果该选项被激活,则主站不会发送 SDO 配置信息及 NMT 启动指令至从站。
复位节点:取决于该内容在硬件设备中是否存在,如果存在,启用后,将会重置所有的
CANopen 参数,
b) 节点保护:如果启用该功能,则会根据“Guide Time(ms)”中所设定的间隔时间发送信息,
默认为 100ms。节点也可以使用“Life Time Factor”进行节点保护,NMT 主节点发送远程请求到该
节点,节点给出应答,应答报文中包含了这个节点的状态,如果没有应答,则认为该节点“不可
用”。
c) Heartbeat : 可 以 设 置 Heatbeat Producing 及 Heartbeat Consuming 的 使 能 及 间 隔 时 间 ,
Heartbeat Consuming 的设置属性如图 12.x 所示。

图 12.x Heartbeat Consuming 属性


d) 紧急情况:可设置使能紧急情况,如果当总线出现故障时,被设置的 COB-ID 则会发出错
误信息。
e) 时间:该功能取决于从站是否支持该功能。可以设置 Time Producing 及 Time Consuming,
以及发送时间戳的 COB-ID。
f) 在重新启动时检查
如果相关选项被使能,则 CANopen 从站的 Firmware 版本信息会和 EDS 文件中的信息进行对比,
如果信息不匹配,则从站不能被启动。可检查的信息有供应商 ID,产品号及版本号。
4) PDO 映射关系
该选项用于显示当前已配置的 TPDO 和 RPDO 的具体参数,如图 12.x 所示。如用户需要添加/
删除或修改映射地址,则需要在“接收 PDO 映射”和“发送 PDO 映射”中进行设置。

图 12.x PDO 映射
双击黑色加粗字体选项,可以对具体 PDO 进行设置,可以设置其 COB-ID,传输类型的方式,
异步数,具体如图 12.x 所示。
图 12.x PDO 属性设置
5) 接收 PDO 映射/发送 PDO 映射:

图 12.x 接收 PDO 映射/发送 PDO 映射


a) 根据图 12.x 所示,第一步,先添加 PDO,点击“添加 PDO”后,会自动弹出图 12.x。

图 12.x 添加 PDO
添加的 PDO 可以自定义其 COB-ID 以及传输类型。当确认完后,点击“确定”系统则会为该
PDO 生成 COB-ID,但是生成后的 PDO 并不具备通许能力,需要用户对该 PDO 进行变量映射,根
据 CANopen 的协议,每个 PDO 支持传输的数据大小为 8Byte。
b) 添加映射:
第二步,鼠标选择“添加映射”,先添加 PDO,点击“添加 PDO”后,会自动弹出图 12.x,
选择索引及子索引,鼠标点击“确定”。
图 12.x 添加映射
6) CANopen I/O 映射

图 12.x CANopen I/O 映射


在该选项卡中,可以查看 CANopen I/O 映射关系、功能描述、实际地址以及映射变量的类型。
7) CANopen 状态:

图 12.x 设备状态信息
该选项卡给用户提供设备状态(如“Running”,“Stop”)以及设备的诊断信息。
12.3.5 SDO 通信示例

采用 PDO 方式做数据交换,简单且直接。但受到数量限制,而且不用这些数据都会占用总线,
会造成连接在总线上的设备不能太多。
SDO 通讯主要用于主节点对从节点的参数配置。用来在设备之间传输大的低优先级数据,典
型的是用来配置 CANopen 网络上的设备,在设备发出 NMT 命令之前,主站会使用 SDO 对各从站
进行如 PDO 映射数据的读写操作,一旦结束才开始发送 NMT 启动命令,之后默认值有 PDO 的操
作。
如果要使用 SDO 方式通讯,在 CoDeSys 中实现需要添加制定功能块,并且需要在 POU 中写程
序。
1. 库文件组态
在 CoDeSys 如果已经添加过 CANbus 总线,则系统会自动加入该库文件,否则需要手动添加库
文件“CAA Cia405”,添加后即可在该库文件中看到“SDO access”文件夹,如图 12.x 所示。

图 12.x 添加库文件

2. 添加 POU
图 12.x 中,“SDO access”文件夹中,有 4 个 CANopen SDO 通讯功能块。第一组 SDO_READ,
SDO_WRITE 这 一 组 对 参 数 的 读 / 写 参 数 对 象 是 任 意 大 小 的 ; 另 外 一 组 为 SDO_READ4 ,
SDO_WRITE4,该功能块可以读/写对象的 4 个字节。
如下,以 SDO_READ 为例说明如何使用该功能块,该功能块的图形化界面如图 12.x 所示,调
用时只需要填入相应输入/输出参数即可使用。表 12-x 罗列了该功能块各输入/输出的具体说明。
图 12.x SDO 读取功能块

表 12-x SDO_READ 功能说明


类型 名称 类型 说明
输入 NETWORK USINT 总线接口号,如 CAN0。
ENABLE BOOL 功能块使能
TIMEOUT UDINT 读取超时
DEVICE CIA405_DEVICE 设备号,范围: 0 … 127
CHANNEL USINT SDO 通道号范围: 0 … 128
INDEX WORD 索引号
SUBINDEX BYTE 子索引号
输出 CONFIRM BOOL 输出确认信号
ERROR CIA405_CANOPEN_ KERNEL_ERROR 故障信息
DATA POINTER TO BYTE 输出结果指针
ERRORINFO CIA405_SDO_ERROR SDO 故障代码

输入/输出 DATALENGTH UINT 数据长度(字节)


当 ENABLE 有上升沿触发信号后,则该功能块会根据填写的输入参数,DEVICE,INDEX 和
SUBINDEX 读取参数。DEVICE 的设置范围为 1 至 127。如果 ENABLE 一直为 TRUE,系统会继续
读取下一个周期的 SDO 数据,并将其结果输出至 DATA。直至 ENABLE 信号 OFF,则读取终止。
具体实现时序图如图 12.x 所示。

图 12.x SDO_READ 读取功能时序图


【例 12.x】SDO 通讯举例,通过 SDO 读取对象的回零点速度。读取对象为 FESTO 所生产的
CMMS-AS 系列的伺服驱动器。
1) 先确定对象的索引以及子索引,使用程序添加功能块最终实现该功能。
通过在供应商的官方网找查找产品的手册或直接打开对象的 EDS 文件找到“回零点速度”的
索引及子索引。
在此介绍一款免费的 EDS 文件查看器,有德国的 Vector 所提供,使用它可以直接方便的编辑
EDS 文件。可以在 http://canopen-solutions.com/canopen_caneds_en.html 进行免费下载。EDS 文件查
看器,如图 12.x 所示。

图 12.x Vector 所开发的 CANeds


使用 CANeds 打开该伺服驱动器的 EDS 文件。故由此可知,该对象的索引号为“6099”,子
索引为“3” ,如图 12.x 所示。

图 12.x Vector CANeds


2) 创建 POU,使用输入助手添加对应 SDO 读取功能块,再次可以使用“SDO_READ”或
“SDO_READ4”。本例中使用“SDO_READ”,如图 12.x 所示。
图 12.x 添加 SDO 读功能块
3) 添加功能块的参数,可以通过程序开始功能块并实时读取该参数。通过置为 bRead 技能实
现读取“回零点速度”速度,程序如图 12.x 所示。

图 12.x 使用 FBD 编程语言使用 SDO 读取命令


上述例程中,通过 SDO 读取功能块,最终将数据的结果存放在变量 ReadData 的内存地址中。
12.4 Modbus 网络基础
Modbus 是由 Modicon 公司(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一
个正真用于工业现场的总线协议。
Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器
经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂
商生产的控制设备可以连成工业网络,进行集中监控。
Modbus 有如下三种通讯方式:
 以太网,对应的通信模式是 ModBus TCP,取决于 IETF 标准:RFC793 和 RFC791。
 异 步 串 行 传 输 ( 各种 介质 如 RS-232/422/485 ; 光纤 、 无 线 等 ) , 对应 的通 信 模 式 有
Modbus RTU 或 ModBus ASCII,取决于 TIA/EIA 标准:232-F 和 485-A。
 高速令牌传递网络,对应的通信模式是 Modbus PLUS。
本书主要针对 Modbus RTU 及 ModBus TCP 做详细介绍。
但无论是以太网的 ModBus TCP 还是异步串行传输 Modbus RTU/ ASCII 通讯都有相应的 OSI 通
信模型说明两个通信规程的,图 12.x 为 Modbus 两种通信方式的模型。

图 12.x Modbus OSI 通信模型

12.4.1 协议描述

自从工业串行链路标准诞生以来,将 Modbus 协议应用于自动化设备,并实现数据通信的案例


数不胜数,并且 Modbus 组织持续增加对 Modbus 结构的支持。
从 OSI 模型可以看出 Modbus 协议是应用层上的应用层报文传输协议,它能作用于不同类型的
总线或网络。Modbus 是依据协议所提供的功能码为用户提供特定的功能服务。Modbus 实现请求/
应答重要的一个因素就是 Modbus 功能码。Modbus 协议之所以能迅猛发展,与其允许在各种网络
体系结构内进行简单通信密不可分。图 12.x 为 Modbus 网络体系结构图。
图 12.x Modbus 网络体系结构
每种设备包括 HMI(人机界面)、控制面板、PLC(可编程逻辑控制器)、驱动程序、输入输出设
备都能使用 Modbus 协议来启动远程操作。在基于串行链路和 TCP/IP 网络的 Modbus 上可以进行相
互通信。一些网关允许在几种使用 Modbus 协议的总线或网络之间进行通信。

12.4.2 Modbus 串口协议描述

Modbus RTU 采用十六进制数传输模式。Modbus 串行链路协议是一个主从协议,该协议位于


OSI 模型的数据链路层。用异步串口通信的方式进行数据通信。在 OSI 模型的物理层上,采用
RS485/RS232。传输速率可以达到 115Kbps,依据 Modbus 协议格式,一个主站至多连接 247 台从
站。但是由于硬件条件的限制,一般最多连接 32 台从站。
图 12.x 和 12.x 给出了 Modbus 串行通信栈对应于应用层 OSI 模型的一般关系。
图 12.x Modbus 串行栈模型

图 12.x Modbus 协议和 ISO/OSI 模型


Modbus 应用层报文传输协议位于 OSI 模型的应用层,为连接于总线或网络的设备之间提供通
信。在 Modbus 串行链路上客户机的功能由主节点提供,而服务器功能由子节点实现。
Modbus 协议有 RTU 和 ASCII 两种传输方式,图 12.x 详细描述了 RTU 的传输模式:

图 12.x RTU 传输模式


Modbus 协议的通讯方式分为单播和广播两种方式,如图 12.x 所示,a)为单播通讯方式,b)
为广播通讯方式。

a) b)
图 8.X Modbus 通讯方式
a )单播 b )广播
当主站向特定某个从站发送指令,并等待从站应答,这种方式就是单播方式。从站在接收到指
令后,根据功能码执行命令,并将结果返回给主站。在这种通信方式下,从站地址唯一,地址从 1
到 247。
相对应,广播方式是主站不需要等待从站应答,它向所有从站发送指令。从站在接到指令并执
行后,也不需要向主站发送应答。
Modbus 帧包含了一个协议数据单元(PDU),该单元结构和基础通信层没有关联;为了在特
定总线或网络上运作,Modbus 协议在应用数据单元(ADU)需要添加特定域信息。通用 Modbus
帧如图 12.x 所示:
图 12.x Modbus 数据帧

12.4.3 Modbus TCP 协议描述

Modbus TCP 是 Modbus 系列通讯协议的派生品,是由 Modicon 开发完成。1999 年公布了其规


范,开始用在以太网上,2004 年开始,Modbus TCP 成为 PAS 文件,Modbus TCP 基于以太网和标
准 TCP/IP 技术,并直接安插在第四层的 TCP/UCP 上。它定义了一个简单的开放式又广泛应用的传
输协议网络用于主从通讯方式,一个综合的结构的协议暂时没有考虑。
Modbus TCP 在网络协议层上很容易被辨识,由于 TCP 能处理很大数量的并发请求,因此对于
Modbus TCP 协议,单一的连接即可支持多个独立事件。
Modbus TCP/IP 的通信系统包括以下几种类型的设备:
 网络互连设备,包括中继器、网桥、路由器、桥由器、和网关等;
 挂载在 Modbus TCP/IP 网络上的服务器和客户机设备。
图 12.x 是 Modbus TCP/IP 的通信结构:

图 12.x Modbus TCP 通信结构


与 Modbus 串行链路协议不同,Modbus TCP 协议在 TCP/IP 上使用一种专用报文头,这种报文
头称为 MBAP 报文头。由于该报文头的存在,使得 Modbus 格式数据在 TCP 上传输时,即使被分
割成多个数据包传输,接收者也能识别出报文边界。这是因为报文头携带有长度信息。Modbus
TCP 的请求或响应帧如图 12.x 所示:

图 12.x Modbus TCP 数据帧


由 MBAP 报文,可以得出 Modbus/TCP 与 Modbus/RS485 的帧结构存在着以下差别:
1) Modbus 串行链路上使用的从地址位,在 Modbus/TCP 上由 MBAP 报文头中的单元标识符
所代替。该标识符是串行链路或其他总线上连接的远程从站识别码。
2) 当 Modbus/TCP 数据过大时,需将报文分成多个信息包来传输,并且为了方便接收者能识
别报文边界,协议在第 5、6 两个字节处添加长度标识符。由于显式和隐式长度规则的关
系,将对请求或响应报文不会造成影响,同时 CRC 差错校验码的使用也将减少可能产生
的未检出干扰。
3) 由接收者完成报文检验,通过这种方式设计所有的 Modbus 请求和响应。对于在请求或响
应中携带一个可变数据的功能码来说,数据域包括字节数。对于 Modbus PDU 有固定长度
的功能码来说,仅需功能码就足够了。
整个 MBAP 报文头长为 7 个字节,其中域定义如下:

图 12.x MBAP 报头文

12.4.4 运行原理

Modbus 是 OSI 模型第 7 层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备


之间提供客户机/服务器通信。它是一个请求/应答协议,并且提供功能码规定的服务。Modbus 功能
码是 Modbus 请求/应答 PDU 的元素。
Modbus 协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上
的 Modbus 协议映射能够在应用数据单元(ADU)上引入一些附加域,数据帧格式如图 12.x 所示。

图 12.x Modbus 数据帧

1. 通讯过程
当服务器对客户机响应时,它使用功能码域来指示正常(无差错)响应或者出现某种差错(称
为异常响应)。对于一个正常响应而言,服务器仅对原始功能码响应。如图 12.x 所示。
图 12.x Modbus 数据处理(无差错)
对于异常响应,服务器返回一个与原始功能码等同的码,设置该原始功能码的最高有效位为逻
辑 1。如图 12.x 所示。
Modbus 最初在串行俩路上的实现(最大 RS-485 ADU=256 字节)限制了 PDU 的长度。Modbus
PDU=256-服务器地址(1 字节)-CRC(2 字节),这是 ModbusPDU 的最大长度。

图 12.x Modbus 数据处理(异常响应)

2. 数据模型
MODBUS 以一系列具有不同特征表格上的数据模型为基础。四个基本类型如表 12-x 所示。

表 12-X 公共功能码类型
基本数据表 对象类型 属性 说明
离散量输入 1位 只读 I/O 系统提供这种类型数据
线圈 1位 读写 通过应用程序改变这种类型数据
寄存器输入 16 位字 只读 I/O 系统提供这种类型数据
寄存器输出 16 位字 读写 通过应用程序改变这种类型数据

a) b)

图 6.x Modbus 数据模型


a) 分离数据块的数据模型 b) 单一数据块的数据模型

图 12.x 为 Modbus RTU 调试软件,图中的 1)可以对选择端口,2)可以对通讯参数进行设置。


波特率:9600/14400/19200/38400/56000/57600/115200/128000/256000。
数据位:7/8。
奇偶校验:NONE/ODD/EVEN。
停止位:1/2。

3. 查询-回应周期
在消息位,Modbus 协议仍然提供了主—从原则,尽管网络通信方法(如 Internet 网)是对等的,如
果一控制器发送一消息,他只是作为主设备,并期望从从设备得到回应。同样,当控制器收到消息,
它将建立从设备回应格式并返回给发送的控制器。
主设备向从设备发送查询信号,其中包含命令控制字、从设备地址、需要传输的参数等信息,
从设备收到查询信号后作出相应的操作执行相关动作、反馈主站读取的数据、命令执行情况等,向
主设备作出应答。同过程中如果出现了故障,导致信息无法到达目的地,主、从站超时定时器满后
放弃该操作,继续下一操作。图 12.x 给出了主从查询响应周期图、帧的组成结构。

图 12.x Modbus 主从查询响应周期图


 查询
查询消息中的功能代码告知被选中的从设备要执行何种功能。数据段包从设备要执行功能的任
何附加消息:要读(或写)的寄存器起始地址及要读或写的寄存器数量。错误检测域为从设备提供了
一种验证消息内容是否正确的方法。
 响应
如果从设备产生一个正常回应,在回应消息中的功能代码是查询中的功能代码的回应。数据段
包含了从设备收集的数据被查询寄存器的值或状态。如果有错误发生,功能码将被修改以用于指出
回应消息是错误的,同时数据段包含了描述此错误的代码。错误检测域允许主设备确认消息内容是
否可用。
4. RTU 模式
设备在 Modbus 串行链路上使用 RTU(远程终端单元)模式通信时,报文中每 8 位字节分为两个
4 位十六进制字符。这种模式的优点是有较高的字符密度,在相同的波特率下,,比 ASCII 模式有更
高的吞吐量。必须要连续的字符传输每个报文。
1) RTU 消息帧
RTU 模式的格式为 8 位二进制编码系统,每个字节 11 位
每个字节位包括:
 1 个起始位;
 8 个数据位;
 1 个奇偶校验位(如果没有奇偶校验则此位亦为停止位);
 1 个停止位。
RTU 报文帧包括从站地址、功能码、数据、CRC 校验,其结构如图 12.x 所示:
图 12.x RTU 报文帧
帧与帧之间最少 3.5 个字符时间的长度,称为t 3。5。起始帧前至少空闲t 3。5 ,字符间时间长度
不得超过个 1.5 字符长度,否则认为是不完整帧,,服务器将丢弃该帧。如图 12.x 所示

图 12.x Modbus 帧间间隔


2) RTU 传输模式状态图
主站和从站均在同一个图中表示,如图 12.x 所示。
a) 从“初始”状态到“空闲”状态转换至少需要t 3。5时间长度。保证帧间延时。
b) “空闲”状态是没有发送和接收报文要处理的正常状态。
c) 在 RTU 模式中,当时间间隔大于或等于t 3。5没有传输激活时,系统将回到空闲状态
d) 当链路处于空闲状态时检测到一个任何一个传输的字符,该字符被认是起始帧。当时间间
隔超过t 3。5还没有接收到字符时,视为帧结束。
e) 检测到帧结束后,执行 CRC 校验。分析地址字段来确定是否要做相应的处理。如果不是
发送到该设备的,则抛弃接收到的帧。

图 12.x RTU 传输模式的状态图


图 12.x 为 CoDeSys 中 Moodbus RTU 的通讯参数设置图。
图 12.x Modbus RTU 通讯参数设置
偶校验是要求的, 其它模式(奇校验, 无校验)也可以使用。为了保证与其它产品的最大兼
容性,同时支持无校验模式是建议的。默认校验模式模式必须为偶校验。
注意:
当校验方式为“NONE”无校验时要求 2 个停止位。

5. ASCII 模式
当使用 ASCII 模式设置设备在 Modbus 串行链路上通信时,用两个 ASCII 字符发送报文中的一
个字节。当通信链路中不能满足 RTU 模式的时间要求时,使用该模式。所以该模式比 RTU 模式效
率低。
ASCII 模式中每个字节 10 位,代表一个字符,其格式如下
编码系统:
 十六进制,ASCII 字符。0~9,A~F;
 报文每个 ASCII 字符含有一个十六进制字符。
每个字节的位
 1 个起始位;
 7 个数据位,地有效位先发送;
 1 个奇偶校验位;
 1 个停止位。
ASCII 报文帧:
传送设备将 Modbus 报文放置在带有己知起始和结束的帧中。帧的起始字符是冒号“:”(十
六进制 0x3A),结束字符是回车一换行“CRLF”(十六进制 0x0D 和 0x0A)。帧结构如图 12.x
所示。

图 12.x ASCII 报文帧


设备侦听总线上的“:”字符,一旦检测到起始字符,则连续接收直到检测到结束字符为止,
然后开始进行 LRC 校验。但是如果在接收帧的过程中间收到一个“:”字符,则认为出错,抛弃所
有接收到的收据并清空缓冲区。
报文字符间时间间隔可以达到 1s,如果时间间隔超过 1s,则认为传输出错。图 12.x 综述了
ASCII 报文帧传输状态。
图 12.x ASCII 传输模式的状态图

6. CRC 校验
CRC 字段包含两个 8 位字节附加到报文后面,先附加字段的低字节,后附加高位字节。接收端
收到一帧后,先对不包含 CRC 字段的所有字节进行 CRC 计算,把计算的结果和接收到的 CRC 字
段相比较,相同则表示传输正常,否则传输出错。
7. 常用公共功能码
功能码指示从设备应该执行什么动作。若应答的功能码最高位被置位,则表示从设备不能够正
确执行此功能码。若一致,则表示从设备能够正确执行此功能,并能够返回功能码所需要的数据
(如果有)。Modbus 常用的公共功能码如表 12-x 所示。

表 12-X Modbus 常用公共功能码


常用公共功能码 功能码
位操作 开关量输入 读输入点 0x02
内部为或开关量输入 读线圈 0x01
写单个线圈 0x05
写多个线圈 0x0F
16 位操作 模拟量输入 读输入寄存器 0x04
内部寄存器或输出寄 读多个寄存器 0x03
存器(模拟量输入) 写单个寄存器 0x06
写多个寄存器 0x10
读/写多个寄存器 0x17
屏蔽写寄存器 0x16
文件记录 读文件记录 0x14
写文件记录 0x15
分装接口 读设备标识 0x2B

输出寄存器,以常用的读输出寄存器为例说明
在一个远程设备中,使用该功能码读取输出寄存器连续块的内容。请求 PDU 说明了起始寄存
器地址和寄存器数量。从零开始寻址寄存器。因此,寻址寄存器 1-16 为 0-15。
将响应报文中的寄存器数据分成每个寄存器有两字节,在每个字节中直接地调整二进制内容。
对于每个寄存器,第一个字节包括高位字节,并且第二个字节包括低位字节。
【例 12.x】将寄存器 108 的内容表示为十进制数 555。寄存器 109 和 110 中的内容分别为十进
制 0 和 100。当要读取保持寄存器 108-110 中的内容时,Modbus 发送的请求报文和响应报文如下所
示。
请求报文如下:

响应报文如下:
12.4.5 电缆和接头

在 Modbus 的通信协议中,对通讯线缆及接头定义有了明确的定义。
1. Modbus 串口通讯线缆
Modbus 串口通信线缆必须使用屏蔽线,并且至少有一端必须要连接到地线,如果在两端使用
了连接器,那连接器必须与通信线缆的屏蔽层相通。
在实际应用中,为了减少接线的错误,基于 RS-485 的 Modbus 通信对通信线缆颜色有所推荐,
建议广大读者可以参考表 12-x 的规范接线。

表 12-X 基于 RS-485 的 Modbus 通信推荐线缆


信号名称 推荐的线缆颜色
D1-TXD1 黄色
D0-TXD0 棕色
公共地 灰色
4 线制(可选) RXD0 白色
4 线制(可选) RXD1 蓝色
当使用 RS-485 时,需确认最大的通讯距离要小于 1000 米,线缆的粗细需要使用 AWG24 的标
准。如果使用 5 类线用于 RS-485 Modbus 通信时,最大的距离为 600 米。
2. Modbus 串口通讯接头
1) 2 线-Modbus 接口定义
如果使用 RJ45(mini-Din 或者 D 型)作为 Modbus 的连接头,外壳选择带有屏蔽功能。以保证
通讯的抗干扰性能。
2 线 Modbus 连接器的输出引脚如图 12.x 所示。

图 12.x 中使用的 RJ-45 连接器


D 型 9 针口的示意图如图 12.x 所示。

图 12.x D 型 9 针口
若一台标准的 MODBUS 设备使用 RJ45 或 9 引脚 D 型连接器,对每种实际电路必须注意下述
输出引脚。

表 12-X RJ45 与 D 型 9 针口连接器输出引脚


RJ45 D 型连接器 级别要求 描述
3 3 可选 端口模式控制
4 5 必须 收发器端子 1
5 9 必须 收发器端子 0
7 2 推荐使用 正 5…24VDC 电源
8 1 必须 信号和电源公共地
2) 4 线-Modbus 接口定义
4 线 Modbus 连接器的输出引脚如图 12.x 所示,该图中使用的是 RJ-45 的通讯,在实际的应用
中,施耐德常采用此通讯接口。

图 12.x 4 线-Modbus 中使用的 RJ-45 连接器


D 型 9 针口的示意图如图 12.x 所示。

图 12.x D 型 9 针口
若一台标准的 MODBUS 设备使用 RJ45 或 9 引脚 D 型连接器,对每种实际电路必须注意下述
输出引脚。

表 12-X 4 线 RJ45 与 D 型 9 针口连接器输出引脚


RJ45 D 型连接器 级别要求 描述
1 8 必须 接受端子 0
2 4 必须 接受端子 1
3 3 可选 端口模式控制
4 5 必须 发送端子 1
5 9 必须 发送端子 0
7 2 推荐使用 正 5…24VDC 电源
8 1 必须 信号和电源公共地
3) RJ45 与 D 型 9 针口用于基于 RS-232 的 Modbus-RTU 的通信。
当使用 RS-232 的硬件接口,内部使用 Modbus-RTU 通讯协议时,必须遵循如下表 12-x 中的引
脚定义。

表 12-X RJ45 与 D 型 9 针口基于 RS-232 的 Modbus-RTU 的输出引脚


RJ45 D 型连接器 级别要求 描述
1 2 必须 发送段子
2 3 必须 接受端子
3 7 可选 发送清除
6 8 可选 发送请求
8 5 必须 信号和电源公共地
上表中的 D 型 9 针口都是基于公头而定义的。

3. 设备连接拓扑图
1) 一台设备的连接
当使用一台设备与从站设备进行 RS-232 的 Modbus-RTU 通讯时,主站块可以是 PLC 或计算机,
其结构图如图 12.x 所示。

计算机/PLC 从站设备

接收数据 SDA
接收数据 SDB
发送数据 RDA
发送数据 RDB
信号接地 SG

图 12.x 一台计算机/PLC 连接一个从站设备


2) 多台设备的连接
当使用多台设备进行连接时,最多可以接受 247 个从站,其结构如图 12.x 所示。

图 12.x 多台从站设备的连接

注意:
由于传送速度、距离而受到反射的影响。当反射影响到通讯时,需要安装终端电阻。终端电阻只与离计算
机/PLC 最远的设备连接。(终端电阻:120Ω)

4. Modbus TCP 线缆及接头


Modbus TCP 的通讯线缆及接头采用标准的以太网通讯标准,其介绍可参考本章节 12.2.5 中的
内容。
12.4.6 Modbus 串口的通讯组态

1. CoDeSys 侧 Modbus 串行主站配置


当使用通过 CoDeSys 来进行配置的 Modbus 串口主站 PLC 时,需要在 CoDeSys 中先对主站进
行配置,其次再对主站下第三方的从站进行相应的配置。
1) 添加 Modbus 串行通讯接口
首先,在 CoDeSys 中添加 Modbus 串行总线接口,如图 12.x 所示,根据名称分类,由于
CANopen 属于现场总线,在其中找到 3S 公司的“Modbus”,单击“插入设备”,完成 Modbus 总
线接口的添加。如主站为其他供应商所提供,则根据实际情况选择主站。

图 12.x Modbus 串行通信及接口


2) 配置 Modbus 串行通信接口
通过该属性可以配置 Modbus 串口配置,可以选择通信的 COM 端口、波特率、奇偶校验、数
据位及停止位。

图 12.x Modbus 串行通信配置界面


3) 添加串行主站/从站设备
根据上述步骤,添加完 Modbus 通信接口后,用户可以使用鼠标选中通讯接口右键选择“添加
设备”,系统会自动弹出窗口如图 12.x 所示,可以根据实际的需要添加主站和从站。

图 12.x 添加 Modbus 串行通信主/从站设备


4) 配置 CoDeSys 侧的 Modbus 串行主站设备
当完成步骤 3)后,需要设置 Modbus 串口设备的主站配置。Modbus 串行通信主站配置界面如
图 12.x 所示。

图 12.x Modbus 串行通信主站配置


传输模式:选择 RTU 或者 ASCII 码。
响应超时(ms):指主站等待从站响应的时间间隔。如果在这段时间中从站没有发出响应,主
站将会请求下一个从站。此时输入的值会认为是每个从站的缺省值。在 ⇘ 从站配置页面,可单独
为每个从站设置合适的时间间隔。
框架之间的时间(ms):指主站接收上一个响应数据帧到下一个请求数据帧之间等待的时间间
隔。这个参数可用于调节数据交换率。
至此,主站的配置结束,接下来,需要对主站连接的从站做相应的配置。
5) 主站下配置第三方的 Modbus 串行设备
在 CoDeSys 的设备树下,鼠标选中主站,右键选择“添加设备” ,选择添加 Modbus 串口设备
从站,Modbus 串行通信从站配置界面如图 12.x 所示。
图 12.x Modbus 串行通信从站设置
从站地址:设置从站的站地址,1~247 有效。
响应超时:设置从站的响应超时时间,如果超过该时间从站还没有相应主站,则主站认为该从
站有通讯故障。
6) 设置从站的通讯通道
如图 12.x 所示,在该设置选项中,用户可以自定义从站的 Modbus 通讯通道,但必须与实际的
从站硬件相匹配,按下“添加通道”后,系统会自动弹出对话框,用户可以直接选择访问功能码、
地址偏移、数据长度及通讯周期时间等。

图 12.x Modbus 串行从站通道设置


至此,针对在 CoDeSys 侧使用 Modbus 串行通讯设备的组态已经完成。
2. CoDeSys 侧 Modbus 串行从站配置
当使用通过 CoDeSys 来进行配置的 Modbus 串口从站 PLC 时,仅需配置 Modbus 串口设备配置
即可。
添加 Modbus 串行从站的步骤与上文所提及的主站步骤 1)~2)是相同的,不同的是在 3)需
要添加的是从站,从站添加后,鼠标双击即可打开其配置界面,如图 12.x 所示。
图 12.x Modbus 串行通信从站设置
Unit ID:串口地址。
Time Out:启动超时功能并指定一个用毫秒表示的超时时长;通常输入时间步长为 500ms。也
可输入 0,表示没有或无限大超时时长。
Holding Registers(%IW):保持寄存器的个数。
Input Registers(%QW):输入寄存器的个数。
完成上述步骤,Modbus 串行从站的配置步骤至此结束。

12.4.7 Modbus TCP 的通讯组态

1. CoDeSys 侧 Modbus TCP 主站配置


如使用 CoDeSys 所配置的 Modbus TCP 的主站需要首先对主站进行配置,此外,需要对从站的
配置也在主站的参数下也作相应的配置,具体步骤在下文会有详细的介绍。
1) 添加主站
添加 Modbus TCP 硬件设备,由于 Modbus TCP 基于以太网的通讯,故先添加硬件,鼠标右键
选择“添加设备”,弹出对话框后选择“以太网适配器-Ethernet”,如图 12.x 所示。

图 12.x 添加以太网适配器-Ethernet
添加完以太网适配器后,鼠标选择“插入设备”,弹出如图 12.x 的对话框后,选择“Modbus
TCP Master”。即完成了 Modbus TCP 主站设备的添加。
图 12.x 添加 Modbus TCP 主站
2) 配置 Modbus TCP 主站

图 12.x Modbus TCP 主站配置界面


响应超时:指主站等待从站响应的时间间隔。如果在这段时间中从站没有发出响应,主站将会
请求下一个从站。此时输入的值会认为是每个从站的缺省值。在从站配置页面,可单独为每个从站
设置合适的时间间隔。
Socket 超时时间:主站等待 TCP/IP 包到达的最大时间。在这段时间里,一个总线循环任务包
是可实现的(例如,用户断开一个 Modbus TCP 从站)。
至此,针对 Modbus TCP 主站的设置在设备管理器中的组态已经完成。
3) 主站配置下添加从站设备
添加 Modbus TCP 硬件设备,由于 Modbus TCP 基于以太网的通讯,故先添加硬件,鼠标右键
选择“添加设备”,弹出对话框后选择“以太网适配器-Ethernet”。
在上述步骤的基础上选中“以太网适配器-Ethernet”,鼠标点击右键,选择“添加设备”,在
弹出的提示框中选择“Modbus TCP”从站设备,如图 12.x 所示。
图 12.x Modbus TCP 从站设备
4) Modbus TCP 主站下从站的配置
在该选项中可以监控当前所连接从站的信息,包括 IP 地址、单元、响应超时时间及端口号信
息,如图 12.x 所示。

图 12.x Modbus TCP 从站基本信息


从站 IP 地址:从站的 IP 地址。
单元-ID[1..247]:从站的 ID 号。
响应超时时间:指主站等待从站响应的时间间隔。
端口:从站端口号码。
5) Modbus TCP 从站通道监视
可以查看 Modbus TCP 从站通道信息,如查看指令功能码、触发时间、地址偏移信息及数据长
度等,具体如图 12.x 所示。

图 12.x Modbus TCP 从站通道配置信息


6) Modbus TCP Slave 配置
在该配置窗口可以对从站 IP 地址、端口号、通道相应的功能码,数据区大小、触发时间及总
线出错后的数据处理等信息进行设置,如图 12.x 所示。

图 12.x Modbus TCP 从站通讯设置接口


7) Modbus TCP Slave I/O 映射
在此选项卡中可以设置通道对应的程序变量,选择“变量”中的“ ”进行程序中变量的映
射,如图 12.x 所示。

图 12.x Modbus TCP Slave I/O 映射表

2. CoDeSys 侧 Modbus TCP 从站配置


如使用第三方的 Modbus TCP 主站连接使用 CoDeSys 所配置的 Modbus TCP 的从站需要做如下
设置。
Modbus TCP Slave 其配置界面如图 12.x 所示,各参数的定义如下所示。
图 12.x Modbus TCP Slave 配置
超时:启动超时功能并指定一个用毫秒表示的超时时长;通常输入时间步长为 500ms。也可输
入 0,表示没有或无限大超时时长。
从站端口:从站端口号码。
ID 单元:从站的 ID 号。
输出区大小: 可输出的字节数,通常为 2-40(输出区包括要写入应用程序的网络输出)。
输入区大小:可输入的字节数,通常为 2-40(输入区包括从应用程序中读出的要输出到网络中
的数据)。
12.5 EtherCAT 网络基础
EtherCAT 是由德国自动控制公司 Beckhoff 开发的,并在 2003 年底成立了 ETG(Ethernet
TechnologyGroup)。ETG 是全球最大的工业以太网组织, 目前拥有超过 3000 个会员单位。

12.5.1 EtherCAT 拓扑结构及媒介

1. 网络拓扑结构
EtherCAT 支持总线型、树型、星型及混合结构(参见图 12.x)。通过现场总线而得名的总线
型或线型拓扑结构也可用于以太网,并且不受限于级联交换机或集线器的数量。

图 12.x EtherCAT 总线拓扑结构


最有效的系统连线方法是对线型、分支或树叉结构进行拓扑组合。因为所需接口在 I/O 模块等
很多设备中都已存在,所以无需附加交换机。当然,仍然可以使用传统的、基于以太网的星型拓扑
结构。
机械设备的结构而非总线系统决定其拓扑。因为无需交换机或集线器,网络结构没有限制。
EtherCAT 技术对此几乎没有限制,线型、树型、星型或菊花链型拓扑结构都可以实现。自动连接
检测使设备部件的热插拔成为可能。设备的连接或断开由总线管理器管理,也可以由从站设备自动
实现。若用一条线缆连接 EtherCAT 主站上另一个(标准的)以太网端口,就简单而经济地实现了
网络冗余。
综上所述,EtherCAT 拥有多种机制,支持主站到从站、从站到从站以及主站到主站之间的通
讯,如图 12.x 所示。
图 12.x 垂直网络拓扑结构

2. 电缆和接头
1) 标准双绞线电缆 100BASE -TX,是一种费用低廉的。允许两个设备之间的最大电缆长度达到
100 米,由于一个 EtherCAT 网络可连接多达 65535 个设备,因此,网络的容量几乎没有限制。
线缆有屏蔽和非屏蔽两种。
2) 光缆 100BASE-FX,最长距离 2000m,每个网段两个节点,适合长距离的要求,或是用于电子
噪声较大的场所。

从站
主站

100BASE –TX 双绞
线电缆
100BASE-FX 光 纤
线电缆

图 12.x EtherCAT 物理接口

12.5.2 EtherCAT 运行原理

1. 协议介绍
EtherCAT 技术突破了其他以太网解决方案固有的局限性:一方面,无需像其它方案那样接收
以太网数据包,将其解码,之后再将过程数据复制到各个设备。EtherCAT 从站设备在报文经过其
节点时读取带有相应寻址信息的数据;同样,输入数据也是在报文经过时插入至报文中,参照图
12.x 所示。整个过程中,报文只有几纳秒的时间延迟。

图 12.x 过程数据插入在报文中
由主站发出的帧被传输并经过所有从站,直到网段(或分支)的最后一个从站。当最后一个设
备检测到其开放端口时,便将帧返回给主站。
另一方面,由于发送和接收的以太网帧压缩了大量的设备数据,所以可用数据率可达 90%以上。
100 Mb/s TX 的全双工特性完全得以利用,因此,有效数据率可以达到 > 100 Mb/s (> 2 x 100 Mb/s
的 90%)。
EtherCAT 主站采用标准的以太网介质存取控制器(MAC),而无需额外的通讯处理器。因此,
任何集成了以太网接口的设备控制器都可以实现 EtherCAT 主站,而与操作系统或应用环境无关。
EtherCAT 从站采用 EtherCAT 从站控制器(EtherCAT Slave Controller, ESC)来高速动态地(on-
the-fly)处理数据。网络的性能并不取决于从站使用的微处理器性能,因为所有的通讯都是在 ESC
硬件中完成的。过程数据接口(Process Data Interface, PDI)为从站应用层提供了一个双口随机存储
器(Dual-Port-RAM, DPRAM)来实现数据交换。
精确同步在广泛要求同时动作的分布过程中显得尤为重要,如几个伺服轴在执行同时联动任务
时。分布时钟的精确校准是同步的最有效解决方案。在通讯系统中,和完全同步通讯相比,分步式
校准时钟在某种程度上具备错误延迟的容错性。
2. 分布时钟
精确同步对于同时动作的分布式过程而言尤为重要。例如,几个伺服轴同时执行协调运动时,
便是如此。
最有效的同步方法是精确排列分布时钟(可参阅 IEEE 1588 标准)。与完全同步通讯中容易出
现通讯故障,立即影响同步品质的情况相比,分布排列的时钟对于通讯系统中可能存在的相关故障
延迟具有极好的容错性。
采用 EtherCAT,数据交换就完全基于纯硬件机制。由于通讯采用了逻辑环结构 (借助于全双工
快速以太网的物理层),主站时钟可以简单、精确地确定各个从站时钟传播的延迟偏移,反之亦然。
分布时钟均基于该值进行调整,这意味着可以在网络范围内使用非常精确的、小于 1 微秒的、确定
性的同步误差时间基。其结构图如图 12.x 所示。
图 12.x 同步时钟原理
比如两设备之间相差 300 个节点,线缆的长度为 120 米,使用示波器抓取其通信信号,其结果
如图 12.x 所示。

图 12.x 同步时钟性能测试
这对于运动控制是非常重要的,它通过连续检测到的位置值计算出速度,当采样时间非常短时,
即使是位置测量出现一个很小的瞬时抖动,也会导致速度计算出现较大的阶跃变化。通过使用分布
时钟,采样不是基于通信抖动,因此速度测量非常精确。比那些基于无抖动通信的测量技术有更高
数量级的精度。此外,高分辨率的分布时钟不仅可以用于同步,还可以为数据采集提供精确的本地
时间信息。在 EtherCAT 中,引入时间戳数据类型作为一个逻辑延伸,可以为测量值附加高分辨率
的系统时间,而以太网所提供的巨大带宽使这成为可能。此功能不仅用于任何测量应用,也用于独
立于控制周期的精确反应时间。而跨工厂等外部同步则可以基于 IEEE 1588 标准。
3. 基于 EtherCAT 的 CAN 应用协议(CoE)
CANopen 设备和应用行规广泛用于多种设备类别和应用,如 I/O 组件、驱动、编码器、比例阀、
液压控制器,以及用于塑料或纺织行业的应用行规等。EtherCAT 可以提供与 CANopen 机制相同的
通讯机制,包括对象字典、PDO(过程数据对象)、SDO(服务数据对象),甚至相似的网络管理。
因此,在已经实施了 CANopen 的设备中,仅需稍加变动即可轻松实现 EtherCAT,绝大部分的
CANopen 固件都得以重复利用。并且,可以选择性地扩展对象,以便利用 EtherCAT 所提供的巨大
带宽资源。
4. IEC 61800-7-204 的伺服驱动行规(SERCOS)
SERCOS 被公认为用于高性能实时系统的通讯接口,尤其适用于运动控制的应用场合。用于伺
服驱动和通讯技术的 SERCOS 行规属于 IEC61800-7-204 标准的范畴。该伺服驱动行规到 EtherCAT
的映 射 ( SoE )在 304 部分定 义。用于访问 位于驱动 中的全部参数 以及功能 的服务通道基于
EtherCAT 邮箱。在此,关注焦点还是 EtherCAT 与现有协议的兼容性(访问 IDN 的数值、属性、
名称、单位等),以及与数据长度限制相关的扩展性。过程数据,即格式为 AT 和 MDT 的
SERCOS 数据,都使用 EtherCAT 设备协议机制进行传送,其映射与 SERCOS 映射相似。并且,
EtherCAT 从站的状态机也可以非常容易地映射为 SERCOS 协议状态。
5. EtherCAT 实现以太网 ( EoE )
EtherCAT 技术不仅兼容以太网,而且在“设计”之初就具备良好的开放性特征——该协议可
以在相同的物理层网络中包容其它基于以太网的服务和协议,通常可将其性能损失降到最小。可将
任何类型的以太网设备通过交换机端口联入 EtherCAT 网段。
以太网帧通过 EtherCAT 协议中开通的隧道传输,这也正是 VPN、 PPPoE ( DSL ) 等因特网应
用所普遍采取的方法。EtherCAT 网络对以太网设备完全透明,其实时特性也不会发生畸变,如图
12.x 所示。

图 12.x EtherCAT 实现以太网


EtherCAT 主站的作用与第 2 层交换机所起的作用一样,可按照编址信息将以太网帧重新定向
到相应的设备。因此,诸如集成的网络服务器、电子邮件和 FTP 传送等所有的因特网技术都可以
在 EtherCAT 的环境中得以应用。
6. EtherCAT 线缆冗余
EtherCAT 可选用电缆冗余可以满足快速增长的系统可靠性需求,它可以保证无需关闭网络即
可进行设备更换。增加冗余特性耗费不高,仅需在主站设备端增加一个标准的以太网端口(无需专
用网卡或接口)和一根电缆,这将线型拓扑结构转变为环型拓扑结构。当设备或电缆发生故障时,
也仅需一个周期即可完成切换。因此,即使是针对运动控制要求的应用,电缆出现故障时也不会有
任何问题。
EtherCAT 使用热备份功能支持主站冗余。一旦出现中断、设备故障等问题,EtherCAT 从站控
制器可以立即自动返回以太网帧,所以不会导致整个网络关闭。例如例如,标准 EtherCAT 拓扑结
构如图 12.x 的 a)所示,如果在该拓扑结构中 Slave2 与 SlaveN-2 之间出现了网络中断现象,如图
中的红色部分,则 Slave N-2 后的所有从站通讯也会相应中断。这也是标准拓扑结构的缺点。

a) b)

图 12.X EtherCAT 冗余
a ) 标准 EtherCAT 拓扑结构 b ) EtherCAT 冗余拓扑结构
图 12.x 的 b)为 EtherCAT 冗余模式的拓扑结构,主站只需要有两个标准网口即可实现该拓扑
结构,使用这两个网口将所有从站构成一条环路,即使在使用过程中网络出现中断,如图 12.x 中
红色的断开部分,主站马上会检测到错误,自动将通讯分为两路,所有的从站还能继续通讯,以保
障系统的稳定运行。

12.5.3 EtherCAT 硬件设定

1. 主站实现
EtherCAT 的单个以太网帧最多传输 1486 字节的分布式过程数
据。EtherCAT 在每周期仅需要一个或两个帧即可完成与所有节点的
全部通讯,因此,EtherCAT 主站不需要专用的通讯处理器。主站功
能几乎不会给主机 CPU 带来任何负担,轻松处理这些任务的同时,
还可以处理应用程序。
EtherCAT 无需使用昂贵的专用有源插接卡,只需使用标准以太
网卡或主板集成的以太网 MAC 即可,如图 12.x 所示。EtherCAT 主
站实施很容易实现,尤其适用于中小规模的控制系统和明确定制的
图 12.x 标准以太网卡即可实现
应用场合。
2. 从站结构
EtherCAT 从站设备中使用成本低廉的 EtherCAT 从站控制器(ESC)。对 EtherCAT 通讯本身
而言,无需微处理器。只需要 I/O 接口的简单设备可以只用 ESC、PHY、电磁隔离和 RJ45 接头实
现。
从站应用层与过程数据接口(PDI)通过一个 32 位的 I/O 接口连接。该从站没有配置参数,因
此无需软件或邮箱协议。EtherCAT 状态机在 ESC 中处理。ESC 的启动信息从 EEPROM 中读入,
EEPROM 也支持从站的识别信息。对于配置了主 CPU 的更复杂的从站设备,CPU 通过一个 8 位或
16 位的并行接口或通过一个串行接口(SPI)连接到 ESC。主 CPU 的性能取决于从站的应用——
EtherCAT 协议软件自行独立运行。EtherCAT 协议栈管理 EtherCAT 状态机和通讯协议,通讯协议
通常意味着 CoE 协议和支持固件下载的 FoE。可有选择地实施 EoE,其结构如图 12.x 所示。
图 12.x EtherCAT 从站内部结构

12.5.4 EtherCAT 网络设计

EtherCAT 网络通常由一台主机最多带有 65535 台从站组成。其中,主机单独管理从机,如果


采用线路冗余的话,就会用到 2 个主站。
1) 电气设备间的通信可以完成如下:
 基于以太网点对点通信(这里会涉及) – 电缆连接;
 基于差分低压信号(LVDS)– ‘E-bus’ – 用于可堆叠模块化设备;不需要电缆连接。
2) 设计 EtherCAT 网络时,以下因素会决定周期(s)大小:
 设备的最大数量(如最大 65535) ;
 设备间允许的以太网电缆最大长度 (见下方)。由电缆长度产生的传播延迟是并不太长,不
用着重考虑;100m 长的以太网电缆大约产生 550ns 的时延;
 所有主机到从机的来回线路构成了以太网的周期。设备间通信可看做一下两种量级:- 采
用以太网设备:约 1 µs- 采用 E-bus:约 300 ns;
 以太网报文的总长与设备的数量有关。
集线器和交换机会推延周期时间(ISO Layer 2 注:即 Data Like Layer),并分散在整个
EtherCAT 网络中;不能有由路由器(ISO Layer 3 注:即 Network Layer )。
3) 电缆设计:
以太网电缆是在两个智能终端设备间以点对点通信方式传输信息的连接器。快速以太网
/100Mbit 一般工作在全双工模式,因此两方可在不同的电缆线上同时进行传送和接收操作。而对于
拓扑,EtherCAT 在工业环境中的布线和在办公室中是有所不同的。不过,为了提高以太网工作的
可靠性,一般会减少以太网终端间的跳线盘和连接点数量,但会降低布线的灵活性。
与工作状态相关的临界条件为:
 环境/工作温度 ;
 端点间的插口连接(单/双)数量 ;
 所用电缆类型(刚/软芯或者它们的电特性;可参考数据表);
 电缆模块外部干扰(电磁场,平行线缆,环形/拖链型安装,化学性干扰等);
 对于使用 100Base-TX 介质标准的以太网,最大总链路长度为 100m;注:根据所用电缆材
料,可用的链路长度可能低于额值或者甚至高于额值—但实际延时可能更长;
 下文提出的设计方法都是参考了 EN50173-1 和 3 标准,可用于工业部门;
 电缆模块安装后需要测试;所有测试方法均在 EN50346:2001 标准中。
12.5.5 主从站通讯配置示例

首先先配置 EtherCAT 主站,随后通过在主站卡菜单下添加从站从而完成配置。


1. 主站配置
1) 添加主站
首先在设备下添加 EtherCAT 主站,点击设备,右键选择“添加设备”,当弹出添加设备窗口
后,选择“EtherCAT” --> “主站”-->“EtherCAT Master”单击“添加设备”,如图 12.x 的 a)
和 b)所示。

a) b)

图 12.x 添加 EtherCAT 主站设备


a)添加设备 b)选择 EtherCAT Master
2) EtherCAT 主站配置
主站添加后,可以通过点击选中主站从而对其进行配置。图 12.x 为 EtherCAT“主站”选项卡
中的设置,用于配置主站、分布式时钟、冗余及从站相应设置。

图 12.x EtherCAT 主站设置选项卡


a) EtherCAT NIC 设置
目的地址(MAC):为接受 EtherCAT 报文的目标地址,如果“广播”选项被激活,则不需要
输入目标地址,系统会自动进行通过广播搜索目标地址。
激活冗余:该选项使能后,则正式开启 EtherCAT 冗余模式,其支持环形拓扑结构。
源地址(MAC):PLC 网络接口的的 MAC 地址,可以选择“根据 MAC 选择网络”或者选择
“根据名称选择网络”。用户可以选择“浏览”鼠标选择想要设置的源地址。
b) 分布式时钟:
周期时间:如果分布式时钟功能被激活,主站发送将会根据该循环时间向从站发送相应数据报
文。因此数据交换可以实现精确同步,在分布式过程中要求同步动作时(例如几个伺服轴执行同时
联动任务),此功能尤为重要的。可以在网络范围内提供信号抖动小于 1 微秒的主时钟。
同步偏移:通常当 PLC 任务开始 20%后,同步报文开始影响从站,这就意味着 PLC 的任务周
期可以有 80%的延迟,在此延迟内不会有数据会丢失。
同步窗口监控:如果该选项打开,可以监控从站的同步状态。
同步窗口:用于监控同步窗口的时间。如果所有的从站在同步窗口时间内,则变量
xSyncInWindow (IoDrvEthercat)将会被置为 TRUE,否则为 FALSE。
c) 选项
使用 LRW 代替 LWR/LRD:激活此项会使能从设备-从设备的通信。组合读写命令(LRW)会
替代单独的读(LR)和写命令(LRW)。
在每个任务中激活消息:激活此项,处理输入输出信息的读写命令可以由不同任务完成。
自动重启从站:激活此项,主机会在通信终止后立即尝试重启从站。
3) EtherCAT I/O 映射
由 EtherCAT 主站提供的 I/O 映射表,PLC 中的变量可以连接其中的 I/O,为用户提供可控制的
接口。

图 12.x EtherCAT I/O 映射


4) 状态
如图 12.x 所示,提供显示状态信息(如“运行”,“停止”)和详细设备诊断信息

图 12.x EtherCAT 状态监控

2. 从站配置
1) 安装 EtherCAT 从站设备描述文件
为了在设备目录中插入和配置 EtherCAT 设备,主站和从站必须使用硬件提供的设备描述文件,
通过“设备库”对话框安装(标准的
CoDeSys 设置自动地完成)。主站的设备描
述文件(*.devdesc.xml)定义了可以插入的从
站。从站的描述为“xml”文件格式(文件
类型:EtherCAT XML 设备描述配置文件)。
在“工具”菜单栏中“设备库”-->“安
装”选择“EtherCAT XML 设备描述配置文
件(*.xml)”,找到该文件路径,选择“打开”
进行安装。

图 12.x EtherCAT XML 文件安装


2) 添加从站设备
a) b)

图 12.x 添加 EtherCAT 从站设备


a)插入 EtherCAT 从站设备 b)选择 EtherCAT Slave
选择“插入设备”系统会自动弹出从站设备添加框,用户可以根据实际连接的从站进行添加,
如图 12.x 所示。此外,用户也可以通过选中主站选项卡,右击鼠标,选择“扫描设备”进行实际
从站自动扫描搜索。
注意:
使用“扫描设备”功能之前,必须确保从站的 EtherCAT 设备描述文件已经安装在调试 PC 的 CoDeSys
内,否则无法使用此功能。
3) 从站配置

图 6.x 从站信息
a) 地址
自动配置地址:由从站在网络中的位置确定。这个地址仅仅在启动时使用,主站需要向从站分
配 EtherCAT 地址。当用于此目的的首个报文通过从站时,每一个经过的从站将自身的自动增量地
址加 1。
EtherCAT 地址:从站的最终地址,由主站在启动时分配。
b) 分布式时钟
选择 DC:下拉菜单提供了由设备描述文件提供的所有关于分布时钟的设置,可以选择同步会
不同步。

c) 同步 0/1:
同步 0/1 使能:如果该选项被选中,使用 " sync0/1 "同步单元。一个同步单元描述了一套同步
交换的过程数据。
同步单元循环:主站周期的时间乘以所选择的系数,将被用作从站的同步周期时间。循环时间
(μs )栏显示当前设置的周期时间。
d) 站别名:
此设置只有被设备描述显式支持才能被激活。允许直接命令地址别名以获取与总线中位置无关
的从设备地址。
e) 附加
使能专家设置:当用户使能该选项后,能够修改更多 EtherCAT 从站的内部数据。
可选的:如果定义了该选项,如果总线中该节点不存在,则不会发送任何错误代码。激活该选
项后,站号地址被存储在了从站设备中,故必须定义“站别名”和地址并将其写入 EEPROM 中。
4) 过程数据
显示了设备描述文件所描述的从站输入和输出过程数据,如图 12.x 所示。

图 12.x 过程数据
5) 启动参数

图 12.x 启动参数
如果有错,则退出/跳行:如果检测到有错误,则会根据指定的选项退出或跳行,如选择跳行
则会根据用户所设置的参数“下一行”进行跳转。
当设置如 12.x 中所示时,如当执行第 3 行时出现错误,则进入“下一行”所设置的行数,即自
动进入第 5 行。
图 12.x 启动参数应用举例
当用户选择新建或编辑时,会自动弹出 12.x 中所示的对话框,用户可以选择新建或编辑对参
数进行修改。

图 12.x 新建/编辑子索引
用户可以在红色编辑区域进行修改。
6) EtherCAT I/O 映射

图 12.x EtherCAT I/O 映射


在该选项卡中,可以查看 CANopen I/O 映射关系、功能描述、实际地址以及映射变量的类型。
7) 状态

该选项卡给用户提供设备状态(如“Running”,“Stop”)以及设备的诊断信息。
12.6 PROFINET 网络基础
PROFINET 是在 SIEMENS 公司的支持下由 PNO(Profibus Nutzer/User Organisation)开发而成
的,用于实现基于工业以太网的集成、一致的自动化解决方案。PROFINET 支持用以太网通信的简
单分散式现场设备和苛求时间的应用的集成,以及基于组件的分布式自动化系统的集成。

12.6.1 PROFINET 拓扑结构及媒介

1. 网络拓扑结构
PROFINET 网络支持总线型、星型的拓扑结构,其结构如图 12.x 所示。

图 12.x PROFINET 总线型拓扑结构


此外,通过添加交换机能使其能够支持星型的拓扑结构,此外 PROFINET 还支持树型和混合
型的总线拓扑结构,如图 12.x 所示。

图 12.x PROFINET 星型拓扑结构


PROFINET 的系统结构如图 12.x 所示。可以看到,PROFINET 的技术的核心设备是网关代理设
备。代理设备负责将所有的 PROFINET 网段、以太网设备、甚至其他总线设备集成到 PROFINET
系统中。
图 12.x PROFINET 系统结构
在应用中,尤其是存在大型且复杂的 PROFINET 网络拓扑结构时,很难知道 IO 设备之间的连
接关系,从而造成维护和诊断的不便。
2. 电缆和接头
1) 线缆
通过双绞线的信号传输是在传输速率为 100Mbps(快速以太网)依照 100BASE-TX 协议执行
的。定义 2 根屏蔽双绞线铜缆(STP = 屏蔽双绞线对)作为传输介质。
所有这些设备都通过一个活动网络组件连接。PROFINET 使用可切换的网络组件。网络组件的
规范保证了简单安装。在传输电缆的两端装有相同的连接器,对其也可以按相同的规定进行预安装。
最大分段的长度为 100 米。
2) 接头
工业中使用的主要标准是本地处理的连接系统,M12 和 RJ45 的插头连接器可用于此目的。使
用标准工具,这些连接器的就地装配是很容易的。
在开关柜内 PROFINET 使用 IP20 保护等级的 RJ45。它与办公室用连接器兼容。开关柜外部的
插头连接器必须考虑工业的特殊要求。
IP65/IP67 保护等级的 RJ45 型或 M12 型用于条件恶劣的场所,它带有推挽式锁定。如图 12.x
所示。

图 12.X 插头连接件
用于 PROFINET 的 RJ45 插头连接器在 IEC 61076-3-106 的草案中规定为 4 极和 5 极。用于
PROFINET 的 M12 插头连接器连接器在 IEC 61076-2-101 的草案中规定为屏蔽的 D 编码型。

图 12.X 插头连接件
混合插头连接器用于以下场合:分布式现场模块是通过带有数据和供电电压的组合连接器进行
连接。带有 IP67 的 RJ45 有一个用于通信的 2 对屏蔽的数据线和用于供电的 4 根铜导线。一个完全
防电击的插头连接器允许双向使用同样的插头连接器。因为有整体的保护,不再需要针状插座的转
换。

12.6.2 PROFINET 运行原理

如图 12.x 所示,PROFINET 提出了两类工业以太网的通信机制,PROFINET CBA 采用 TCP/IP


协议通道来实现非实时数据的传输,比如用于设备参数化、组态和读取诊断数据的传输。而实时数
据的传输是将 OSI 模型的第三层和第四层进行旁路,实现实时数据通道,传输的实时数据存放在
RT 堆栈上,实现传输时间的确定性。为了减少通信堆栈的访问时间,PROFINET IRT 对协议中传
输数据的长度作了限制。因此在实时通道上传输的数据主要是用于现场 I/O 数据、事件控制的信号
与报警信号等。为优化通信功能,PROFINET 根据 IEEE 802.1p 定义了报文的优先权,规定了 7 级
的优先级。其中最高级用于硬实时数据的传输。

图 12.x PROFINET 种类
1. TCP/IP 标准通讯(NRT)
PROFINET 使用以太网和 TCP/UDP/IP 协议作为通信基础。就 TCP/UDP/IP 而论,TCP/UDP/IP
是 IT 领域在通信协议方面的事实上的标准。但是,对于不同应用的互操作性,它还不足以在现场
设备上建立一个基于 TCP/UDP 的公共通信通道(Layer 4)。事实是,TCP/UDP/IP 只提供了使以
太网设备能够通过本地和分布式网络的透明通道中进行数据交换的基础。因此,在较高层上则需要
其它的规范和协议(亦称为应用层协议),而不是 TCP/UDP。那么,只有对于所有设备都使用相
同的应用层协议时,才能保证互操作性。典型的应用层协议有:例如 SMTP(用于电子邮件),
FTP(用于文件传输)和 HTTP(用于互联网)。
在工厂自动化领域,实时应用需要刷新/响应时间范围在 5~10ms 内。刷新时间是指以下过程所
经历的时间:在一台设备应用程序中创建一个变量,然后通过通信系统将该变量发送给一个伙伴设
备,其后可在此伙伴设备中再次获得该变量。
为了确保优先连续处理应用程序,应尽量使设备处理器用于实现实时通信的负载减少到最小。
经验指出,与设备中的处理时间相比,快速(100Mbps)或更高速率的以太网线路上的传输时
间是可以忽略不计的。在提供者的应用中可提供数据的时间是不受通信影响的。这也适用于消费者
中所接收的数据的处理。这就是说,在刷新时间以及实时响应中任何重大的改进主要可通过提供者
和消费者通信栈的优化来达成。
2. 实时通讯(RT)
为了能满足自动化中的实时要求,PROFINET 有一个优化的实时通道— 软件实时(RT)通道。
此通道基于以太网(Layer 2),其结构如图 12.x 所示。此解决方案显著地减少了通信栈所占
用的运行时间,从而提高了过程数据刷新速率方面的性能。一方面,若干个协议层的去除减少了报
文长度;另一方面,在需要传输的数据准备就绪发送(即:应用准备就绪处理)之前,只需较少的
时间。同时,可大量地减少设备用于通信所需的处理器能力。
3. 通过优先级优化数据传输
在 PROFINET 中,不仅最小化了可编程控制器中的通信栈,而且也对网络中数据的传输进行
了优化。为了能在这些情况下达到一种最佳结果,在 PROFINET 中按照 IEEE 802.1Q 将这些数据包
区分优先级。设备之间的数据流则由网络组件依据此优先级进行处理。优先级 6(Priority 6)是用
于实时数据的标准优先级。由此也就确保了对其它应用的优先级处理,例如:优先级 5 是互联网电
话。

图 12.x PROFINET RT 结构图

4. 同步实时通讯(IRT)
然而,上述解决方案对于运动控制应用还远远不够。运动控制应用要求刷新速率在 1ms,100
节点的连续循环的抖动精度为 1μm。为了满足这些需求,PROFINET 在快速以太网的 Layer 2 协议
上已定义了时间间隔控制的传输方法 IRT。
图 12.x PROFINET IRT 的通信时间表
通过具备上述精度的参与设备(网络组件和 PROFINET 设备)的时间同步化,可在网络中规
定时间槽,在此时间间隔内传输自动化任务所必需的关键数据。通信循环被分成两个部分,即:时
间确定性部分和开放性部分。循环的实时报文在时间确定性通道中传输,而 TCP/IP 报文则在开放
性通道中传输。这种处理方法可与高速公路媲美,最左边的车道总是为时间要求最紧迫的车辆(实
时通信)而保留的,由此防止其它车道上的用户(TCP/IP 通信)占用此车道。甚至在右边车道交
通拥塞的情况下也绝不能影响时间要求紧迫(苛求时间)的车辆的交通(通信)。
等时同步数据传输的实现基于硬件。具备此功能的 ASIC 包括用于实时数据的循环同步和时间
间隔保留功能。基于硬件的实现能够获得所要求的异常重要的顺序精度要求,同时也解放了承担
PROFINET 设备通信任务的处理器。这就免除了烦琐的计算,从而可为自动化任务提供解决方案。
PROFINET IRT 的优点:
IRT 网络采用集成电路的 ERTEC(增强了实时以太网控制器)以太网控制器实施的 IRT 传输
方法,允许更新时间为 250us 和发送始终的抖动精度小于 1us 来实现。
 高精度确定性,甚至标准的通讯具有相同的网络负载。
 简单,灵活的继承现有公司网络 PROFINET 实时应用的设备。
 预留的传输带宽,因此可以充分的进行数据传输的实时控制。
 并行与实时通信的标准的通信使用相同的传输介质。
 继续在 PROFINET IO 系统的同步域意外使用标准组件。

图 12.x PROFINET 网络延时


12.6.3 PROFINET 协议架构

PROFINET 的数据交换基于提供者/消费者模型实现。提供者/消费者模型包括三种实体:信息
的提供者和消费者,以及提供者和消费者建立联系的消息代理。它通过拉(Pull)和推(Push)两
种模型实现。在拉模型中,提供者从应用管理层接收一个发布请求,并通过网络组播它的响应,需
要数据的消费者给予响应,由管理器从提供者“拉”出数据供消费者使用。模型提供了两种服务:
证实服务和非证实服务。证实服务仅用于提供者和消费者位于不同的应用进程 AP( Application
Process) 时,消费者按照客户机/服务器模式使用证实服务请求加入发布,提供者给予响应并返还给
消费者。非证实服务中提供者仅负责在合适的时间将其信息分发给消费者,消费者无需对信息进行
确认。
PROFINET 基于无证实服务的提供者/消费者模型的推模式。控制器和 IO 设备既可以作为提供
者,也可作为消费者。提供者以固定时间间隔Δt1 将数据传送给消费者,消费者以固定时间Δt2 接
收。传输期间数据未经任何保护,也不需消费者确认。其模型如图 12.x 所示。

图 12.x PROFINET 消费者/提供者模型


传统的以太网使用 CSMA /CD (带有冲突监测的载波监听多路访问) 协议实现介质访问控制,虽
然工业以太网可使用标准的通信协议(如 TCP / IP 或 UDP / IP)来提高其实时性,但数据包的传输时
延很大程度上依赖网络负载而不能预先确定,因此标准协议通信过程中会产生帧过载现象,这即加
大传输时延及处理器计算时间, 从而延长发送周期,严重影响网络的实时性。为此, PROFINET 通过
对发送器和接收器的通信栈进行实时性优化,可保证同一网络中不同站点可在一个确定时段内完成
时间要求严苛的数据传输。PROFINET 通过软实时和硬实时方案对 ISO /OS I 参考模型的第 2 层进
行了优化, 此层内所改进的实时协议对数据包的寻址不是通过 IP 地址实现的, 而使用接收设备的
MAC 地址, 同时保证与其他标准协议在同一网络中的兼容性。PROFINET 的协议架构如图 12.x 所示。

图 12.x PROFINET 通信协议框架

1. 协议简介
PROFINET 为减小交换机在帧处理时的最大周期偏差,使用 VLAN 标签对帧进行优先级标识,
从而控制运行时间内设备之间的数据流。PROFINET 实时帧使用优先级 6 或 7 发送。遵照 IEEE
802.1Q,VLAN 标签对以太网帧扩展了 4Byte 。Ether type 0x8100 确定 VLAN 标签协议标识符。
VLAN 帧格式在 IEEE 802.1D 中定义。IEEE 分配以太网协议 0x8892 对实时帧进行标识。帧类型标
识符用于描述两个设备之间的通信信道。以太网与帧类型标识符的结合即可对实时帧进行识别,实
时帧结构如图 12.x 所示。

图 12.x PROFINET 以太网数据帧


其中,RT 数据区内的用法与结构没有具体定义,但若实时帧长度<4 Byte,则实时数据的长度
必须扩展到最小 40Byte。VLAN TPID 区的 CFI 用于区别以太网和令牌环网的类型。对于接收器,
控制器首先验证 6Byte 的目的地址,随后在 Profinet 协议栈中用以太网类型和帧类型标识符将帧分
配到相应信道。
2. 通信的建立
PROFINET 使用发送器/接收器通信方式进行数据传输。PROFINET 设备可同时作为接收器和
发送器进行工作。在周期性实时数据的通信中,数据交换是基于连接的,连接的建立及删除由应用
层协议控制;数据的接收器不会对数据包的接收状态向发送器进行明确回复,而仅通过监控时间间
隔来考察数据接收情况。此外,PROFINET 实时协议不支持数据的分段及重组,以及长度超出以太
网标准数据包长度(包含所有协议首部)的传输。
当 PROFINET 发起者收到要建立的连接方面的信息时,这些信息可能来自于工程设计系统,
也可能来自于保存的组态数据,它利用这些数据自动尝试与响应者建立连接。在成功建立连接之后,
发送器向接收器传输实时的生产数据或 I/O 数据。与此相反,发起者也可提供删除连接的触发,如
上位操作终端或设计系统删除连接。此外,发起者可以将发送器和接收器组合在同一个设备中,其
回路的监控是通过实时协议的数据安全特性、发送器和接收器的高层协议和特殊的监控机制来实现
的。PROFINET 建立与删除连接的过程如图 12.x 所示。

图 12.x PROFINET 连接建立与删除

3. 设备描述文件 GSD
在 RPOFIBUS 中,设备描述文件 GSD(General Station Description)把 PROFINET 设备集成到
一个 IO 控制器的组态工具中。PROFINET 的 GSD 文件基于 XML。IO 设备的属性以 GSD 文件的
形式描述,该文件包括如下的信息:
 IO 设备属性(如通信参数)。
 可嵌入的模块(类型数)。
 独立模块的组态数据。
 模块参数。
 记录诊断错误的文本(如断线、短路),XML 是 PROFINET IO 设备 GSD 文件的描述基
础。
因为 XML 是一个开放的、应用普遍并且已被接受的用于描述数据的标准,所以有以下可用的
标准工具和属性:
 通过一个标准工具生成和确认。
 外部语言的集成。
 分层的结构。
GSD 文件的结构符合 ISO 15745 规范,由报头、应用层的设备描述(如组态数据和模块参数)
和传输层的通信属性描述组成。
4. 等时同步机制
PROFINET 的 IRT 协议主要为运动控制等硬实时系统提供解决方案。它通过使用时分多路复用
协议及特殊通信 ASIC (专用集成电路),确保在网络过载或网络拓扑动态变化时的通信质量。此外,
IRT 需要确定的网络组态,即通信前应规划网络拓扑、源/目的节点、通信数据量、连接路径属性等。
IRT 的一个传输周期主要由 IRT 通道和开放通道进行分配,硬件 ASIC 会对 IRT 周期定时进行监视。
IRT 通道用于传输等时同步的周期性实时帧,开放通道用于传输非同步实时帧和非实时帧( NRT
frame)。IRT 周期组成及分配如图 12.x 所示。

图 12.x PROFINET 周期
PROFINET 在实现网络同步时使用精确透明时钟协议( Precision Transparent Clock Protoco,
PTCP) 来记录传输链路时间参数。PTCP 位于 OSI 参考模型的第 2 层,不具路由功能,但具有显著
优点,如同步精度高、消耗资源少、带宽使用少、管理要求低,并对网络组件的 CPU 性能和存储
器性能无特殊要求。PTCP 主端用一个多播帧触发同步,其帧结构如图 12.x 所示。此帧的接收器通
过接收到的同步信息调整自身的时钟。调整时不能破坏相应设备的本地时间记录。

图 12.x PTCP 帧结构


PROFINET 将同一个时钟进行同步的子网内所有通信参与者定义为一个 PTCP 子域。PTCP 子
域内可实现 PTCP 主端和 PTCP 从端之间微秒级或亚微秒级时间同步。PTCP 同步是通过周期性地
交换两个网络节点间的同步帧序列来实现的,其中具有最高精确度时钟(主时钟)的网络节点用于
同步其它节点的本地时钟(从时钟)。同一序列的所有帧具有相同的序列号。同步过程包含时延测
量和子域内同步两个阶段。
同步过程的第一个阶段是测量相互通信双方(时延请求者与时延响应者)之间的时延,即时延
测量阶段,其在同步过程中的主要任务是测量通信双方之间的时延。通常情况下,该时延由 3 部分
组成,即请求者本地时延、应答者本地时延及帧传输时延。首先,时延请求者向时延响应者发送一
个时延请求(时延帧),该帧的精确传输时间由时延请求者确定并记录。之后, 时延响应者在收到
的数据包上添加一个时间戳, 并将接收时间通过一个时延响应(应答帧)回复给时延请求者,并通
过发送一个跟随响应(跟随帧),将本地时延通报给时延请求者。在数据传输期间,线路上对称的
时延对测量的准确性具有决定性意义。
子域内同步阶段,PTCP 子网内的时间同步是通过在 PTCP 主端发送一个同步帧实现的。此过
程会指定 PTCP 的主时钟值,以及发送者与接收者之间链路时延。PTCP 从端将利用同步帧和跟随
帧中信息,同步其本地时钟(PTCP 从时钟)。在 PROFINET 中,将收到同步帧和跟随帧发送出去
的网络节点称为透明时钟。透明时钟必须测量发送同步帧/跟随帧的内部校正时延,以及透明时钟
与同步帧/跟随帧的发送器之间的线路时延,从而校正接收时间。此外,若传输设备向发送器或接
收器添加时间戳时出现抖动或主时钟和从时钟的晶振频率之间偏差,均会在主时钟和从时钟之间产
生偏差。因此,在完整地进行一次同步之后,可通过更新偏移量的测量值来确定此偏差,并通过调
整从时钟进行校正。
5. IT 集成功能
PROFINET 的一个重要特征就是可以同时传递实时数据和标准的 TCP/IP 数据。在其传递
TCP/IP 数据的公共通道中,各种业已验证的 IT 技术都可以使用(如 http 、HTML 、SNMP、DHCP
和 XML 等)。在使用 PROFINET 的时候,可以使用这些 IT 标准服务加强对整个网络的管理和维
护,这意味着调试和维护中的成本的节省。
6. IP 管理
PROFINET 使用 TCP/IP 则表示,必须给网络用户(PROFINET 设备)分配 IP 地址。
 使用制造商专用的配置系统分配地址:在网络上不可用网络管理系统的情况下需用此可选
方案。因此,PROFINET 规定了 DCP(发现和基本配置)协议,该协议允许使用制造商专
用的组态/编程工具给 IP 参数赋值,或者在跨系统工程设计内(例如:在 PROFINET 连接
编辑器内)给 IP 参数赋值。
 使用 DHCP 自动分配地址:目前动态主机配置协议(DHCP)已经成为事实上的标准,它
用在办公环境带有网络管理系统的网络内分配和管理 IP 地址。PROFINET 现已选择采用
这些标准,为此,PROFINET 描述了如何能在 PROFINET 环境下优化使用 DHCP。在
PROFINET 设备中实现 DHCP 是一种可选方案。

12.6.4 PROFINET 主从站通讯配置

IO 设备的描述文件输入组态工具。IO 地址分配给现场设备独立的 IO 通道。IO 输入地址包含


接收到的过程数据。用户程序评估和处理这些数据后,形成输出值,并通过 IO 输出地址将它们传
送到系统中。另外,组态工具中参数被分配给独立 IO 模块和通道。组态完成后,组态信息下载到
控制器中。IO 设备被控制器自动分配和组态,接着进入循环数据交换。
1. CoDeSys 侧主站的配置
1) 添加主站
首先在设备下添加 PROFINET 主站,点击设备,右键选择“添加设备”,当弹出添加设备窗
口后,选择“PROFINET IO” --> “PROFINET IO 主站”-->“CIFX-PN”单击“添加设备”,如
图 12.x 所示。
图 12.x 添加 PROFINET IO 主站
添加完主站后用户可以选择手动添加从站或通过硬件自动扫描硬件。首先先介绍如何自动扫描
硬件,这也是在实际操作中常用的一种手段。
2) 硬件扫描
该命令是对应控制器当前设备树中的选择。例如一个已经添加的 PROFINET IO 主站模块可以
被选中并通过扫描命令对其从站设备和 IO 模块进行检查。
“扫描到设备”区域可能仍旧为空或者包含最后一次扫描得到的所有设备和模块的列表。
这意味着在一个对话框中检测和查看硬件配置,并使用户能够将此配置直接映射到工程中的设
备树中。

注意:
扫描命令的处理,只有在应用登录的情况下才可用,启动一个当前连接到 PLC 上的硬件环境的一个扫描。
例 :t#45s + t#50s = t#1m35 s。
被选择的输出数据类型应可存储输出结果,否则可能引起数据错误。
选中主站鼠标右键选择“扫描设备”,随后会自动弹出对话框,将所扫描到的硬件逐一显示。
图 12.x PROFINET IO“扫描设备”对话框
3)设置主站 PNIO 参数
当然,在没有连接实际硬件的情况下,也可以手动添加所有的“PROFINET IO”参数。在
“主站 PNIO 参数”选项卡中可以设置 PROFINET 的主要技术参数。

图 12.x PN IO 设置
a) 标识:
下地址必须定义以便在当前环境中标识主站。只需将光标放置在各自的领域,并编辑条目:
IP 地址: 默认值“192.168.0.1”。
子网掩码:默认值“255.255.255.0”。
默认网关:默认值 “0.0.0.0” 。
站名:默认 “NetX Master”。
注意:
每个设备必须有一个站名,因为这在使用网络操作的特定功能时非常有用。
站名必须是网络中的唯一名称,并且可以包含 240 个小写字符、数字等标识。
b) 看门狗:
看门狗控制:若激活该选项,会启用所定义的看门狗时间来监控主站。如果这段时间内主站没
有收到从站设备响应,则会产生一个超时错误。
时间(m)(ms):监控时间,在看门狗控制被激活的情况下起作用,有效值为 0 到 65535,
单位为毫秒。
c) 从站的地址设置
当硬件扫描(命令“设备扫描”)到从站设备并将其映射到设备树中时,并且,在“扫描设备”
对话框中没有定义这些地址,这时,程序才会采用这些参数。
这种情况下,此处定义的地址会自动应用到添加设备中。缺省采用的 IP 地址为有效范围内下
一个空余的地址。缺省地址由设备描述文件提供且可在编辑框中修改。
4) 添加通讯接口变量。
当完成添加完主站步骤后,需要添加通讯接口变量与从站做对应。

图 12.x 添加通讯接口变量
如图 12.x 所示,在弹出的对话框中可以选择输入/输出变量,Input 即为“从站-->主站”的变量,
Output 为“主站-->从站”的变量。
注意:
主站所添加的通讯接口变量的输入接口与输出接口必须从站的相对应。
例如,主站添加了一个“1 Byte Digital Input”的接口,相应的从站必须配有“1 Byte Digital Output”,
否则会引起通讯的异常。
5)添加变量映射
添加完通讯变量后,鼠标选中该变量接口,在其“PNIO Dev-Module I/O 映射”栏中通过“输
入助手”更改变量的映射,如图 12.x 所示。
图 12.x 更改变量映射

2. 对 CoDeSys 中的主站下的从站进行配置
当 CoDeSys 控制器侧作为主站时,配置完主站后,需要在主站下将相应的从站也进行设定。
1) 添加 PROFINET IO 从站设备
鼠标选中 PROFINET IO 的主站设备,点击右键,选择“添加设备”,弹出提示框如图 12.x 所
示,选择“PROFINET IO”“PROFINET IO 设备”,添加实际使用的 PROFINET IO 从站设备,
以下,以“CoDesys PLC PN Device”为例进行说明。

图 12.x 添加 PROFINET IO 从站设备


完成上述步骤后,点击“添加设备”后,系统会自动添加一个 PROFINET IO 的从站,并带有
5 个属性标签栏,如图 12.x 所示。

图 12.x PROFINET IO 从站属性设置选项


2) 设置 PNIO 参数
PNIO 参数主要是指从站的参数,所有参数如图 12.x 所示。
a) 参数
从站发送数据的实际周期,依赖于如下两个参数(t = 递减因子*发送时钟):
发送时钟 (ms):以毫秒为单位的发送间隔;
递减因子:从发送时刻开始计的周期时间的计算因数;
RT 类:如果该选项有效,则从表中选择需要的类(实时通讯);
VLAN 优先级:在虚拟局部网络中,用户自定义的从站的优先级(0-7)(依赖于设备);
VLAN ID:VLAN 的标识:输入 0-4095 之间的 802.1Q 型数据或 0–32767 之间 ISL 型的数据
(依赖于设备)。
b) 看门狗
看门狗控制: 若激活该选项,会使用下面定义的看门狗时间。若从站在该时间内没有获得主
站信号,产生一个设备特定响应,如,一个出错信息。
时间 (ms): 监测周期,如果“看门狗控制”选项激活,则此参数有效。允许值为:0 到 65535。
c) 模块信息
Ident Number:模块的设备 ID,以 16 进制显示(设备描述文件定义);
d) 用户参数
用户可以在参数表格中相应单元格双击鼠标对变量值进行编辑。根据参数的不同可以通过一个
选择列表直接进行输入选择。列表包含以下基于设备描述的参数属性:
参数:参数名以及参数类别 (在这种情况下没有值输入)
值:当前参数值
数据类型:参数数据类型,例如: "比特"
字节偏移:用户定义的参数存储在数据记录 (字节数组)。字节偏移是指向第一个有效字节。
位偏移:用户定义的参数存储在数据记录 (字节数组)。 位偏移是指向有效字节内的第一个有效
位。
位长:长度信息存储在变量数据记录中包含用户定义的参数。
默认值:默认参数值
允许值:变量的信息可以在列‘值’输入。语法: <参数类型> (<使用的位>) <基本值> <允许
值的范围>。示例: "BitArea (4-5) 0 0-2" 表示以下意思:配置字节的位排列存储在第 4 和第 5 位。
基本值为 0,允许的变量值为从 0 到 2。

图 12.x PNIO 从站设备参数设置


3) 设置 PNIO 标识
PROFINET IO 的连接通过站名和 IP 地址来进行连接的。在“PNIO 标识”中可以对这两项重要
参数进行设置。如图 12.x 所示。

图 12.x PNIO 标识设置


4) IoxS
该对话框是 PROFINET IO 设备编辑器的一部分内,如果在设备描述中定义了 IO-Provider/IO-
Consumer,则可以通过如下的配置,设置地址及变量在程序中进行监控。视图如图 12.X 所示。

图 12.x IoxS 的设置


5)添加通讯变量
鼠标选中从站,鼠标右键,选择“添加设备”,随机系统会弹出如 12.x 所示的提示框,用户
可以通过鼠标选择要添加的通讯变量类型及数量,添加完成后,点击“关闭”结束设置。
图 12.x 添加与主站进行通讯的变量大小及数量
在图 12.x 中可以看到 8Byte Analog Input 和 8Byte Analog Output,前者 Input 对于主站而言是输
入变量,而后者 Output 对于从站是输出变量。完成添加后,即可选中该通讯变量对其进行变量映
射的设置。
6) 通讯变量的映射
无论是输入还是输出变量的设置都是通过地址的方式进行设置的,用户可以直接修改系统自动
分配的地址,如图 12.x 所示。用户可以直接选中该地址选项进行编辑,从而实现与程序中变量的
映射。

图 12.x PROFINET IO 通讯变量的映射

3. CoDeSys 侧作为从站的配置
通常如使用此种配置方式,使用的往往是第三方的 PROFINET IO 主站(非 CoDeSys 平台)进
行配置的,而从站使用的是 CoDeSys 平台。
1) 主站安装 GSDML 文件
第一步,需要在主站的 Step7 中导入从站的 GSDML 文件,以下以西门子主站的配置为例。在
“Options”“Install GSD File...”,随后将从站供应商所提供的 GSDML 文件通过菜单浏览进行
添加。

图 12.x 主站添加从站的 GSDML 文件


如果完成了上位机的设定,PLC 的指示灯的状态如图 12.x 所示。

图 12.x 主站 PLC 的指示灯


2)添加 PROFINET IO 从站设备
鼠标选中设备右键,选择“添加设备”,弹出提示框如图 12.x 所示,选择“PROFINET IO”
“PROFINET IO 设备”,添加实际使用的 PROFINET IO 从站设备,以下,以“NetX PN Device”
为例进行说明。
图 12.x 添加 PROFINET IO 从站设备
3)设置 PNIO 标识
PROFINET IO 的连接通过站名和 IP 地址来进行连接的。在“PNIO 标识”中可以对这两项重要
参数进行设置。如图 12.x 所示。

图 12.x PNIO 标识设置


4)配置通讯变量
鼠标选中从站,鼠标右键,选择“添加设备”,随机系统会弹出如 12.x 所示的提示框,用户
可以通过鼠标选择要添加的通讯变量类型及数量,添加完成后,点击“关闭”结束设置。
图 12.x 添加与从站进行通讯的变量大小
在图 12.x 中可以看到 8Byte Analog Input 和 8Byte Analog Output,前者 Input 对于从站而言是输
入变量,而后者 Output 对于从站是输出变量。完成添加后,即可选中该通讯变量对其进行变量映
射的设置。
5) 通讯变量的映射
无论是输入还是输出变量的设置都是通过地址的方式进行设置的,用户可以直接修改系统自动
分配的地址,如图 12.x 所示。用户可以直接选中该地址选项进行编辑,从而实现与程序中变量的
映射。

图 12.x 添加与从站进行通讯的变量大小
12.7 EtherNet/IP 网络基础
EtherNet/IP 名称中的 IP 是“Industrial Protocol”(工业协议)的简称。由罗克韦尔自动化公司
开发的工业以太网通讯协定,由开放 DeviceNet 厂商协会(ODVA)管理,可应用在程序控制及其
他自动化的应用中,是通用工业协定(CIP)中的一部份。
早在 1990 年后期由罗克韦尔自动化公司开发。是罗克韦尔工业以太网路方案的一部分。后来
罗克韦尔将 EtherNet/IP 交给 ODVA 管理,ODVA 管理 EtherNet/IP 通讯协议,并确认不同厂商开发
的 EtherNet/IP 设备都符合 EtherNet/IP 通讯协定,确保多供应商的 EtherNet/IP 网路仍有互操作性。
EtherNet/IP 是应用层的协定,将网路上的设备视为许多的“物件”。EtherNet/IP 为通用工业协
定为基础而架构,可以存取来自 ControlNet 及 DeviceNet 网路上的物件。
EtherNet/IP 使用以太网的物理层网路,也架构在 TCP/IP 的通讯协定上,用微处理器上的软体
即可实现,不需特别的 ASIC 或 FPGA。EtherNet/IP 可以用在一些可容许偶尔出现少量非决定性的
自动化网路。
EtherNet/IP 很容易误解为 Ethernet(以太网)及 Internet Protocol(网际协议)的组合。不过
EtherNet/IP 是一个工业使用的应用层通讯协定,可以使控制系统及其元件之间建立通讯,例如可编
程逻辑控制器 PLC、I/O 模组等,EtherNet/IP 中的 IP 是指工业协定。

12.7.1 EtherNet/IP 拓扑结构及媒介

建立一个以太网网络首先要做好网络的规划,网络规划就是根据连接设备的个数,安装的空间
距离和环境及对安全性的要求,来决定采用什么样的网络拓扑结构,选用什么样的电缆类型和接头,
以及使用什么样的中转设备。
1. 网络拓扑结构
EtherNet/IP 支持的拓扑结构有线型结构、星型结构、混合结构和环形结构。
1) 线型结构
线型结构允许直接将所有设备直接连接起来而不用任何以太网交换机。如图 12.x 所示。

图 12.x EtherNet/IP 线型拓扑结构


2)星型结构
星型结构,用双绞线或光纤和网线集中设备构成的网络结构,所有的节点都连接在网线集中器
上,网络的材料价格低廉,搭接容易,市面可以找到很多合适设备,并且增减节点和维护维修都很
方便。
这是目前经常采用的网络结构,同样也是 ControlLogix 的以太网推荐采用的网络结构。

图 12.x EtherNet/IP 星型拓扑结构


3)环形结构
如果使用 EtherNet/IP 环型网络结构,即使整个网络中出现了单边出错的情况,网络能够实现
内部切换使用另一路以保证网络的稳定运行,环形结构是满足于冗余的特殊结构。EtherNet/IP 支持
两种环型网,一种是设备级的环型网络及带交换机的网络。图 12.x 为带交换机的环型网络
图 12.x EtherNet/IP 带交换机的环型拓扑结构
如图 12.x 为设备级的环型网络拓扑结构,其中不带有交换机。

图 12.x EtherNet/IP 设备级别的环型拓扑结构

2. 电缆和接头
Ethernet/IP 提供两种连接头的类型,一种是 8 针的模块化连接器,另一种是 4 针的 M12 连接器。
分别是根据 IEC 61076-3 及 IEC61076-2-101 中的标准来定义的。
1) 双绞线电缆是一种费用低廉的,用于星形结构的电缆。最长距离 100m,每个网段两个节点,
有屏蔽和非屏蔽两种。
a) 标准 RJ45 以太网网口
即没有特殊保护的以太网网口,不能应用在 IP65/IP67 的场合,通常应用在柜内以太网连接
IP20 的工业应用项目。连接器如图 12.x 所示。

图 12.x 标准以太网连接器
b) 带安装密封圈的 Ethernet/IP 8 针连接器
带有密封圈及带安装的接头的连接器能够应用在 IP65/IP67 的特殊场合。8 针的接线方式有两
种,在本章的 12.1 节中对这两种接线方式已经有了详细的讲解,再次不再重复说明。带安装密封
圈的 8 针连接器如图 12.x 所示。
a) b)
图 12.x 带安装密封圈的 8 针连接器
a) 8 针的模块化连接器(塑料) b) 8 针的模块化连接器(金属)
c) M12 的 4 针 D 型连接器
4 针的 M12 的连接器内置密封圈,能够应用在 IP65/IP67 的特殊场合。该 M12 的连接器内有 2
对双绞线,如果需要支持如声音,视频及大数据(1G/b 或 10G/b 的以太网)则需要 4 对双绞线配合
8 针的连接器。M12 的 4 针连接器如图 12.x 所示。

a) b)

图 12.X M12 螺纹的 4 针连接器


a )添加对象 b )输入视图名称
2)Ethernet/IP 可支持的光纤接头有三种,ST、SC 和 LC。
a)ST 连接器
ST 连接器是一种刺针式的连接头,光纤直径为 2.5mm,它的管套大部分使用陶瓷材料的,但
有一些也使用金属及塑料材质的。ST 是一种外置弹簧式的连接头,直接推拉连接器即可拔出连接
器。ST 连接器可以支持单模光纤及多模光纤及 POF,ST 的连接器如图 12.x 所示。

图 12.x ST 光纤连接器
b)SC 连接器
SC 连接器是一种通过塑料件安装的推拉式的连接器, 光纤直径为 2.5mm,SC 类型的连接器可
以适用于单模光纤、多模光纤及 POF。可以使用单线或者双线的硬件配置。图 12.x 为这两种光纤
连接器的实物图。

a) b)

图 12.x SC 两种类型的光纤连接器
a) 单线 SC 连接器 b) 双线 SC 连接器
c) LC 连接器
LC 连连接器使用的是 1.25mm 直径的小型光纤线,他可以使用单线或双线的硬件配置。图
12.x 为 3 种不同类型的 LC 连接器。
a) b) c)

图 12.X LC 三种类型的光纤连接器
a ) 单线 LC 连接器 b ) 双线 LC 连接器 c )IP65/67LC 密封双线连接器

12.7.2 EtherNet/IP 运行原理

Ethernet/IP 协 议 基 于 标 准 的 以 太 网 技 术 , 使 用 所 有 传 统 的 以 太 网 协 议 和 标 准 的 TCP/IP
( Transmission ControlProtocol/Internet Protocol ) 协 议 , 并 且 采 用 了 通 用 工 业 协 议 ( Common
Industrial Protocol ,CIP),共同构成 Ethernet /IP 协议的体系结构。该协议的各层结构如图 12.x 所
示。

图 12.x EtherNet/IP 协议框架图


1) 在物理层和数据链路层采用标准以太网技术意味着 Ethernet/IP 可以和现在所有的标准以太网设
备透明衔接工作,并且保证了 Ethernet/IP 会随着以太网技术的发展而进一步发展。
2) 在网络层和传输层,采用 UDP(User Datagram Protocol)协议传送对实时性要求较高的隐式报
文, 将 UDP 报文映射到 IP 多播传送,实现高效 I /O 交换。用 TCP 协议的流量控制和点对点
特性通过 TCP 通道传输非实时性的显式报文。
3) 基于标准的 TCP/IP 协议,在 TCP 或 UDP 报文的数据部分嵌入了 CIP 封装协议,CIP 协议是一
个端到端的面向对象并提供了工业设备和高级设备之间连接的协议,独立于物理层和数据链路
层,使得连接在以太网上的各种设备具有较好的一致性,从而使不同供应商的产品能够互相交
互。
1. EtherNet 和 TCP/IP 技术
由于 EtherNet/ IP 采用了 EtherNet 和 TCP/ IP 技术,因此,采用 EtherNet/ IP 技术的工业控制网
络能够很好地集成到 Internet/ Intranet 上,适应全球化的 Internet 的需要。这是因为以太网是世界上
使用最多的网络,成本低、速度高、获得众多的支持,90%以上的网络采用以太网构成的网络。
EtherNet/ IP 利用 TCP/ IP( UDP/ IP) 来传送隐式的 I/ O 数据和显式的报文数据。TCP 是一个面
向连接的并能够为一台设备同另一台设备提供可靠通信的协议,它只能工作在单播( 点对点) 模式。
UDP 是一个无连接的协议,它只提供了设备间发送数据报的能力,可以工作在单播和多播方式。
对于对实时性要求较高的实时 I/ O 数据,采用 UDP/ IP 协议来传送,而对实时性要求不太高的显式
信息( 如组态、参数设置和诊断等)则采用 TCP/ IP 来传送。EtherNet/ IP 采用了生产者/消费者的通
信模式而不是传统的源/ 目的通信模式来交换对时间要求苛刻的数据。在传统的源/ 目的通信模式下,
源端每次只能和一个目的地址通信,源端提供的实时数据必须保证每一个目的端的实时性要求,同
时一些目的端可能不需要这些数据,因此浪费了时间,而且实时数据的传送时间会随着目的端数目
的多少而改变。而在 EtherNet/ IP 所采用生产者/ 消费者通信模式下,数据之间的关联不是由具体的
源、目的地址联系起来;而是以生产者和消费者的形式提供,允许网络上所有节点同时从一个数据
源存取同一数据,因此使数据的传输达到了最优化,每个数据源只需要一次性的把数据传输到网络
上,其它节点就可以选择性地接收这些数据,避免了浪费带宽,提高了系统的通信效率,能够很好
地支持系统的控制、组态和数据采集。
2. CIP 通用规范
TCP/ IP 协议能够为通过以太网及其它网络相连接的两个设备提供一系列的服务。但是,TCP/
IP 并不能保证网络上的两个节点能够有效通信,它只能保证应用层的信息能够成功的在两个节点间
传送。有效的通信传输需要网络上的双方具有相互兼容的应用软件,使用相同的语言。这些应用软
件需要能够理解从对方传来的信息的属性、服务等,因此它们就需要一个共同的基于 TCP/
IP( UDP/ IP) 的方案,这样,连接在以太网上的各种设备才能够具有较好的一致性。在 EtherNet/IP
网络上, CIP 就是这样一种协议,它使得不同供应商的产品能够互相交互。
CIP 协议是一个端到端的面向对象并提供了工业设备和高级设备之间的连接的协议,它独立于
物理层和数据链路层之上。CIP 有两个主要的目的,一是传输同 I/ O 设备相联系的面向控制的数据,
二是传输其它同被控系统相关的信息,如组态、参数设置和诊断等。CIP 协议规范主要由对象模型、
通用对象库、设备行规、电子数据表、信息管理等组成。
CIP 对象模型使用抽象的对象模型来描述可供使用的一系列通信服务、CIP 节点的外部特性和
CIP 产品获得及交换信息的通用方法。Internet 为网络上的各种分布对象提供端到端的通信服务。
CIP 所使用的面向对象的结构,它使得开发者和最终用户使用简单的、面向对象并且具有广泛的网
络接口的网络设备。详细的网络地址和内部的设备数据结构都对用户透明。
CIP 协议簇包括了一些通用定义的对象(目前有 46 个对象类) 。所有的对象类可以分为 3 种,
分别为通用对象、应用对象和网络特定对象。除了网络特定对象外, 其它对象都可以被 EtherNet/ IP、
DeviceNet 和 ControlNet 使用。CIP 对象在结构上划分为类(Classes)、示例(Instances)、属性
(Attributes)。CIP 对象在寻址时采用的方案主要包括媒体访问标识(MAC ID)、类标识(Class
ID)、示例标识(Instance ID)、属性标识(Attribute ID)、服务代码(Service Code)。
CIP 设备行规为设备提供了一致性规范,这使得设计具有较高一致性的设备更加容易。通常,
功能相似的产品很可能具有完全不同的结构,表现出完全不同的特点,CIP 设备行规对对象结构和
属性的详细描述很好地解决了这个问题,它对常用的各种设备类型提供了较为详细的设计方案,每
一个工业设备都由一些对象及一些同特定设备相关的可选属性组成。属于同一设备模型的所有设备
都必须支持共同的标识和通信状态数据。设备描述是针对各种设备而定义的,包括设备各种特定的
数据。符合设备类型描述的多个供货商提供的简单设备(例如按钮、电动机起动器、光电池、气动
阀执行器)在逻辑上是可互换的。
图 12.x 为支持 CIP 协议的 EtherNet/ IP 设备的对象模型,每一个工业设备都包括 CIP 对象库中
的一部分对象,这些对象中,有些是必须实现的,有些是可供选择的。每一个设备必须包括的对象
有至少一个连接对象、一个实体对象、一个同网络连接相关的对象和一个信息路由对象。EtherNet/
IP 中的同网络连接有关的对象为 TCP/ IP 对象和 EtherNet 连接对象,TCP/IP 对象包括使用 TCP/ IP
协议的信息,EtherNet 连接对象包括 EtherNet/ IP 通信连接的通信参数信息。此外,还可根据实际
的应用来选择加入其它的对象。

图 12.x EtherNet/ IP 对象模型


从 12.x 的 CIP 对象模型可以看到 CIP 协议采用未连接管理器和连接管理器来处理网络上的信
息。EtherNet/ IP 协议是基于高层网络连接的协议,一个连接为多种应用之间提供传送信息的通道。
未连接管理器为尚未连接的设备创立连接。每一个连接被建立时,这个连接就被赋予一个连接 ID,
如果连接包括双向的数据交换,那它就被赋予两个连接 ID。EtherNet/IP 使用 TCP/IP 和 UDP/IP 来
封装网络上的信息,包括显式信息连接和隐式信息连接等。显式报文适用于两个设备间多用途的点
对点报文传递,是典型的请求-响应网络通信方式,常用于节点的配置、问题诊断等。显式报文通
常使用优先级低的连接 ID,并且该报文的相关报文包含在显式报文数据帧的数据区中,包括要执
行的服务和相关对象的属性及地址。隐式报文适用于对实时性要求较高和面向控制的数据如 I/ O 数
据等。I/ O 报文为一个生产应用和一个或多个消费应用之间提供适当的专用的通信路径。I/O 报文
通常使用优先级高的连接 ID,通过一点或多点连接进行报文交换。报文的含义由连接 ID 指示,在
I/O 报文利用连接 ID 发送之前,报文的发送和接受设备都必须先进行配置,配置的内容包括源和目
的对象的属性,以及数据生产者和消费者的地址。
3. 通信模型
EtherNet/IP 采用生产者/消费者通信模式代替点对点方式来保一证高实时性要求的数据交换。
点对点方式是传统的通信模式(即源/目的通信模式),当将报文发送到 X 个节点时,需发送 X 次,
而生产者/消费者模式允许 X 个节点同时存取数据,节约带宽,甚至各节点接收到报文的时间一致,
可实现精确的同步,提高了通信效率。
CIP 协议是一个端到端的面向对象的,提供了工业设备和高级设备之间进行协议连接的数据通讯
机制。CIP 连接可分为显性报文连接和 I/O 连接(隐性报文连接)。
CIP 协议的 I/O 连接模型如图 12.x 一所示。隐式报文连接通过专用的特殊通讯路径或端口,在
生产者和多个消费者应用对象之间建立连接。这类报文专门用于传输 I/O 数据,隐式报文数据的含义
已经在通讯连接建立、分配连接标识的时候完成了定义。因此,隐式报文中只包含具体应用对象的
数值。
图 12.x CIP 协议 I/O 连接模型
CIP 协议的显性报文连接模型如图 12.x 所示。显式报文连接用于两个设备之间的普通信息传输,
可以使用多用途的通讯路径。使用典型的请求应答网络通讯模式,一般用来上载下载程序、设备信
息、组态信息等。通常需要访问报文路由对象。每一个请求报文包含有明确的显式信息,例如接收
方的网络地址、需要执行的动作等内容。

图 12.x CIP 协议显性报文连接模型

4. EtherNet/IP 协议的数据封装
CIP 数据包发送之前要完成数据包的封装,即将 CIP 报文帧封装到 TCP(UDP)帧中。这种 CIP
信息的封装操作是 EtherNet/IP 规范在其应用层提供的承载服务。CIP 数据包所请求的服务属性决定
了报文首部的内容。以太网连接中,如图 12.x 所示,封装的 CIP 数据包包括报文首部(专用于以太网)、
IP 首部、TCP 首部和封装首部。任何支持 TCP/IP 的网络都支持 EtherNet/IP 的封装层。TCP(UDP)
端口 0xAF12 的作用是传送封装好的 CIP 数据包。

图 12.x EtherNet/IP 协议的报文封装


CIP 数据包之所以能够通过 TCP 或 UDP 顺利地发送和接收,是因为其封装首部含有控制命令、
格式、同步数据和状态信息等字段。表 12-x 给出了 CIP 报文的封装格式。

表 12-X CIP 报文封装格式


字段 数据类型 描述
报文头 Command UINT 命令字
(24 字节) Length UINT 数据长度
Session Handle UDINT Session ID
Status UDINT 状态代码
Sender Context 8 字节数组 发送方上下文
Options UDINT 选项标志
数据 Encapsulated Date 0~65511 字节长数组 特定命令相关数据

12.7.3 EtherNet/IP 通讯配置

1. CoDeSys 侧主站的配置
1) 添加主站
首先在设备下添加 EtherNet/IP 主站,点击设备,右键选择“添加设备”,当弹出添加设备窗
口后,选择“EtherNetIP” --> “EtherNetIP 扫描器”-->“CIFX-EIP”单击“添加设备”,如图
12.x 所示。

图 12.x EtherNet/IP 扫描器添加


确认后鼠标选中“添加设备”即完成设备的添加。完成后的扫描仪设置界面如图 12.x 所示。
2) 扫描仪设置
一个 Ethernet/IP 扫描配置对话框是 Ethernet/IP 设备编辑器的一部分。扫描仪设置的设置界面如
图 12.x 所示。
图 12.x EtherNet/IP 扫描仪设定
a) 地址设定
使用混合 IP-地址:在“IP 地址”, “子网掩码” 以及 “网关” 输入包含四字节并且每个可
以用于定义网络内的扫描。将鼠标放在相应的编辑区域可以对默认设置进行修改。
b) 自动获得 IP-地址
BOOTP:通过一个自主协议从配置服务中获得一个 IP 地址 (BOOTP)
DHCP:通过动态配置协议由主机自动配置网络设置 (DHCP)
c) Ethernet Settings:
Speed & Duplex:右边的下拉菜单包括了不同的传输波特率设置;选择“自动检测”,将使用
可用的最高波特率。
2. 对 CoDeSys 中的扫描器下的从站设备进行配置
当 CoDeSys 控制器侧作为主站时,配置完主站后,需要在主站下将相应的目标从站也进行设
定。
1) 添加 EtherNet/IP 目标设备
鼠标选中 EtherNetIP 的扫描器设备,点击右键,选择“添加设备”,弹出提示框如图 12..x 所
示,选择“EtherNetIP”“EtherNetIP 目标”,添加实际使用的 EtherNet/IP 从站设备。

图 12.x 添加 EtherNet/IP 目标设备


如果图 12.x 的目标列表中没有用户所需要的设备文件,则需要到设备供应商的网站下载对应
的 EtherNet/IP 的 EDS 文件,在“工具” “设备库”中进行添加,添加的类型选择“EDS 和 DCF
文件”。
2) 设定目标设备
图 12.x EtherNet/IP 目标设备设定
a) 地址设置
IP 地址:使用 4 个字节来标识 EtherNet/IP 目标设备,单击编辑框可以修改。
BOOTP:如果 BOOTP 选项 (Bootstrap 协议) 被激活,IP 地址将会分配给通过 MAC 地址定义
的从站设备。设备特殊“MAC 地址”必须在 MAC 地址区域进行定义。“节点 IP 地址”选项通知
从站保存 IP 地址 (如果从站支持这个功能)。
b) 电子键控
这部分包含从设备描述文件中读取的信息,包含“设备类型”、“作者代码”、“产品代码”、
“主要版本” 以及 “次要版本”。对于一个实际存在的目标设备这个信息只能读取不能编辑。如
果要对一个一般设备进行设置,也可以对这些变量进行编辑。通过按键“复位默认值”选中的变量
可以被设置为默认值。
3) 配置通讯变量
对话框的上面部分包含了一系列连接配置,包括 RPI(请求包间隔=发送应用向目标应用传输
数据的时间间隔的毫秒数),输入/输出数据的大小,配置的大小。 配置界面如图 12.x 所示。

图 12.x EtherNet/IP 目标设备连接设定


a)添加连接
通过点击“添加连接...”一个具有输入输出的新连接将会被创建。以下对话框可以用于进行配
置。该处可以修改选中连接的输入和输出的数据包的大小、配置的大小。连接的参数如图 12.x 所
示。
图 12.x EtherNet/IP 新建连接
b) 通用参数:
连接路径:该参数是通过系统自动生成的。
触发类型:
 循环:设置数据的周期的变化,周期的变化是根据 RPI 所设定的时间。
 改变状态:当应用对象检测到状态改变时发生。注意,接收端可能已被设置为以确定的速
率接受包,而不管数据产生端的触发机制。
传输类型 :用户可以在 协议中的 CIP Volume 1 和 Volume 2 找到详细信息。
RPI (ms)(是 Requested Packet Interval 的简称):以毫秒(ms)为单位的传输间隔时间,目
标应用对象的传送数据是根据发送应用对象的请求而决定的。该参数必须是总线任务周期的倍数关
系。超时倍增:设备等待的时间如大于 RPI * (所设定倍率),则设备的状态会变为“Error”。
c) 从目标到扫描(消耗)/(生产):
O--> T 大小(Bytes):从适配器至扫描器的数据大小,单位为字节。
T--> O 大小(Bytes):从扫描器至适配器的数据大小,单位为字节。
配置#1 大小(Bytes):配置#1 的数据大小,单位为字节。
配置#2 大小(Bytes):配置#2 的数据大小,单位为字节。
4) 设置用户参数
在此选项卡中指定了一些在从站设备启动时就发送给总线系统的额外的系统参数,设置界面如
图 12.x 所示。
图 12.x EtherNet/IP 选择参数
名称:参数的名称。
类:网络中所有可访问的对象类别都有一个唯一的整数值标识号。如图 12.x 的 a)所示。类也
可以由该类特定的对象实例来指明,见实例的说明。
实例:实例是一个整数值,用以标识类中的一个目标实例,如图 12.x 的 b)所示。

a) b)

图 12.X EtherNet/IP 用户参数的类别和实例


a ) 对象类别 b ) 对象实例
在实例的设置中,也可以将实例设置为 0,这个特殊实例引用的其实就是类本身,例如图 12.x
的 a)所示。其实指的是就类别 5。
属性:属性是一个整数值,它是类或者实例的一部分,属性如图 12.x 的 b)所示。

a) b)

图 12.X EtherNet/IP 用户参数的类别和实例


a ) 对象实例 0 b ) 属性
位长度:系统会根据用户设定的“数据类型”进行自动调整。
值:需要写入参数的数值。
5) 设置变量的 I/O 映射
变量的 I/O 映射界面如图 12.x 所示。选中“EtherNet/IP I/O 映射”选项卡,无论是输入还是输
出变量的设置都是通过地址的方式进行设置的,用户可以直接修改系统自动分配的地址,如图 12.x
所示。用户可以直接选中该地址选项进行编辑,从而实现与程序中变量的映射。

图 12.X EtherNet/IP I/O 映射设置


第13章 附加功能

13.1 程序安全
13.1.1 工程文件加密

1. 密码

2. 硬件加密狗

13.1.2 库文件加密

13.1.3 用户管理及访问限制

“用户管理”和“用户管理界面”插件为工程提供了用户账户以及访问配置(访问权限)的功
能。注意 特定设备用户管理以可以用于控制在运行系统中的 PLC 文件系统和对象的访问权限。
工程的访问权限通过指定的动作只能分配给用户组,不能分配给单一的用户。所以具有权限的
用户必须是组的成员。

是否有需要加入这部分内容?

13.2 诊断及常见故障处理
13.2.1 下载出错

很多编程者在编写程序的过程中由于思路往往不够缜密,导致程序在下装运行后,PLC 会提示”
下装例外错误”,而令编程者烦恼的是如何确认故障的原因。在这里,给大家总结一下产生该错误的
可能原因,以免大家在编写的过程中可以提前避免。

是否有需要加入这部分内容?
13.2.2 添加隐含检查功能

在程序的编写过程中,可能会发生如下的几种情况:
 除法运算的被除数在某些情况下会为零;
 指针在赋值的过程中可能不小心指向空地址;
 调用数组时数组边界别溢出了;

针对上述情况,CoDeSys 有专门的解决方案,在一个应用下可以添加特殊的 POUs,但是这个


POU 程序必须存在在应用下,如果隐式检查能够检查函数的阵列和界限,以及除数为零和运行系
统中的指针。注意,如果设备的校验功能是由一个特殊的库提供的,那么这个功能可以被停用。
因为这个原因“添加对象”菜单中的“POUs 的隐式检查”属性中提供了以下函数功能:
 CheckBounds
 CheckDivInt
 CheckDivLInt
 CheckDivReal
 CheckDivLreal
 CheckRange
 CheckRangeUnsigned
 CheckPointer
挡在 POU 中添加一个检查之后,将会按照选定的编程语言方式打开。默认的编程环境是 ST 语
言编辑器。
用户可以在应用下鼠标右键选择“添加对象”,选择“用于隐含检查的 POU”,随后,系统
则会弹出对话框,如图 13.x 所示。如下,会对这几种常用的函数做介绍。

图 13.X 隐含检查的 POU 添加选项


1) CheckBounds
此函数检查是否对数组的边界有侵犯(例如,通过检测到的错误标志设置或更改索引)。一个
可变的数组类型被分配这个函数被称作隐藏的函数。
当调用该函数参照以下输入参数:
 索引:字段元素的索引;
 下限:字段部分的下限;
 上限:字段部分的下限。
只要索引的范围内,则返回值是索引本身。否则将被返回对应违反上限或下限范围内的字段。
例如,在程序的数组中“a” 超出上限,其程序如下,
PROGRAM PLC_PRG
VAR a: ARRAY[0..7] OF BOOL;
b: INT:=10;
END_VAR

a[b]:=TRUE;
在程序之初,数组 a 只有 0~7 八个成员,而在实际的程序中,a 数组的第 b 个成员为 TRUE,
而 b 在程序定义时却为 10,实际已经超出了数组 a 的定义范围。
当使用了该 CheckBound 函数后,将影响的分配前的影响,被改变的索引值从“10”到上限
“7”。因此值 TRUE 将会分配给数组元素 a[7]。
2) Check+数据类型
为 了 检 查 除 数 的 值 , 避 免 除 数 为 零 , 可 以 使 用 检 查 函 数 CheckDivInt, CheckDivLint,
CheckDivReal 以及 CheckDivLReal。在将它们包含在应用中之后每个相关代码发生的除法过程都将
产生一个此函数调用的预处理。
例如,使用除法指令,具体程序如下,
PROGRAM PLC_PRG
VAR
erg:REAL;
v1:REAL:=799;
d:REAL;
END_VAR

erg:= v1 / d;
在上例中,erg 等于 v1 除以 d,而 d 在变量定义之初并没有赋予初值,故其初值为 0,在程序
中如果直接将数除以 0,系统则会出错。但是,如果在指令中经过了指向除法运算检查的
CheckDivReal 函数之后除数“d”的值在初始化的时候变为“1”。因此除法最终结果为 799 ,能够
有效的避免控制器异常出错。
3) CheckRange(Un)Signed
为了在运行过程中检查域的限制,可以使用函数 CheckRangeSigned 或 CheckRangeUnsigned。
此检查功能的目的是恰当的子集违规处理(如设置一个检测到的错误旗帜或改变值)。当一个
变量的子集类型被确认后这个功能将被隐藏访问。
当访问这个功能时得到以下输入参数:
 值:域类型被分配的值
 低:域的下限
 高:域的上限
如果被分配的值是在有效的域内,他将作为功能中的返回值被使用。否则,对应超过范围的数
值,要么上限或下边界的范围将被返回。
例如,分配 i:=10*y 将被隐性替代为
i := CheckRangeSigned(10*y, -4095, 4095);
如果 y 的值为 1000,变量 i 将不会分配到原始执行提供的 10*1000=10000 , 取而代之的是
4095,因为函数设定的上限值最大为 4095。
例如,死循环的例子,
VAR
ui : UINT (0..10000);
END_VAR
FOR ui:=0 TO 10000 DO
...
END_FOR
FOR 循环将永远不会离开,因为检查功能制止了将 ui 的超过 10000。

注意:
使用 CheckRangeSigned 指令和 CheckRangeUnsigned 的功能,可能会导致在一个无限循环,例如,
如果一个子界类型被用作循环不匹配子范围的增量。
4) CheckPointer
函数 CheckPointer 检查地址的指针引用是否都在有效的内存范围内。
在运行过程中,用户可能在每个指针操作都可以使用 CheckPointer 来进行指针访问的检查。

第14章 附录

14.1 快捷键
14.1.1 快捷输入

使用快捷键 [ Ctrl ] +[ Enter ] 能实现快捷输入,而不用讲变量完整的输入。

表 6-x 快捷键一览
类型快捷键 定义
B or BOOL BOOL
I or INT INT
R or REAL REAL
S or string STRING

例 6-x
快捷键 结果
1 A A: BOOL;
2 A B I 2 A, B: INT := 2;
3 ST1 S 2; A string ST1:STRING(2); (* A string *)
4 X %MD12 R 5 X AT %MD12: REAL := 5.0;
5 B ! B: BOOL;

 An address (as in %MD12) is extended by the ⇘ AT"AT" attribute (see below: example 4).
 A text after a semicolon (;) becomes a comment (see below: example 4).
 All other characters in the line are ignored (see below, e.g., the exclamation point in example 5).

 如果没有相关类型快捷键输入,则自动以 BOOL 类型定义,详见 1。


 数字常数,取决于定义的数据类型,将会作为初始数值或 String,详见例子 2,3。
14.1.2 切换窗口

提供编辑器的切换,使用快捷键[Ctrl ] +[Tab],持续按住[ Ctrl ],按[Tab]进行窗口的切换。

图 13.x 窗口切换
第15章 参考文献
[1] Karl-Heinz J, Michael T. IEC 61131-3 Programming Industrial Automation Systems
[M]. German:Springer, 2010.
[2] Holger Zeltwanger. CANopen-das standardisierte,eingebettete Netzwerk[M].
German:gebundene Ausgabe,2008.
[3] 彭瑜,何衍庆. IEC 61131-3 编程语言及应用基础[M]. 北京:机械工业出版社, 2009.
[4] 谭浩强. C 程序设计[M]. 北京:清华大学出版社, 2005.
[5] 王小科等. C#开发宝典[M]. 北京:机械工业出版社, 2012.
[6] 李幼涵. 施耐德 SoMachine 控制器应用及编程指南[M]. 北京:机械工业出版社, 2014.
[7] 邓李. ControlLogix 系统实用手册[M]. 北京:机械工业出版社, 2008.
[8] 姜建芳. 西门子 S7-300/400 PLC 工程应用技术 [M]. 北京:机械工业出版社, 2012.
[9] 李正军.现场总线与工业以太网及其应用技术[M]. 北京:机械工业出版社, 2012.9
[10] 王丽丽. CoDeSys 平台下嵌入式系统软 PLC 的研究[D]. 北京:北京工业大学, 2007.
[11] 喻塞花. 基于 Windows 的软 PLC 系统开发[D]. 南京:南京航空航天大学, 2011.
[12] 吴爱国,李长滨. 工业以太网协议[D]. 武侯:计算机应用, 2003.23.11.
[13] 杨镇宇,何佳育,朱智炜. CoDeSys 控制软件操作说明论文[D]. 台湾:逢甲大学,2010.
[14] 宋文好. 基于 Modbus 协议的远程无线抄表系统的设计与实现[D] . 杭州:浙江工业大学,
2012.
[15] 马立新,康存锋. CoDeSys V3 基础编程入门[G]. 德国 3S 软件有限公司.
[16] CoDeSys V3.5 在线帮助[G]. 德国 3S 软件有限公司.
[17] CoDeSys 2.3 中文教程[G]. 德国 3S 软件有限公司.
[18] 可编程控制器 AC500[G]. ABB(中国)有限公司
[19] CoDeSys 编程手册 和利时 G3 系列小型一体化 PLC 软件手册[G]. 杭州和利时自动化有限公司
[20] M218 SoMachine 指令手册[G]. 施耐德电气
[21] 王蔚庭 解析工业标称语言国际标准[D] IEC 61131-3 北京凯恩迪自动化技术有限公司
[22] 韩明睿 现场工业总线在自动化系统中的应用[J] 电气传动自动化,2004.26-4

You might also like