PLC编程常见错误

STEP7编程常见错误

Mistakes in Programming with STEP7

摘 要

本文档主要用于讨论以下相关问题: STEP7编程中常见错误 常见错误的分析及避免方法

关键词

Step7;梯形图;语句表;编程;错误

Key Words

Step7;LAD ;STL ;Programming ;Mistake

目 录

STEP7编程常见错误................................................................................................1 1. 前言....................................................................................................................5 2. STEP7编程常见的错误例子...............................................................................5

2.1.

简单错误............................................................................................................5 2.1.1. 地址超范围............................................................................................................................5 2.1.2. 对指令不熟悉........................................................................................................................6 2.1.3. 地址重叠................................................................................................................................6 循环程序错误....................................................................................................6 2.2.1. 循环程序初始化....................................................................................................................7 2.2.2. 循环程序执行时间................................................................................................................8 2.2.3. 循环程序累加控制................................................................................................................9 数据类型匹配不严谨........................................................................................9 2.3.1. STL 指令数据类型匹配.........................................................................................................9 2.3.2. 数据类型匹配与浮点数运算..............................................................................................10 2.3.3. 浮点数运算与比较指令...................................................................................................... 11

语句执行先后顺序.......................................................................................... 11 上升(下降)沿不工作..................................................................................13 定时器不工作..................................................................................................15 定时器的定时与程序扫描周期......................................................................17 软定时器的使用..............................................................................................18 计数器不工作..................................................................................................18

2.2.

2.3.

2.4. 2.5. 2.6. 2.7. 2.8. 2.9. 2.10.

数据块错误......................................................................................................18 2.10.1. 打开数据块错误................................................................................................................18 2.10.2. 数据块寻址长度错误........................................................................................................19 2.10.3. 数据块寻址不严谨错误....................................................................................................19 2.10.4. 数据块寄存器使用错误....................................................................................................19 2.10.5. 改变DB 寄存器和地址寄存器AR1操作........................................................................21 2.10.6. STRUCT 数据类型作为 FC 或 FB 里的地址...............................................................21 2.10.7. STRUCT数据类型作为 FC 或 FB 的实参被调用............................................................22 2.10.8. 通常情况,DB寄存器不受影响........................................................................................23 2.10.9. 数据块的完整引用方式的优缺点....................................................................................24

2.11.

在FC 的使用当中常见的错误.........................................................................25 2.11.1. ENO 的误解........................................................................................................................25 2.11.2. 停止对FC 调用后引起的故障:.......................................................................................26 2.11.3. FC 中临时变量的使用:...................................................................................................28 2.11.4. FC 输出处理.......................................................................................................................31 调用FB 引起错误...........................................................................................33 2.12.1. FB 的输出处理...................................................................................................................33 2.12.2. 在FB 中使用AR2...............................................................................................................33

关于FC/FB使用的总结:...............................................................................35

2.12.

2.13. 2.14.

OB 块引起错误.................................................................................................35 2.14.1. OB 未装载........................................................................................................................35 2.14.2. 调用中断程序引起的故障................................................................................................36

项目一致性检查(数据块,FB, FC更新)..................................................36 例子程序的使用事项......................................................................................37 重要声明:......................................................................................................38

2.15. 2.16. 2.17.

3. 附录-推荐网址................................................................................................38

3.1.

西门子自动化与驱动产品的在线技术支持..................................................38

重要提示:本文为技术交流文档,不能作为订货、选型等重要事宜的唯一依据,建议用户参考 Siemens 的标准产品样本和技术手册进行产品的选型和订货。

1. 前言

学习任何一种编程语言都不是一件简单的事情,不可能一朝一夕完成。任何一种编程语言都遍布陷阱(尽管各种编程语言的发明人尽量避免这种情况的出现)。作为编程人员,必须要清楚程序的来龙去脉,否则程序的执行结果就有可能与编写人员的初衷大相径庭,甚至造成不必要的财产损失和人身伤害。

本文不会讲述STEP7软件及编程语言的详细使用方法,关于这部分内容请用户参考相关手册。 在本文中,笔者将会列举一些STEP7编程常见的错误,其中一些例子来自工程实例。笔者并未将其直接用于本书,而是将其精简成易于理解,易于发现错误的例子(删除工艺因素及无关逻辑程序干扰)。希望通过对这些例子的讲解,用户能够减少在编程方面的错误,能够快速地在纷繁复杂的程序中查找出错误所在,加快开发项目的进度。

相关手册地址连接:

S7-300和S7- 400的梯形图 (LAD) 编程

S7-300 和S7-400 的语句表 (STL) 编程

S7-300 和S7-400 的 功能块图 (FBD) 编程

使用STEP 7 V5.3 编程

2. STEP7编程常见的错误例子

2.1. 简单错误

下面列举三个简单的STEP7编程常见的错误例子,这三种错误是非常常见的,但却非常容易被忽视:

2.1.1. 地址超范围

A =

M3000.0 Q0.0

上面这两条语句相当简单,语法没有任何错误,可以下载到部分S7-400系列CPU 当中,但是,如果用户试图将这两条语句下载到CPU315-2DP 当中,那将无法完成,因为CPU315-2DP 不支持M3000.0这么大的地址空间。

2.1.2. 对指令不熟悉

A M 0.0 FP M 0.0 = Q 0.1

同样以上三条语句是没有任何语法错误的,本意是当M0.0由 0 变为 1 的上升沿位置时,Q0.1 导通一次。但由于FP 指令是用了与A 指令相同的地址M0.0, 所以此处Q0.1 的状态是不会有任何变化的。

2.1.3. 地址重叠

A

=

M0.0 M11.0

………………… L T

0 MW10

与前面的两个例子一样,这四条语句是没有语法错误的。但如果这些语句分布在程序的不同位置,由于MW10包括了M11.0,用户就要考虑对M11.0的“写操作”与对MW10 的“写操作”是否存在逻辑冲突的问题了。

通过以上三个简单的例子,可以得出如下结论:即使再简单的程序,也存在着出现编程错误的可能性。所以在后续的章节中,将单独列举一些STEP7 编程中常见的错误。

2.2. 循环程序错误

用户在编程过程中,循环程序的使用是非常常见的。下面例子的初衷为实现一个500次的循环操作(Network2 添加的用户程序可以被执行500次)。但是由于没有考虑下述的几个因素,使得程序不能正确执行。

图2-1循环程序示例(a)

2.2.1. 循环程序初始化

首先,程序中没有MW0初始化的语句,一旦循环程序被多次调用将发生错误,所以应在LOOP 标号前应增加如下语句:

L T

0 MW0

将编程环境切换为STL 格式后,可得到如下程序:

图2-2循环程序示例(b)

2.2.2. 循环程序执行时间

上图为比较常见的循环程序例子,在network3处添加了用户程序后,是不是所有的工作就完成了呢?答案是否定的,我们还需要考虑CPU 的扫描执行周期问题。假设network3处所添加的程序为一个或数个子程序,这些程序执行时需要的时间为A, 用户其它程序执行需要的时间为B。

那么,A*500+B的时间总和一定要小于下图中的Scan cycle monitoring time[ms],否则,就有可能由于程序扫描时间超出了CPU 的监控时间而导致CPU 停机,用户应当将硬件组态中的程序扫描监控时间更改为大于此时间的数值。

图2-3 CPU扫描监控时间

2.2.3. 循环程序累加控制

这里之所以将循环程序以STL 格式显示,目的在于提示另一个在编写循环程序经常出现的错误。有些编程人员可能会使用MB0 代替上述程序中的MW0 ,或者不使用加法指令而使用INC 指令。由于这两种用法都是字节操作,如果使用MB0,由于MB0最大为255,永远也不会大于500,所以程序会出现死循环的情况。而MW0作为有符号整数可以最大支持到+32767,包括了0-500的计数范围,所以不会出现错误。因此,在下文中将强调数据类型的匹配的问题。

2.3. 数据类型匹配不严谨

对于任何一门计算机语言,都存在着数据类型匹配问题,作为一名有着良好编程习惯的编程人员应当严格遵循的数据匹配规则。

2.3.1. STL指令数据类型匹配

由于STL 相对于LAD 对于数据类型匹配检查并不严格,所以要求用户在在使用STL 编程的时候尤其要注意到这一点。

特别提示:无论是否会获得正确结果,下列程序是不应当出现在程序当中的:

L L

1.000000e+000 +R

T MD 0

特别提示:而如下的程序的细微区别也应当引起注意:

L L L L

10 L#10 MB10 MW10

这些操作后的执行结果可以参考L 指令的STEP

帮助文件及数据类型说明。

图2-4 L指令操作结果

注意:装载不同的数据类型,累加器ACCU1中的内容改写情况是不同的,例如装载MW10时,ACCU1的高16位将作添加0的处理。

2.3.2. 数据类型匹配与浮点数运算

在流量累计编程中经常会遇到实数加法问题,实数加法运算的注意事项也应当引起编程人员的重视,请看下例程序(假设其在OB35中被调用,目的为每隔一定时间间隔就累计一次流量)

L L

MD0 MD4 +R T

MD 0

//累计流量存储值 //流量瞬时值

以上的程序是否存在问题?很多人会认为没有问题,但实际情况是此程序在运行一段时间后就将出现错误。此程序在运行之初是正常的,因为累计流量初始值及流量瞬时值都为一个很小的浮点数,两数相加后,结果正确。但是当一段时间后,累计流量的数值逐渐增大,当它与瞬时流量的数值相差很远的时候,两者执行加法操作后,瞬时流量的数值将被忽略掉(如9999990.0与0.2做加法操作)。其实具备计算机常识的人都应当清楚这一点,这是由于浮点数的存储机制造成

的,是所有计算机方面编程都需要考虑的问题。这个问题可以通过使用二次累加或多次累加的方法来解决。

特别提示:避免数量级相差太多的浮点数之间进行运算。

2.3.3. 浮点数运算与比较指令

用户程序中很多情况下会对浮点数运算的结果与预先设定值进行比较,例如下面的程序比较MD 与10.0是否相等,如果相等的输出Q0.0 为1。 L MD 0 L 1.000000e+001 ==R

= Q 0.0 此程序存在两个问题:

• 由于浮点数运算存在误差,所以MD0有可能非常接近于10.0,但总是不等于10.0, (例如

9.999999e+000)

• 如果MD0在10.0附近数值波动,有可能造成输出Q0.0 输出频繁波动,造成输出点损坏 因此,用户应当使用一个范围比较的方法代替等于数值比较的方法(例如 9.9

L MD 0 L 9.900000e+000 >R ) A(

L MD 0 L 1.010000e+001

= Q 0.0

2.4. 语句执行先后顺序

由于PLC 扫描程序是由头至尾依次执行的,所以编程人员必须重视程序语句执行顺序对逻辑

结果的影响。对于下面的程序相信大家都会判断MW0中最后的执行结果。但是,随着程序的复杂性的增加,以及其它干扰因素的出现,对于语句执行先后顺序引起的错误,容易被编程人员所忽视。

L T

0 MW0

…… (其它省略的程序段,此时MW0的数值为0) L T

10 MW0

…… (其它省略的程序段,此时MW0的数值为10) L

20 MW0

…… (其它省略的程序段,此时MW0的数值为20)

T

对于下面程序的例子,大多数人会认为是正确的,但实际监控结果却不是这样。 程序原目的:

T1定时器每秒导通一次,C1及C3会每隔一秒钟,进行一次加1 操作。 故障现象:

实际监控结果:C1工作正常,C3并未继续计数。

图2-5程序语句顺序错误

将上面的程序更改为STL 格式,可以更清楚看出语句在程序中执行的顺序。

AN = A

M 0.0 L 0.0 L 0.0

//

AN L SD CU A AN CU

T 1 S5T#1S T 1 C 1

//此处如果T1定时到,则会重新计时, //C1得到了上升沿,计数

L 0.0 //此处的语句将开始新的逻辑, T 1 C 3

//无法将RLO 的0 至 1 的变化送至C3 //C3无法得到了上升沿,不计数

正确的程序反而更加精减,C1与C3

并列出现:

图2-6程序语句顺序正确

正确的程序在STL 格式下的程序为: AN M0.0 AN T1 L S5T#1S SD T1 CU C1 CU C3

特别提示:由于LAD 对程序的语法规则检查是自动完成的,所以编程人员可能在使用时更随意一些,但没有语法规则错误的程序并不一定会按照编程人员的本意来执行。

2.5. 上升(下降)沿不工作

上升(下降)沿不工作也是一种常见的错误,尽管手册中“P”或“N”指令允许的数据类型为:I, Q, M, L, D。但如果没有特殊目的,仅建议使用M 及DB 数据类型。如下图:

图2-7上升(下降)沿指令使用正确

西门子“P”指令要求使用与前面指令不相同的地址,下图为错误用法:

图2-8上升(下降)沿指令使用错误1

“P” 指令要避免使用其它程序有写操作的地址,下图为错误用法:

图2-9上升(下降)沿指令使用错误2

“P” 指令不应使用临时变量作为存储地址(临时变量会随着系统堆栈变化,这一点将会在后续章节详细讲述)

,下图为错误用法:

图2-10上升(下降)沿指令使用错误3

2.6. 定时器不工作

有些用户在使用定时器编程后,发现定时器并没有按照自己的意图去计时工作,出现了不计时错误,进而去怀疑硬件是否故障,CPU是否工作正常等等,浪费了大量的时间和精力。实际上这是由于用户对定时器特性不了解所造成的误解。下面的例子将说明这个问题。 程序原目的:

I4.2的上升沿触发T50, T60的定时,并在T60定时结束后,复位M12.0 故障现象:

I4.2可以触发T50, T60的定时,但有时即使I4.2再次将M12.0置位为 1 ,T50不计时。现象见

下图:

图2-11定时器使用错误

故障分析:

首先要明确这个故障现象既不是硬件故障,也不是语句错误所引起的,而是对定时器使用不正确

引起的故障。

现在我们分析此故障是如何产生的:

1. 某个扫描周期,

a. I4.2的上升沿置位M12.0,I4.2恢复为0

2. 数个扫描周期后, 扫描周期N

a. 当T60计时到时,Network2中M12.0被复位(注意是在SD T50语句的后面),此

扫描周期末M12.0由1 变为了0 b. Network3中T50,T60被复位

3. 扫描周期N+1

a. 如果此时I4.2恰恰出现上升沿置,尽管M12.0在上个扫描周期曾经变为0,但在

本扫描周期开始就变为了1,定时器T50在上个扫描周期接受到的M12.0状态为1,定时器T50在本扫描周期接受到的M12.0状态也为1所以T50将不会工作。

定时器此处读输入

输入信号变化

定时器此处读输入

图2-12定时器错误分析

定时器此处读输入

输入信号变化

定时器此处读输入

图2-13定时器正确使用示意

在上图中,定时器在扫描周期N 与扫描周期N+1之间正确地接收到了上升沿的变化,所以能够正常工作。 故障总结:

定时器计时需要正确地接收到输入端上升沿的变化,如果没有严格遵守这一逻辑顺序,常见的故障现象为定时器不计时工作。这种故障现象可能很隐蔽,本例的原始程序在实际工作中几天才会出现一次故障现象。由于原始程序包括大量的附加逻辑,子程序,语句位置也比较分散,所以排除此故障现象所用的时间超过了3天。

特别提示:此程序改正的方法非常多,例如在置位M12.0指令前增加一些限制条件,用户可以自己尝试。

2.7. 定时器的定时与程序扫描周期

在S7系列CPU 中,定时器的最小时基为10毫秒。也就是说,S7系列CPU 的最小定时时间为10毫秒。如果用户程序代码量比较大,程序扫描周期过了10毫秒,可能会出现如下情况:尽管定时时间已经到达,但CPU 还没有执行到相关的程序逻辑。

特别提示:当用户程序中需要非常短的定时功能时,需要考虑程序扫描周期对定时器状态读取的影响。由于CPU 中的定时中断是由硬件来保证的,并且有高于OB1的优先级, 所以在这种情况下,建议用户使用定时中断的功能来替代定时器的功能。

2.8. 软定时器的使用

有些时候,在编程中会遇到CPU 提供的硬件定时器不够使用的问题,这时可以使用系统提供的软定时器,例如SFB4(TON)。此功能块需要一个背景数据块,

特别提示:使用SFB4需要注意的一个问题,CPU启动后的软定时器复位问题。

由于SFB 的定时、计时值是存在DB 中的,由于当CPU 断电或停机后,DB中的数据是保持的。如果定时器计时到在停机前已经计时,那么当CPU 重新运行后(定时器输入端仍然为1的情况),定时器会在原来计时位置继续计时。为了避免这种情况的出现,可以在OB100中添加如下语句来初始化SFB4的背景数据块(参数PT 应当为T#0MS)。具体信息可以参考STEP7的在线帮助。

软定时器初始化程序: CALL “TON”, DB1 IN: = PT: =T#0MS Q: = ET: = NOP 0

2.9. 计数器不工作

计数器使用的常见故障与定时器非常相似,可以参考定时器的章节

软计数器的使用注意事项类似于软定时器的使用,具体信息可以参考STEP7的在线帮助。

2.10. 数据块错误

对于S7-300/400系列CPU 而言,数据块是其重要的系统资源之一。这些数据块在项目的初始阶段并不存在,编程人员自行定义后并下载至CPU 后,即可使用。正是由于这样的特点,数据块在使用当中存在着一些注意事项,如果忽视这些注意事项,则会引起编程错误。

2.10.1. 打开数据块错误

由于数据块是用户自己定义的,所以在下载至CPU 之前,CPU中是不存在着数据块的。如果用户程序中引用的数据块在CPU 中并不存在,将导致编程错误发生。这种情况可以通过用户对自己程序的了解来避免,即不调用不存在的数据块,也可以通过使用SFC24“TEST_DB”来检测数据块是否存在,再决定是否调用它。

2.10.2. 数据块寻址长度错误

由于数据块的长度或大小也是用户自己定义的,所以用户程序中对数据块的引用不能超出数据块所定义的范围。例如:在DB1中只定义了10个BYTE 数据类型,那么程序中对DB1.DBB10(第11个BYTE)的访问将导致编程错误发生。这种情况可以通过用户对自己程序的了解来避免,即不引用不存在的数据地址,也可以通过使用SFC24“TEST_DB”来检测数据块的大小,再决定如何调用它。

2.10.3. 数据块寻址不严谨错误

有些类型的PLC 对于用户自定义的存储区域的寻址方式是有一定限制的,例如对于整数类型的数据地址是不支持位寻址方式的。而西门子PLC 由于其数据块具有绝对的数据地址,所以可以实现对不同的数据类型地址使用各种方式寻址。例如:DB1.DBW0被定义为一个整数数据类型,但程序中可以对DB1.DBX0.0-DB1.DBX1.7进行位寻址。西门子这种灵活强大的寻址功能给用户提供了非常多的选择,很多算法及数据转换功能可以非常轻松的实现,但与此同时,用户务必要注意如果不遵循数据类型进行寻址,是否会对数据内容的造成影响。

2.10.4. 数据块寄存器使用错误

西门子S7-300/400系列CPU 拥有两个数据块寄存器,它们保存着当前打开的数据块编号:

DB 寄存器保存着打开的共享数据块编号 DI 寄存器保存着打开的背景数据块编号

特别提示:DI 寄存器主要用于FB 引用背景数据块,但也常用于程序中同时打开两个数据块的操作。 如下图的程序即完成了将DB1.DBW0(16#2222)传送到DB4.DBW0中的工作。用户请注意程序中的格式(如T DIW0),详细信息请参考STEP7

编程手册中的寻址方式部分。

图2-14同时打开两个数据块

上述例子也可以使用如下语句直接完成:

图2-15两个数据块之间数据传送

那么上述两者有何区别呢?从两图中的对比可以看出:

也就是说,对于数据块中地址的完整引用,将影响到DB 寄存器的内容。那么对于下面的程序,我们将很容易发现其中的错误。 程序原目的:

将3333传送至DB1.DBW0 将4444传送至

DB1.DBW2 L T L

DBW0 DIW0

//不改变DB 寄存器的内容 //不改变DI 寄存器的内容 //改变DB 寄存器的内容

//改变DB 寄存器的内容,相当于增加了 OPN DB4的指令。

DB1.DBW0

T DB4.DBW0

图2-16错误传送程序

故障分析:

由于程序的Network5中使用了对于DB4.DBW0的比较指令,此指令改变了DB 寄存器的内容,因而我们将得到如下的错误结果,DB1.DBW2并没有得到正确数值,正确数值4444被错误地送到了

DB4.DBW2

中:

图2-17错误传送程序结果

2.10.5. 改变DB 寄存器和地址寄存器AR1操作

那么在STEP7编程中,都有哪些情况会引起DB 寄存器中的内容改变呢?下面列出了可能引起

DB 寄存器或 AR1 内容改变的一些操作:

使用下述复杂语言结构会导致 DB 寄存器 和地址寄存器AR1内容(关于AR1的使用将在后续

章节中讲解)改变:

1. 以绝对地址对DB 块的访问 (如:DB20.DBW10)

2. FB 的多重背景调用

3. STRUCT 数据类型作为 FC 或 FB 里的地址

4. STRUCT 数据类型作为 FC 或 FB 的实参

如果用户在编程时使用了上面提到的选项,则必须手动恢复寄存器的内容,否则可能产生错误。

关于这个问题的细节可以在 STEP 7 帮助中"Avoiding errors when calling modules" 项下找到。

2.10.6. STRUCT数据类型作为 FC 或 FB 里的地址

下图的例子显示了如下两种情况对于DB 寄存器的影响情况。

1. FB 的多重背景调用,

2. STRUCT 数据类型作为 FC 或 FB 里的地址

图2-18程序对DB 寄存器的影响

程序执行过程:

1. 在执行 OPN DB1 后, DB寄存器内容为1

2. 在调用FB2,背景数据块为DB10后,DB寄存器内容为10,DB寄存器被改变

3. 在引用“stuct_db”.my_struct.aa后,DB寄存器内容为11,DB寄存器被改变

注意:FB2的输入参数(BOOL类型)DB5.DBX10.0,虽然此种格式为数据块的完整引用方式,

但作为输入参数类型使用时,并不改变此处DB 寄存器的值

2.10.7. STRUCT 数据类型作为 FC 或 FB 的实参被调用

下图的例子显示了如下情况对于DB 寄存器的影响情况:

STRUCT 数据类型作为 FC 或 FB 里的实参

图2-19访问STRUCT 对DB 寄存器的影响

程序执行过程:

1. 在FC9中调用FC10,并将形参“stuct_db”.my_struct 赋给输入参数FC_IN

2. 在FC10中,FC_IN为STRUCT 数据类型

3. 在FC10中执行 OPN DB1 后, DB寄存器内容为1

4. 引用FC_IN.aa后,DB寄存器内容为11,DB寄存器内容被改变

2.10.8. 通常情况,DB寄存器不受影响

在通常情况下,DB 寄存器是不受影响的,下图为FC9中调用FC11及SFC20后,DB 寄存器不

受影响。

图2-20对DB 寄存器无影响的程序

程序执行过程:

1. 在FC9中执行 OPN DB1 后, DB寄存器内容为1

2. 在FC9中调用FC11及SFC20

3. 在FC11中,引用了地址DB5.DBX0.0

4. 在SFC20参数中使用了ANY 数据类型

5. FC9中,调用FC11,SFC20结束后,DB寄存器内容为1,未受影响

2.10.9. 数据块的完整引用方式的优缺点

至此,也许有的用户会对数据块的完整引用方式存在疑问,既然此种引用方式可以明确当前的

数据寄存器,并且编程简单,是不是可以在程序中全部使用数据块完整引用方式呢?答案当然是

否定的,原因如下:

1. 相对于数据块的完整引用方式,数据块简略方式寻址提供了更灵活的编程方式及功能(特

别是关于指针寻址方式)

2. 数据块完整寻址方式每次都对DB 寄存器进行操作,增加了程序执行时间,不适用于大数

据量编程方式

特别提示:当程序涉及到快速,多次对数据访问时,可以使用M 存储区代替DB 数据区,这样可以

得到更快的程序执行时间,但要注意CPU 中的M 存储区资源要远少于DB 数据区资源,要节约使用。

(对于31x 系列CPU,执行一次 T DBW0指令需要约1.6μS, 而执行一次 T MW0指令仅需要约0.2

μS)

特别提示:上面的例子告诉我们,尽管对于数据块完整地址引用会改变DB 寄存器中的内容,但通

过编程者的重视,这个错误是完全可以避免的。

2.11. 在FC 的使用当中常见的错误

2.11.1. ENO的误解

对于初学者来说,容易在ENO 的使用上出错误,由于不清楚ENO 来龙去脉,经常认为只要调

用FC 是无条件的,那么ENO 也是永远导通的,实则不然。下图中的例子将说明这个问题。

程序原目的:进行模拟量转换,并无条件地将MD10的数值传送至

MD14。

图2-21 ENO的使用

在图中可以看出,当FC105的输入端PIW256在正常范围内的时候,MOVE 指令被执行(ENO=EN),

当PIW256超出了上限值后,MOVE指令不再被执行(ENO≠EN)。此故障还是比较隐蔽的,因为大部

分情况下,输入可能都处于正常范围。

故障分析:在STEP7的LAD 编程手册中有对EN/ENO机制的详细描述,这里不再赘述。仅列出主要

部分内容:

ENO 的值取决于公式:ENO = EN 与非 (error )

• 如果程序调用没有错误(error = 0),则ENO = EN。

• 如果程序调用有错误(error = 1),则ENO = 0。

EN/ENO 机制用于:

• 数学运算指令

• 传输及转换指令

• 移位及循环移位指令

• 块调用

EN/ENO 机制不能用于:

• 比较指令

• 计数器

• 定时器

如果用户要创建自己在FBD 或LAD 中调用的块,那么必须确保退出块时,置位BR 位。这并不

是一个自动处理过程。不能使用BR 作为存储位,因为EN/ENO机制会不断重写BR 位。作为代替,

可使用一个临时变量(例如 #error)来保存发生的所有错误,并用0初始化此变量。在块内部程

序中,如果用户某处程序执行为错误状态,则可以将此变量置1。并且在块结尾编写以下程序段:

end: AN error

SAVE

确保在任何情况下都处理本程序段,这表示禁止在块内使用BEC,并禁止跳过本程序段。

2.11.2. 停止对FC 调用后引起的故障:

下面的程序非常简单,看似正确,但存在着一定隐患。

程序原目的:

在OB1中当M0.0为1 的时候,调用FC13

在OB1中当M0.0为01 的时候,不调用FC13

FC13中包含简单逻辑及定时器的使用

图2-22普通FC 程序内容举例

故障现象:

假设某个时刻,M0.0,M0.1,M2.0都为1 ,并且维持数值1的时间超过了10秒,那么Q0.1,M2.1

也都会为 1。

假设此时M0.0 变为0,FC13

不再被调用,结果如图:

图2-23普通FC 程序执行结果

对于初学者来说,容易忽视的问题为:M0.0 变为0后,FC13中的Q,M,会保持原来状态,T,C,

会继续工作,如果M0.0再次变为1,并且此时M2.0也为1,由于定时器保持着计时到达的状态,

M2.1会立刻变为1,这种情况可能会导致某些在FC 被调用后必须延时执行的逻辑立刻被执行。在

实际应用中,如此逻辑为某个设备启动信号,那么这个设备可能会跳过延时或保护逻辑而马上运

行! 对于编程人员如果能够确保上述现象不构成对人身及财产的伤害,则可以不采取措施,否则

应当加入限制程序,例如下面的复位语句。

图2-24 FC程序复位举例

2.11.3. FC中临时变量的使用:

很多初学者容易将FC 及FB 相混淆,认为FB 仅仅是比FC 多了一个背景数据块,这种认识是非

常危险的。在STEP7的关于FC 的描述是这样的:

FC 是一个没有存储空间的逻辑块。FC的临时变量存储在本地数据堆栈中,这些数据在FC 执

行完毕后将会丢失。为了永久的保存数据,FC可以使用共享数据块。

由于FC 没有自己的存储空间,所以必须指定实参给它的参数(这就是为什么FC 的输入输出

管脚必须填写参数的原因)。FC的临时变量(位于本地数据堆栈中)是无法指定初始值的(由于本

地数据堆栈是由系统自动动态使用的)。为了更形象的说明这一点,我们来看下面的例子,此例子

对L 堆栈在程序调用时的分配进行了详细的讲解:

L 堆栈永远以地址“0”开始。在 L 堆栈中,会为每个FC 提供一定地址空间,作为存放每个

块所拥有的固有数据或局部数据。当某个块终止时,那么它的空间随之也被重新释放出来。 指针

总是指向当前打开块的第一个字节。 运行等级 L 堆栈中指针

的字节数

调用 OB1 (带有 20 个字节的系统固有数据和局部数据的10个附加

字节) 30

调用 FC1 (带有 30 个字节的局部数据)

30 个字节 (OB1) + 30 个字节 (FC1)

调用 FC20 (带有 20 个字节的局部数据)

60 个字节 (OB1 + FC1) +20 个字节 FC10

调用 FC21 (带有 20 个字节的局部数据)

60 个字节 (OB1 + FC1) +20 个字节 FC11

调用 FC2 (带有 50 个字节的局部数据)

30 个字节 (OB1) +50 个字节 (FC2)

调用 FC30 (带有 10 个字节的局部数据)

80 个字节 (OB1 + FC2) +10 个字节 FC20

表2-1 L堆栈在程序执行过程当中的动态分配 0 30 60 60 30 80 60 80 80 80 90

由上面的例子可以看出:对于FC20曾经使用过的系统中L 堆栈60-80区间(FC20中地址范围

为LB0-LB19)在FC20调用结束后,被提供给FC21使用(FC21中地址范围同样为LB0-LB19)。

对于FC 的临时变量认识不清晰,用户在对临时变量的使用当中,也经常会出现一些错误,下

面将使用一个例子非常直观地说明上面的问题

程序原目的:

在OB1在程序中调用FC20后立即调用FC21

FC20中将20赋值给临时变量FC20_TEMP1,将21赋值给临时变量FC20_TEMP2

FC21中将FC21_TEMP1,FC21_TEMP2相加

程序分析:我们发现FC20中的临时变量曾经出现的数值(20,21)被FC21中的临时变量FC21_TEMP1,

FC21_TEMP2得到了,如果直接使用这两个临时变量进行加法操作,可以得到结果41。对于编程人

员来说,临时变量必须要在所在程序段中赋值,而后使用。用户对此例中的FC21_TEMP1, FC21_TEMP2

必须先做清零处理,否则其在使用前即可能拥有数值。

图2-25不同FC 程序临时变量之间的影响

结论:对于FC 或FB 中的临时变量,不要希望将本次调用的数值可以存储在里面以供下次程序调

用使用,因为这些临时变量所使用的L 堆栈空间在FC 或FB 调用结束就释放给系统了,其它后续

程序可以任意使用。所以下列用法都是错误的:

• 将临时变量用于上升/下降沿指令

• 将临时变量用于自保持逻辑

• 临时变量未在所在程序段中赋值,直接使用

警告:不要试图利用L 堆栈的这种特点进行功能或功能块之间的数据传递。程序逻辑改变,语句

执行顺序改变,临时数据区长度定义改变,中断程序都会影响L 堆栈中的数据存储顺序。

2.11.4. FC输出处理

对于FC 的使用,另一个的常见的错误是对输出的错误处理:导致这个错误的原因还是对FC 认

识的不清楚。再次强调:相比较于FB, FC 是一个没有存储空间的逻辑块。如果没有数据被写至FC

的OUT 参数,FC将会输出一个随机值!对于FB, 因为其可以使用背景数据块来存储OUT 参数的数

值,即使某次调用没有对OUT 参数进行写操作,OUT参数依然可以输出上一次的旧值。

下面的程序将说明这一点:

程序原本目的:

在OB1中调两次FC22,将MW0,MW2作为输入参数,DB1.DBX0.0,DB1.DBX0.1分别作为输出参数

赋给FC22

FC22检测当输入大于10时,置位输出为1 FC22检测当输入小于-10时,复位输出为0 FC22的输出的动作死区为-10至10

此程序乍看是没有错误的,但是,如果OB1中调用了两次FC22,而且MW2位于死区(-10 至

10)之间时,MW0的数值改变将不仅仅改变DB1.DBX0.0的状态,同时会影响输出DB1.DBX0.1的数

值。

图2-26 FC程序输出编程错误举例

故障分析:在上面的例子,OB1中调用了两次FC22,而且MW2位于死区(-10 至10)之间时,其

输出在FC22没有被赋值,DB1.DBX0.1正常情况下不应当改变数值。但是本例中,MW0的数值改变

将不仅仅改变DB1.DBX0.0的状态,同时会影响输出DB1.DBX0.1

的数值。如下图。

图2-27 FC程序输出编程错误结果

结论:

对于FC 的输出变量,必须要在每次执行FC 时赋给一个确定的值,否则输出有可能会输出一个

随机值。下列用法都是错误的:

• 将输出变量用于上升/下降沿指令

• 将输出变量用于自保持逻辑

• 输出变量未在所在程序段中赋值

警告:不要因为在FC 编程中遇到没有对输出赋值,而程序执行正确,就忽略了对FC 输出编程的

注意事项,否则将承担这个错误有可能带来的风险。

建议:

• 用IN/OUT变量代替OUTPUT 变量

• 不论何时调用块,FC中的OUT 参数都必须被赋值

2.12. 调用FB 引起错误

2.12.1. FB的输出处理

由于FB 有自己的背景数据块,因此其除了临时变量外,其所有过程数据都可以保存在自己的

背景数据块内。因此对于FB 的使用,只是输出变量的处理与FC 不同,不需要每次都赋给确定的

数值。但其它前者FC 时用的注意事项都适用于FB。

2.12.2. 在FB 中使用AR2

另外由于在FB 中,系统将会使用AR2用于背景数据块的访问,所以如果在FB 中使用了AR2 ,

务必要注意其用法。下面的例子将说明这一点。

程序原目的:

同时对DB12及DB13 中的数据进行操作,将DB12中的多个数据进行加1操作复制到DB13中(本例

仅为了举例说明问题,虽然未涉及复杂算法,也使用了间接寻址) :

DB13.DBB0=DBW12.DBB0+1

DB13.DBB1=DBW12.DBB1+1

DB13.DBB2=DBW12.DBB2+1

下面的程序可以放在FC 中执行,但不可放在FB 中执行。

图2-28 AR2应用于FC

发现此错误很容易,因为当程序存盘后会变成如下状态,其中涉及到AR2的数据块访问被替换

为了背景数据块的变量(图中为输入参数FB1_IN)

图2-29 AR2应用于FB

2.13. 关于FC/FB使用的总结:

对于同时要打开两个数据块,并且涉及间接寻址的程序,推荐使用FC 实现

并且在FC 程序开始增加如下语句存储数据块寄存器及地址寄存器的内容:

L DBNO

T #DBNO_TEMP //用户自定义的WORD 临时变量,存储数据块寄存器数值

L DINO

T #DINO_TEMP //用户自定义的WORD 临时变量,存储数据块寄存器数值

TAR1

T #AR1_TEMP

TAR2

T #AR2_TEMP //用户自定义的DWORD 临时变量,存储地址寄存器数值 //用户自定义的DWORD 临时变量,存储地址寄存器数值

//在以上程序之后,此处可以添加用户自身程序。

在FC 程序结束位置增加如下语句恢复数据块寄存器及地址寄存器的内容:

OPN DB [#DBNO_TEMP]

OPN DI [#DINO_TEMP]

L #AR1_TEMP

LAR1

L #AR2_TEMP

LAR2

警告:以上建议仅代表笔者个人观点,例子程序也是免费的。任何用户都可以免费复制或传播此

程序例子。程序的作者或拥有者对此程序不承担任何功能性或兼容性的责任。此程序的使用者风

险自负

2.14. OB 块引起错误

2.14.1. OB 未装载

在STEP7程序中,所有的用户程序都将在组织块中被调用。而针对于不同事件,CPU将会调用

不同的组织块,当某事件发生时,如果CPU 中没有下载相对应的组织块,CPU 将进入STOP 状态(例

如DP 从站通信故障时,CPU中如果没有OB86,CPU 将进入STOP 状态)。

2.14.2. 调用中断程序引起的故障

调用中断程序引起的故障并不多见,但也应当引起足够的重视,否则也会降低项目程序的可靠性。

1. OB35的使用:

由于定时中断程序具有稳定的执行时间间隔特性,所以OB35也许是除去OB1之外,人们

最经常使用的组织块了。但是如果其执行间隔如果被修改得非常短(例如1毫秒),那么就必须

考虑OB35中的程序是否能够在1毫秒之内执行完毕。如果OB35的执行时间超过了1毫秒,这

时OB35又再次被系统触发,系统将会出错。

2. OB40的使用:

类似的情况也会在OB40中出现,例如某个通道触发了OB40硬件中断,在OB40尚未执行

完毕之前,此通道如果再次触发了硬件中断,此中断将会丢失,不被系统响应。但是,如果某

个通道触发了OB40硬件中断,在OB40尚未执行完毕之前,其它通道触发了硬件中断,此中断

不会丢失,将被系统响应。此情况也应引起注意。

2.15. 项目一致性检查(数据块,FB, FC更新)

由于STEP7的程序是由各种类型的块组成的,用户可以分别对这些块进行编辑或修改,并可

以单独对某个块进行下载操作,而不影响其它块。在使用这种方便灵活的操作的同时,用户也务

必要注意其带来的风险。

例如:

在OB1中调用FC1,当FC1的输入/输出参数作出修改后,如果仅仅下载FC1,而不下载OB1,

那么CPU 将会出现编程错误。所以当用户修改FB/FC, DB, UDT以后,应当对涉及到这些调用的程

序进行更新,避免发生错误。STEP7对此提供了一致性检查的功能,可以在选中程序的BLOCK 目录

后,由菜单的Edit-Check Block Consistency调出此功能。

图2-30块的一致性检查界面

在STEP7程序中,如果出现FB/FC的参数改变/时间标签不一致的情况,所调用的FB/FC会以

红色显示。此时右键点击次FB/FC, 在菜单中将会出现Update Block Call菜单,使用此功能后,

调用程序将自动更新FB/FC的调用。使用此种方式,比手动删除此FB/FC,再手动重新输入各种参

数要方便的多。

图2-31块调用的更新

2.16. 例子程序的使用事项

用户在附件中的例子程序在使用中需要遵循以下注意事项:

• 示例代码大部分编写在FC/FB当中,使用OB1调用

• 当用户希望验证某个FC/FB的功能时,首先应当将相关的FC/FB/DB下载到PLC/PLCSIM当

中,并在OB1中将调用此FC/FB的注释符号删除,下载OB1,此FC/FB即被调用

• 尽量避免同时验证多个FC/FB的功能,因为这些FC/FB可能存在着逻辑上的冲突

• 对于不需要验证功能的FC/FB,在OB1中应当保持其作为注释出现的状态

本文附件程序使用的说明:

FC1:循环程序示例

FC2:浮点数运算程序

FC3:程序执行顺序例子

FC4:上升延指令

FC6:定时器触发例子

FC7:同时操作两个数据块的循环程序例子

FC8:数据块寄存器例子1

FC9:数据块寄存器例子2

FC10:数据块寄存器例子3

FC11:数据块寄存器例子4

FC12:ENO使用例子

FC13:停止调用FC 后引起故障的例子

FC20:FC中临时变量使用的例子1

FC21:FC中临时变量使用的例子2

FC22:FC输出使用的的例子

FC23:系统变量保存的例子

FB1: 在FB 使用AR2的例子

2.17. 重要声明:

由于例子是免费的,任何用户可以免费复制或传播此程序例子。程序的作者对此程序

不承担任何功能性或兼容性的责任,使用者风险自负。

西门子不提供此程序例子的错误更改或者热线支持。

3. 附录-推荐网址

3.1. 西门子自动化与驱动产品的在线技术支持

AS

西门子(中国)有限公司

工业自动化与驱动技术集团 客户服务与支持中心

网站首页:http://www.ad.siemens.com.cn/Service/

AS 下载中心:

专家推荐精品文档:http://www.ad.siemens.com.cn/Service/recommend.asp

“找答案”AS 版区:http://www.ad.siemens.com.cn/service/answer/category.asp?cid=1027

版权 西门子(中国)有限公司2001-2008 版权保留

复制、传播或者使用该文件或文件内容必须经过权利人书面明确同意。侵权者将承担权利人的全

部损失。权利人保留一切权利,包括复制、发行,以及改编、汇编的权利。

西门子(中国)有限公司

STEP7编程常见错误

Mistakes in Programming with STEP7

摘 要

本文档主要用于讨论以下相关问题: STEP7编程中常见错误 常见错误的分析及避免方法

关键词

Step7;梯形图;语句表;编程;错误

Key Words

Step7;LAD ;STL ;Programming ;Mistake

目 录

STEP7编程常见错误................................................................................................1 1. 前言....................................................................................................................5 2. STEP7编程常见的错误例子...............................................................................5

2.1.

简单错误............................................................................................................5 2.1.1. 地址超范围............................................................................................................................5 2.1.2. 对指令不熟悉........................................................................................................................6 2.1.3. 地址重叠................................................................................................................................6 循环程序错误....................................................................................................6 2.2.1. 循环程序初始化....................................................................................................................7 2.2.2. 循环程序执行时间................................................................................................................8 2.2.3. 循环程序累加控制................................................................................................................9 数据类型匹配不严谨........................................................................................9 2.3.1. STL 指令数据类型匹配.........................................................................................................9 2.3.2. 数据类型匹配与浮点数运算..............................................................................................10 2.3.3. 浮点数运算与比较指令...................................................................................................... 11

语句执行先后顺序.......................................................................................... 11 上升(下降)沿不工作..................................................................................13 定时器不工作..................................................................................................15 定时器的定时与程序扫描周期......................................................................17 软定时器的使用..............................................................................................18 计数器不工作..................................................................................................18

2.2.

2.3.

2.4. 2.5. 2.6. 2.7. 2.8. 2.9. 2.10.

数据块错误......................................................................................................18 2.10.1. 打开数据块错误................................................................................................................18 2.10.2. 数据块寻址长度错误........................................................................................................19 2.10.3. 数据块寻址不严谨错误....................................................................................................19 2.10.4. 数据块寄存器使用错误....................................................................................................19 2.10.5. 改变DB 寄存器和地址寄存器AR1操作........................................................................21 2.10.6. STRUCT 数据类型作为 FC 或 FB 里的地址...............................................................21 2.10.7. STRUCT数据类型作为 FC 或 FB 的实参被调用............................................................22 2.10.8. 通常情况,DB寄存器不受影响........................................................................................23 2.10.9. 数据块的完整引用方式的优缺点....................................................................................24

2.11.

在FC 的使用当中常见的错误.........................................................................25 2.11.1. ENO 的误解........................................................................................................................25 2.11.2. 停止对FC 调用后引起的故障:.......................................................................................26 2.11.3. FC 中临时变量的使用:...................................................................................................28 2.11.4. FC 输出处理.......................................................................................................................31 调用FB 引起错误...........................................................................................33 2.12.1. FB 的输出处理...................................................................................................................33 2.12.2. 在FB 中使用AR2...............................................................................................................33

关于FC/FB使用的总结:...............................................................................35

2.12.

2.13. 2.14.

OB 块引起错误.................................................................................................35 2.14.1. OB 未装载........................................................................................................................35 2.14.2. 调用中断程序引起的故障................................................................................................36

项目一致性检查(数据块,FB, FC更新)..................................................36 例子程序的使用事项......................................................................................37 重要声明:......................................................................................................38

2.15. 2.16. 2.17.

3. 附录-推荐网址................................................................................................38

3.1.

西门子自动化与驱动产品的在线技术支持..................................................38

重要提示:本文为技术交流文档,不能作为订货、选型等重要事宜的唯一依据,建议用户参考 Siemens 的标准产品样本和技术手册进行产品的选型和订货。

1. 前言

学习任何一种编程语言都不是一件简单的事情,不可能一朝一夕完成。任何一种编程语言都遍布陷阱(尽管各种编程语言的发明人尽量避免这种情况的出现)。作为编程人员,必须要清楚程序的来龙去脉,否则程序的执行结果就有可能与编写人员的初衷大相径庭,甚至造成不必要的财产损失和人身伤害。

本文不会讲述STEP7软件及编程语言的详细使用方法,关于这部分内容请用户参考相关手册。 在本文中,笔者将会列举一些STEP7编程常见的错误,其中一些例子来自工程实例。笔者并未将其直接用于本书,而是将其精简成易于理解,易于发现错误的例子(删除工艺因素及无关逻辑程序干扰)。希望通过对这些例子的讲解,用户能够减少在编程方面的错误,能够快速地在纷繁复杂的程序中查找出错误所在,加快开发项目的进度。

相关手册地址连接:

S7-300和S7- 400的梯形图 (LAD) 编程

S7-300 和S7-400 的语句表 (STL) 编程

S7-300 和S7-400 的 功能块图 (FBD) 编程

使用STEP 7 V5.3 编程

2. STEP7编程常见的错误例子

2.1. 简单错误

下面列举三个简单的STEP7编程常见的错误例子,这三种错误是非常常见的,但却非常容易被忽视:

2.1.1. 地址超范围

A =

M3000.0 Q0.0

上面这两条语句相当简单,语法没有任何错误,可以下载到部分S7-400系列CPU 当中,但是,如果用户试图将这两条语句下载到CPU315-2DP 当中,那将无法完成,因为CPU315-2DP 不支持M3000.0这么大的地址空间。

2.1.2. 对指令不熟悉

A M 0.0 FP M 0.0 = Q 0.1

同样以上三条语句是没有任何语法错误的,本意是当M0.0由 0 变为 1 的上升沿位置时,Q0.1 导通一次。但由于FP 指令是用了与A 指令相同的地址M0.0, 所以此处Q0.1 的状态是不会有任何变化的。

2.1.3. 地址重叠

A

=

M0.0 M11.0

………………… L T

0 MW10

与前面的两个例子一样,这四条语句是没有语法错误的。但如果这些语句分布在程序的不同位置,由于MW10包括了M11.0,用户就要考虑对M11.0的“写操作”与对MW10 的“写操作”是否存在逻辑冲突的问题了。

通过以上三个简单的例子,可以得出如下结论:即使再简单的程序,也存在着出现编程错误的可能性。所以在后续的章节中,将单独列举一些STEP7 编程中常见的错误。

2.2. 循环程序错误

用户在编程过程中,循环程序的使用是非常常见的。下面例子的初衷为实现一个500次的循环操作(Network2 添加的用户程序可以被执行500次)。但是由于没有考虑下述的几个因素,使得程序不能正确执行。

图2-1循环程序示例(a)

2.2.1. 循环程序初始化

首先,程序中没有MW0初始化的语句,一旦循环程序被多次调用将发生错误,所以应在LOOP 标号前应增加如下语句:

L T

0 MW0

将编程环境切换为STL 格式后,可得到如下程序:

图2-2循环程序示例(b)

2.2.2. 循环程序执行时间

上图为比较常见的循环程序例子,在network3处添加了用户程序后,是不是所有的工作就完成了呢?答案是否定的,我们还需要考虑CPU 的扫描执行周期问题。假设network3处所添加的程序为一个或数个子程序,这些程序执行时需要的时间为A, 用户其它程序执行需要的时间为B。

那么,A*500+B的时间总和一定要小于下图中的Scan cycle monitoring time[ms],否则,就有可能由于程序扫描时间超出了CPU 的监控时间而导致CPU 停机,用户应当将硬件组态中的程序扫描监控时间更改为大于此时间的数值。

图2-3 CPU扫描监控时间

2.2.3. 循环程序累加控制

这里之所以将循环程序以STL 格式显示,目的在于提示另一个在编写循环程序经常出现的错误。有些编程人员可能会使用MB0 代替上述程序中的MW0 ,或者不使用加法指令而使用INC 指令。由于这两种用法都是字节操作,如果使用MB0,由于MB0最大为255,永远也不会大于500,所以程序会出现死循环的情况。而MW0作为有符号整数可以最大支持到+32767,包括了0-500的计数范围,所以不会出现错误。因此,在下文中将强调数据类型的匹配的问题。

2.3. 数据类型匹配不严谨

对于任何一门计算机语言,都存在着数据类型匹配问题,作为一名有着良好编程习惯的编程人员应当严格遵循的数据匹配规则。

2.3.1. STL指令数据类型匹配

由于STL 相对于LAD 对于数据类型匹配检查并不严格,所以要求用户在在使用STL 编程的时候尤其要注意到这一点。

特别提示:无论是否会获得正确结果,下列程序是不应当出现在程序当中的:

L L

1.000000e+000 +R

T MD 0

特别提示:而如下的程序的细微区别也应当引起注意:

L L L L

10 L#10 MB10 MW10

这些操作后的执行结果可以参考L 指令的STEP

帮助文件及数据类型说明。

图2-4 L指令操作结果

注意:装载不同的数据类型,累加器ACCU1中的内容改写情况是不同的,例如装载MW10时,ACCU1的高16位将作添加0的处理。

2.3.2. 数据类型匹配与浮点数运算

在流量累计编程中经常会遇到实数加法问题,实数加法运算的注意事项也应当引起编程人员的重视,请看下例程序(假设其在OB35中被调用,目的为每隔一定时间间隔就累计一次流量)

L L

MD0 MD4 +R T

MD 0

//累计流量存储值 //流量瞬时值

以上的程序是否存在问题?很多人会认为没有问题,但实际情况是此程序在运行一段时间后就将出现错误。此程序在运行之初是正常的,因为累计流量初始值及流量瞬时值都为一个很小的浮点数,两数相加后,结果正确。但是当一段时间后,累计流量的数值逐渐增大,当它与瞬时流量的数值相差很远的时候,两者执行加法操作后,瞬时流量的数值将被忽略掉(如9999990.0与0.2做加法操作)。其实具备计算机常识的人都应当清楚这一点,这是由于浮点数的存储机制造成

的,是所有计算机方面编程都需要考虑的问题。这个问题可以通过使用二次累加或多次累加的方法来解决。

特别提示:避免数量级相差太多的浮点数之间进行运算。

2.3.3. 浮点数运算与比较指令

用户程序中很多情况下会对浮点数运算的结果与预先设定值进行比较,例如下面的程序比较MD 与10.0是否相等,如果相等的输出Q0.0 为1。 L MD 0 L 1.000000e+001 ==R

= Q 0.0 此程序存在两个问题:

• 由于浮点数运算存在误差,所以MD0有可能非常接近于10.0,但总是不等于10.0, (例如

9.999999e+000)

• 如果MD0在10.0附近数值波动,有可能造成输出Q0.0 输出频繁波动,造成输出点损坏 因此,用户应当使用一个范围比较的方法代替等于数值比较的方法(例如 9.9

L MD 0 L 9.900000e+000 >R ) A(

L MD 0 L 1.010000e+001

= Q 0.0

2.4. 语句执行先后顺序

由于PLC 扫描程序是由头至尾依次执行的,所以编程人员必须重视程序语句执行顺序对逻辑

结果的影响。对于下面的程序相信大家都会判断MW0中最后的执行结果。但是,随着程序的复杂性的增加,以及其它干扰因素的出现,对于语句执行先后顺序引起的错误,容易被编程人员所忽视。

L T

0 MW0

…… (其它省略的程序段,此时MW0的数值为0) L T

10 MW0

…… (其它省略的程序段,此时MW0的数值为10) L

20 MW0

…… (其它省略的程序段,此时MW0的数值为20)

T

对于下面程序的例子,大多数人会认为是正确的,但实际监控结果却不是这样。 程序原目的:

T1定时器每秒导通一次,C1及C3会每隔一秒钟,进行一次加1 操作。 故障现象:

实际监控结果:C1工作正常,C3并未继续计数。

图2-5程序语句顺序错误

将上面的程序更改为STL 格式,可以更清楚看出语句在程序中执行的顺序。

AN = A

M 0.0 L 0.0 L 0.0

//

AN L SD CU A AN CU

T 1 S5T#1S T 1 C 1

//此处如果T1定时到,则会重新计时, //C1得到了上升沿,计数

L 0.0 //此处的语句将开始新的逻辑, T 1 C 3

//无法将RLO 的0 至 1 的变化送至C3 //C3无法得到了上升沿,不计数

正确的程序反而更加精减,C1与C3

并列出现:

图2-6程序语句顺序正确

正确的程序在STL 格式下的程序为: AN M0.0 AN T1 L S5T#1S SD T1 CU C1 CU C3

特别提示:由于LAD 对程序的语法规则检查是自动完成的,所以编程人员可能在使用时更随意一些,但没有语法规则错误的程序并不一定会按照编程人员的本意来执行。

2.5. 上升(下降)沿不工作

上升(下降)沿不工作也是一种常见的错误,尽管手册中“P”或“N”指令允许的数据类型为:I, Q, M, L, D。但如果没有特殊目的,仅建议使用M 及DB 数据类型。如下图:

图2-7上升(下降)沿指令使用正确

西门子“P”指令要求使用与前面指令不相同的地址,下图为错误用法:

图2-8上升(下降)沿指令使用错误1

“P” 指令要避免使用其它程序有写操作的地址,下图为错误用法:

图2-9上升(下降)沿指令使用错误2

“P” 指令不应使用临时变量作为存储地址(临时变量会随着系统堆栈变化,这一点将会在后续章节详细讲述)

,下图为错误用法:

图2-10上升(下降)沿指令使用错误3

2.6. 定时器不工作

有些用户在使用定时器编程后,发现定时器并没有按照自己的意图去计时工作,出现了不计时错误,进而去怀疑硬件是否故障,CPU是否工作正常等等,浪费了大量的时间和精力。实际上这是由于用户对定时器特性不了解所造成的误解。下面的例子将说明这个问题。 程序原目的:

I4.2的上升沿触发T50, T60的定时,并在T60定时结束后,复位M12.0 故障现象:

I4.2可以触发T50, T60的定时,但有时即使I4.2再次将M12.0置位为 1 ,T50不计时。现象见

下图:

图2-11定时器使用错误

故障分析:

首先要明确这个故障现象既不是硬件故障,也不是语句错误所引起的,而是对定时器使用不正确

引起的故障。

现在我们分析此故障是如何产生的:

1. 某个扫描周期,

a. I4.2的上升沿置位M12.0,I4.2恢复为0

2. 数个扫描周期后, 扫描周期N

a. 当T60计时到时,Network2中M12.0被复位(注意是在SD T50语句的后面),此

扫描周期末M12.0由1 变为了0 b. Network3中T50,T60被复位

3. 扫描周期N+1

a. 如果此时I4.2恰恰出现上升沿置,尽管M12.0在上个扫描周期曾经变为0,但在

本扫描周期开始就变为了1,定时器T50在上个扫描周期接受到的M12.0状态为1,定时器T50在本扫描周期接受到的M12.0状态也为1所以T50将不会工作。

定时器此处读输入

输入信号变化

定时器此处读输入

图2-12定时器错误分析

定时器此处读输入

输入信号变化

定时器此处读输入

图2-13定时器正确使用示意

在上图中,定时器在扫描周期N 与扫描周期N+1之间正确地接收到了上升沿的变化,所以能够正常工作。 故障总结:

定时器计时需要正确地接收到输入端上升沿的变化,如果没有严格遵守这一逻辑顺序,常见的故障现象为定时器不计时工作。这种故障现象可能很隐蔽,本例的原始程序在实际工作中几天才会出现一次故障现象。由于原始程序包括大量的附加逻辑,子程序,语句位置也比较分散,所以排除此故障现象所用的时间超过了3天。

特别提示:此程序改正的方法非常多,例如在置位M12.0指令前增加一些限制条件,用户可以自己尝试。

2.7. 定时器的定时与程序扫描周期

在S7系列CPU 中,定时器的最小时基为10毫秒。也就是说,S7系列CPU 的最小定时时间为10毫秒。如果用户程序代码量比较大,程序扫描周期过了10毫秒,可能会出现如下情况:尽管定时时间已经到达,但CPU 还没有执行到相关的程序逻辑。

特别提示:当用户程序中需要非常短的定时功能时,需要考虑程序扫描周期对定时器状态读取的影响。由于CPU 中的定时中断是由硬件来保证的,并且有高于OB1的优先级, 所以在这种情况下,建议用户使用定时中断的功能来替代定时器的功能。

2.8. 软定时器的使用

有些时候,在编程中会遇到CPU 提供的硬件定时器不够使用的问题,这时可以使用系统提供的软定时器,例如SFB4(TON)。此功能块需要一个背景数据块,

特别提示:使用SFB4需要注意的一个问题,CPU启动后的软定时器复位问题。

由于SFB 的定时、计时值是存在DB 中的,由于当CPU 断电或停机后,DB中的数据是保持的。如果定时器计时到在停机前已经计时,那么当CPU 重新运行后(定时器输入端仍然为1的情况),定时器会在原来计时位置继续计时。为了避免这种情况的出现,可以在OB100中添加如下语句来初始化SFB4的背景数据块(参数PT 应当为T#0MS)。具体信息可以参考STEP7的在线帮助。

软定时器初始化程序: CALL “TON”, DB1 IN: = PT: =T#0MS Q: = ET: = NOP 0

2.9. 计数器不工作

计数器使用的常见故障与定时器非常相似,可以参考定时器的章节

软计数器的使用注意事项类似于软定时器的使用,具体信息可以参考STEP7的在线帮助。

2.10. 数据块错误

对于S7-300/400系列CPU 而言,数据块是其重要的系统资源之一。这些数据块在项目的初始阶段并不存在,编程人员自行定义后并下载至CPU 后,即可使用。正是由于这样的特点,数据块在使用当中存在着一些注意事项,如果忽视这些注意事项,则会引起编程错误。

2.10.1. 打开数据块错误

由于数据块是用户自己定义的,所以在下载至CPU 之前,CPU中是不存在着数据块的。如果用户程序中引用的数据块在CPU 中并不存在,将导致编程错误发生。这种情况可以通过用户对自己程序的了解来避免,即不调用不存在的数据块,也可以通过使用SFC24“TEST_DB”来检测数据块是否存在,再决定是否调用它。

2.10.2. 数据块寻址长度错误

由于数据块的长度或大小也是用户自己定义的,所以用户程序中对数据块的引用不能超出数据块所定义的范围。例如:在DB1中只定义了10个BYTE 数据类型,那么程序中对DB1.DBB10(第11个BYTE)的访问将导致编程错误发生。这种情况可以通过用户对自己程序的了解来避免,即不引用不存在的数据地址,也可以通过使用SFC24“TEST_DB”来检测数据块的大小,再决定如何调用它。

2.10.3. 数据块寻址不严谨错误

有些类型的PLC 对于用户自定义的存储区域的寻址方式是有一定限制的,例如对于整数类型的数据地址是不支持位寻址方式的。而西门子PLC 由于其数据块具有绝对的数据地址,所以可以实现对不同的数据类型地址使用各种方式寻址。例如:DB1.DBW0被定义为一个整数数据类型,但程序中可以对DB1.DBX0.0-DB1.DBX1.7进行位寻址。西门子这种灵活强大的寻址功能给用户提供了非常多的选择,很多算法及数据转换功能可以非常轻松的实现,但与此同时,用户务必要注意如果不遵循数据类型进行寻址,是否会对数据内容的造成影响。

2.10.4. 数据块寄存器使用错误

西门子S7-300/400系列CPU 拥有两个数据块寄存器,它们保存着当前打开的数据块编号:

DB 寄存器保存着打开的共享数据块编号 DI 寄存器保存着打开的背景数据块编号

特别提示:DI 寄存器主要用于FB 引用背景数据块,但也常用于程序中同时打开两个数据块的操作。 如下图的程序即完成了将DB1.DBW0(16#2222)传送到DB4.DBW0中的工作。用户请注意程序中的格式(如T DIW0),详细信息请参考STEP7

编程手册中的寻址方式部分。

图2-14同时打开两个数据块

上述例子也可以使用如下语句直接完成:

图2-15两个数据块之间数据传送

那么上述两者有何区别呢?从两图中的对比可以看出:

也就是说,对于数据块中地址的完整引用,将影响到DB 寄存器的内容。那么对于下面的程序,我们将很容易发现其中的错误。 程序原目的:

将3333传送至DB1.DBW0 将4444传送至

DB1.DBW2 L T L

DBW0 DIW0

//不改变DB 寄存器的内容 //不改变DI 寄存器的内容 //改变DB 寄存器的内容

//改变DB 寄存器的内容,相当于增加了 OPN DB4的指令。

DB1.DBW0

T DB4.DBW0

图2-16错误传送程序

故障分析:

由于程序的Network5中使用了对于DB4.DBW0的比较指令,此指令改变了DB 寄存器的内容,因而我们将得到如下的错误结果,DB1.DBW2并没有得到正确数值,正确数值4444被错误地送到了

DB4.DBW2

中:

图2-17错误传送程序结果

2.10.5. 改变DB 寄存器和地址寄存器AR1操作

那么在STEP7编程中,都有哪些情况会引起DB 寄存器中的内容改变呢?下面列出了可能引起

DB 寄存器或 AR1 内容改变的一些操作:

使用下述复杂语言结构会导致 DB 寄存器 和地址寄存器AR1内容(关于AR1的使用将在后续

章节中讲解)改变:

1. 以绝对地址对DB 块的访问 (如:DB20.DBW10)

2. FB 的多重背景调用

3. STRUCT 数据类型作为 FC 或 FB 里的地址

4. STRUCT 数据类型作为 FC 或 FB 的实参

如果用户在编程时使用了上面提到的选项,则必须手动恢复寄存器的内容,否则可能产生错误。

关于这个问题的细节可以在 STEP 7 帮助中"Avoiding errors when calling modules" 项下找到。

2.10.6. STRUCT数据类型作为 FC 或 FB 里的地址

下图的例子显示了如下两种情况对于DB 寄存器的影响情况。

1. FB 的多重背景调用,

2. STRUCT 数据类型作为 FC 或 FB 里的地址

图2-18程序对DB 寄存器的影响

程序执行过程:

1. 在执行 OPN DB1 后, DB寄存器内容为1

2. 在调用FB2,背景数据块为DB10后,DB寄存器内容为10,DB寄存器被改变

3. 在引用“stuct_db”.my_struct.aa后,DB寄存器内容为11,DB寄存器被改变

注意:FB2的输入参数(BOOL类型)DB5.DBX10.0,虽然此种格式为数据块的完整引用方式,

但作为输入参数类型使用时,并不改变此处DB 寄存器的值

2.10.7. STRUCT 数据类型作为 FC 或 FB 的实参被调用

下图的例子显示了如下情况对于DB 寄存器的影响情况:

STRUCT 数据类型作为 FC 或 FB 里的实参

图2-19访问STRUCT 对DB 寄存器的影响

程序执行过程:

1. 在FC9中调用FC10,并将形参“stuct_db”.my_struct 赋给输入参数FC_IN

2. 在FC10中,FC_IN为STRUCT 数据类型

3. 在FC10中执行 OPN DB1 后, DB寄存器内容为1

4. 引用FC_IN.aa后,DB寄存器内容为11,DB寄存器内容被改变

2.10.8. 通常情况,DB寄存器不受影响

在通常情况下,DB 寄存器是不受影响的,下图为FC9中调用FC11及SFC20后,DB 寄存器不

受影响。

图2-20对DB 寄存器无影响的程序

程序执行过程:

1. 在FC9中执行 OPN DB1 后, DB寄存器内容为1

2. 在FC9中调用FC11及SFC20

3. 在FC11中,引用了地址DB5.DBX0.0

4. 在SFC20参数中使用了ANY 数据类型

5. FC9中,调用FC11,SFC20结束后,DB寄存器内容为1,未受影响

2.10.9. 数据块的完整引用方式的优缺点

至此,也许有的用户会对数据块的完整引用方式存在疑问,既然此种引用方式可以明确当前的

数据寄存器,并且编程简单,是不是可以在程序中全部使用数据块完整引用方式呢?答案当然是

否定的,原因如下:

1. 相对于数据块的完整引用方式,数据块简略方式寻址提供了更灵活的编程方式及功能(特

别是关于指针寻址方式)

2. 数据块完整寻址方式每次都对DB 寄存器进行操作,增加了程序执行时间,不适用于大数

据量编程方式

特别提示:当程序涉及到快速,多次对数据访问时,可以使用M 存储区代替DB 数据区,这样可以

得到更快的程序执行时间,但要注意CPU 中的M 存储区资源要远少于DB 数据区资源,要节约使用。

(对于31x 系列CPU,执行一次 T DBW0指令需要约1.6μS, 而执行一次 T MW0指令仅需要约0.2

μS)

特别提示:上面的例子告诉我们,尽管对于数据块完整地址引用会改变DB 寄存器中的内容,但通

过编程者的重视,这个错误是完全可以避免的。

2.11. 在FC 的使用当中常见的错误

2.11.1. ENO的误解

对于初学者来说,容易在ENO 的使用上出错误,由于不清楚ENO 来龙去脉,经常认为只要调

用FC 是无条件的,那么ENO 也是永远导通的,实则不然。下图中的例子将说明这个问题。

程序原目的:进行模拟量转换,并无条件地将MD10的数值传送至

MD14。

图2-21 ENO的使用

在图中可以看出,当FC105的输入端PIW256在正常范围内的时候,MOVE 指令被执行(ENO=EN),

当PIW256超出了上限值后,MOVE指令不再被执行(ENO≠EN)。此故障还是比较隐蔽的,因为大部

分情况下,输入可能都处于正常范围。

故障分析:在STEP7的LAD 编程手册中有对EN/ENO机制的详细描述,这里不再赘述。仅列出主要

部分内容:

ENO 的值取决于公式:ENO = EN 与非 (error )

• 如果程序调用没有错误(error = 0),则ENO = EN。

• 如果程序调用有错误(error = 1),则ENO = 0。

EN/ENO 机制用于:

• 数学运算指令

• 传输及转换指令

• 移位及循环移位指令

• 块调用

EN/ENO 机制不能用于:

• 比较指令

• 计数器

• 定时器

如果用户要创建自己在FBD 或LAD 中调用的块,那么必须确保退出块时,置位BR 位。这并不

是一个自动处理过程。不能使用BR 作为存储位,因为EN/ENO机制会不断重写BR 位。作为代替,

可使用一个临时变量(例如 #error)来保存发生的所有错误,并用0初始化此变量。在块内部程

序中,如果用户某处程序执行为错误状态,则可以将此变量置1。并且在块结尾编写以下程序段:

end: AN error

SAVE

确保在任何情况下都处理本程序段,这表示禁止在块内使用BEC,并禁止跳过本程序段。

2.11.2. 停止对FC 调用后引起的故障:

下面的程序非常简单,看似正确,但存在着一定隐患。

程序原目的:

在OB1中当M0.0为1 的时候,调用FC13

在OB1中当M0.0为01 的时候,不调用FC13

FC13中包含简单逻辑及定时器的使用

图2-22普通FC 程序内容举例

故障现象:

假设某个时刻,M0.0,M0.1,M2.0都为1 ,并且维持数值1的时间超过了10秒,那么Q0.1,M2.1

也都会为 1。

假设此时M0.0 变为0,FC13

不再被调用,结果如图:

图2-23普通FC 程序执行结果

对于初学者来说,容易忽视的问题为:M0.0 变为0后,FC13中的Q,M,会保持原来状态,T,C,

会继续工作,如果M0.0再次变为1,并且此时M2.0也为1,由于定时器保持着计时到达的状态,

M2.1会立刻变为1,这种情况可能会导致某些在FC 被调用后必须延时执行的逻辑立刻被执行。在

实际应用中,如此逻辑为某个设备启动信号,那么这个设备可能会跳过延时或保护逻辑而马上运

行! 对于编程人员如果能够确保上述现象不构成对人身及财产的伤害,则可以不采取措施,否则

应当加入限制程序,例如下面的复位语句。

图2-24 FC程序复位举例

2.11.3. FC中临时变量的使用:

很多初学者容易将FC 及FB 相混淆,认为FB 仅仅是比FC 多了一个背景数据块,这种认识是非

常危险的。在STEP7的关于FC 的描述是这样的:

FC 是一个没有存储空间的逻辑块。FC的临时变量存储在本地数据堆栈中,这些数据在FC 执

行完毕后将会丢失。为了永久的保存数据,FC可以使用共享数据块。

由于FC 没有自己的存储空间,所以必须指定实参给它的参数(这就是为什么FC 的输入输出

管脚必须填写参数的原因)。FC的临时变量(位于本地数据堆栈中)是无法指定初始值的(由于本

地数据堆栈是由系统自动动态使用的)。为了更形象的说明这一点,我们来看下面的例子,此例子

对L 堆栈在程序调用时的分配进行了详细的讲解:

L 堆栈永远以地址“0”开始。在 L 堆栈中,会为每个FC 提供一定地址空间,作为存放每个

块所拥有的固有数据或局部数据。当某个块终止时,那么它的空间随之也被重新释放出来。 指针

总是指向当前打开块的第一个字节。 运行等级 L 堆栈中指针

的字节数

调用 OB1 (带有 20 个字节的系统固有数据和局部数据的10个附加

字节) 30

调用 FC1 (带有 30 个字节的局部数据)

30 个字节 (OB1) + 30 个字节 (FC1)

调用 FC20 (带有 20 个字节的局部数据)

60 个字节 (OB1 + FC1) +20 个字节 FC10

调用 FC21 (带有 20 个字节的局部数据)

60 个字节 (OB1 + FC1) +20 个字节 FC11

调用 FC2 (带有 50 个字节的局部数据)

30 个字节 (OB1) +50 个字节 (FC2)

调用 FC30 (带有 10 个字节的局部数据)

80 个字节 (OB1 + FC2) +10 个字节 FC20

表2-1 L堆栈在程序执行过程当中的动态分配 0 30 60 60 30 80 60 80 80 80 90

由上面的例子可以看出:对于FC20曾经使用过的系统中L 堆栈60-80区间(FC20中地址范围

为LB0-LB19)在FC20调用结束后,被提供给FC21使用(FC21中地址范围同样为LB0-LB19)。

对于FC 的临时变量认识不清晰,用户在对临时变量的使用当中,也经常会出现一些错误,下

面将使用一个例子非常直观地说明上面的问题

程序原目的:

在OB1在程序中调用FC20后立即调用FC21

FC20中将20赋值给临时变量FC20_TEMP1,将21赋值给临时变量FC20_TEMP2

FC21中将FC21_TEMP1,FC21_TEMP2相加

程序分析:我们发现FC20中的临时变量曾经出现的数值(20,21)被FC21中的临时变量FC21_TEMP1,

FC21_TEMP2得到了,如果直接使用这两个临时变量进行加法操作,可以得到结果41。对于编程人

员来说,临时变量必须要在所在程序段中赋值,而后使用。用户对此例中的FC21_TEMP1, FC21_TEMP2

必须先做清零处理,否则其在使用前即可能拥有数值。

图2-25不同FC 程序临时变量之间的影响

结论:对于FC 或FB 中的临时变量,不要希望将本次调用的数值可以存储在里面以供下次程序调

用使用,因为这些临时变量所使用的L 堆栈空间在FC 或FB 调用结束就释放给系统了,其它后续

程序可以任意使用。所以下列用法都是错误的:

• 将临时变量用于上升/下降沿指令

• 将临时变量用于自保持逻辑

• 临时变量未在所在程序段中赋值,直接使用

警告:不要试图利用L 堆栈的这种特点进行功能或功能块之间的数据传递。程序逻辑改变,语句

执行顺序改变,临时数据区长度定义改变,中断程序都会影响L 堆栈中的数据存储顺序。

2.11.4. FC输出处理

对于FC 的使用,另一个的常见的错误是对输出的错误处理:导致这个错误的原因还是对FC 认

识的不清楚。再次强调:相比较于FB, FC 是一个没有存储空间的逻辑块。如果没有数据被写至FC

的OUT 参数,FC将会输出一个随机值!对于FB, 因为其可以使用背景数据块来存储OUT 参数的数

值,即使某次调用没有对OUT 参数进行写操作,OUT参数依然可以输出上一次的旧值。

下面的程序将说明这一点:

程序原本目的:

在OB1中调两次FC22,将MW0,MW2作为输入参数,DB1.DBX0.0,DB1.DBX0.1分别作为输出参数

赋给FC22

FC22检测当输入大于10时,置位输出为1 FC22检测当输入小于-10时,复位输出为0 FC22的输出的动作死区为-10至10

此程序乍看是没有错误的,但是,如果OB1中调用了两次FC22,而且MW2位于死区(-10 至

10)之间时,MW0的数值改变将不仅仅改变DB1.DBX0.0的状态,同时会影响输出DB1.DBX0.1的数

值。

图2-26 FC程序输出编程错误举例

故障分析:在上面的例子,OB1中调用了两次FC22,而且MW2位于死区(-10 至10)之间时,其

输出在FC22没有被赋值,DB1.DBX0.1正常情况下不应当改变数值。但是本例中,MW0的数值改变

将不仅仅改变DB1.DBX0.0的状态,同时会影响输出DB1.DBX0.1

的数值。如下图。

图2-27 FC程序输出编程错误结果

结论:

对于FC 的输出变量,必须要在每次执行FC 时赋给一个确定的值,否则输出有可能会输出一个

随机值。下列用法都是错误的:

• 将输出变量用于上升/下降沿指令

• 将输出变量用于自保持逻辑

• 输出变量未在所在程序段中赋值

警告:不要因为在FC 编程中遇到没有对输出赋值,而程序执行正确,就忽略了对FC 输出编程的

注意事项,否则将承担这个错误有可能带来的风险。

建议:

• 用IN/OUT变量代替OUTPUT 变量

• 不论何时调用块,FC中的OUT 参数都必须被赋值

2.12. 调用FB 引起错误

2.12.1. FB的输出处理

由于FB 有自己的背景数据块,因此其除了临时变量外,其所有过程数据都可以保存在自己的

背景数据块内。因此对于FB 的使用,只是输出变量的处理与FC 不同,不需要每次都赋给确定的

数值。但其它前者FC 时用的注意事项都适用于FB。

2.12.2. 在FB 中使用AR2

另外由于在FB 中,系统将会使用AR2用于背景数据块的访问,所以如果在FB 中使用了AR2 ,

务必要注意其用法。下面的例子将说明这一点。

程序原目的:

同时对DB12及DB13 中的数据进行操作,将DB12中的多个数据进行加1操作复制到DB13中(本例

仅为了举例说明问题,虽然未涉及复杂算法,也使用了间接寻址) :

DB13.DBB0=DBW12.DBB0+1

DB13.DBB1=DBW12.DBB1+1

DB13.DBB2=DBW12.DBB2+1

下面的程序可以放在FC 中执行,但不可放在FB 中执行。

图2-28 AR2应用于FC

发现此错误很容易,因为当程序存盘后会变成如下状态,其中涉及到AR2的数据块访问被替换

为了背景数据块的变量(图中为输入参数FB1_IN)

图2-29 AR2应用于FB

2.13. 关于FC/FB使用的总结:

对于同时要打开两个数据块,并且涉及间接寻址的程序,推荐使用FC 实现

并且在FC 程序开始增加如下语句存储数据块寄存器及地址寄存器的内容:

L DBNO

T #DBNO_TEMP //用户自定义的WORD 临时变量,存储数据块寄存器数值

L DINO

T #DINO_TEMP //用户自定义的WORD 临时变量,存储数据块寄存器数值

TAR1

T #AR1_TEMP

TAR2

T #AR2_TEMP //用户自定义的DWORD 临时变量,存储地址寄存器数值 //用户自定义的DWORD 临时变量,存储地址寄存器数值

//在以上程序之后,此处可以添加用户自身程序。

在FC 程序结束位置增加如下语句恢复数据块寄存器及地址寄存器的内容:

OPN DB [#DBNO_TEMP]

OPN DI [#DINO_TEMP]

L #AR1_TEMP

LAR1

L #AR2_TEMP

LAR2

警告:以上建议仅代表笔者个人观点,例子程序也是免费的。任何用户都可以免费复制或传播此

程序例子。程序的作者或拥有者对此程序不承担任何功能性或兼容性的责任。此程序的使用者风

险自负

2.14. OB 块引起错误

2.14.1. OB 未装载

在STEP7程序中,所有的用户程序都将在组织块中被调用。而针对于不同事件,CPU将会调用

不同的组织块,当某事件发生时,如果CPU 中没有下载相对应的组织块,CPU 将进入STOP 状态(例

如DP 从站通信故障时,CPU中如果没有OB86,CPU 将进入STOP 状态)。

2.14.2. 调用中断程序引起的故障

调用中断程序引起的故障并不多见,但也应当引起足够的重视,否则也会降低项目程序的可靠性。

1. OB35的使用:

由于定时中断程序具有稳定的执行时间间隔特性,所以OB35也许是除去OB1之外,人们

最经常使用的组织块了。但是如果其执行间隔如果被修改得非常短(例如1毫秒),那么就必须

考虑OB35中的程序是否能够在1毫秒之内执行完毕。如果OB35的执行时间超过了1毫秒,这

时OB35又再次被系统触发,系统将会出错。

2. OB40的使用:

类似的情况也会在OB40中出现,例如某个通道触发了OB40硬件中断,在OB40尚未执行

完毕之前,此通道如果再次触发了硬件中断,此中断将会丢失,不被系统响应。但是,如果某

个通道触发了OB40硬件中断,在OB40尚未执行完毕之前,其它通道触发了硬件中断,此中断

不会丢失,将被系统响应。此情况也应引起注意。

2.15. 项目一致性检查(数据块,FB, FC更新)

由于STEP7的程序是由各种类型的块组成的,用户可以分别对这些块进行编辑或修改,并可

以单独对某个块进行下载操作,而不影响其它块。在使用这种方便灵活的操作的同时,用户也务

必要注意其带来的风险。

例如:

在OB1中调用FC1,当FC1的输入/输出参数作出修改后,如果仅仅下载FC1,而不下载OB1,

那么CPU 将会出现编程错误。所以当用户修改FB/FC, DB, UDT以后,应当对涉及到这些调用的程

序进行更新,避免发生错误。STEP7对此提供了一致性检查的功能,可以在选中程序的BLOCK 目录

后,由菜单的Edit-Check Block Consistency调出此功能。

图2-30块的一致性检查界面

在STEP7程序中,如果出现FB/FC的参数改变/时间标签不一致的情况,所调用的FB/FC会以

红色显示。此时右键点击次FB/FC, 在菜单中将会出现Update Block Call菜单,使用此功能后,

调用程序将自动更新FB/FC的调用。使用此种方式,比手动删除此FB/FC,再手动重新输入各种参

数要方便的多。

图2-31块调用的更新

2.16. 例子程序的使用事项

用户在附件中的例子程序在使用中需要遵循以下注意事项:

• 示例代码大部分编写在FC/FB当中,使用OB1调用

• 当用户希望验证某个FC/FB的功能时,首先应当将相关的FC/FB/DB下载到PLC/PLCSIM当

中,并在OB1中将调用此FC/FB的注释符号删除,下载OB1,此FC/FB即被调用

• 尽量避免同时验证多个FC/FB的功能,因为这些FC/FB可能存在着逻辑上的冲突

• 对于不需要验证功能的FC/FB,在OB1中应当保持其作为注释出现的状态

本文附件程序使用的说明:

FC1:循环程序示例

FC2:浮点数运算程序

FC3:程序执行顺序例子

FC4:上升延指令

FC6:定时器触发例子

FC7:同时操作两个数据块的循环程序例子

FC8:数据块寄存器例子1

FC9:数据块寄存器例子2

FC10:数据块寄存器例子3

FC11:数据块寄存器例子4

FC12:ENO使用例子

FC13:停止调用FC 后引起故障的例子

FC20:FC中临时变量使用的例子1

FC21:FC中临时变量使用的例子2

FC22:FC输出使用的的例子

FC23:系统变量保存的例子

FB1: 在FB 使用AR2的例子

2.17. 重要声明:

由于例子是免费的,任何用户可以免费复制或传播此程序例子。程序的作者对此程序

不承担任何功能性或兼容性的责任,使用者风险自负。

西门子不提供此程序例子的错误更改或者热线支持。

3. 附录-推荐网址

3.1. 西门子自动化与驱动产品的在线技术支持

AS

西门子(中国)有限公司

工业自动化与驱动技术集团 客户服务与支持中心

网站首页:http://www.ad.siemens.com.cn/Service/

AS 下载中心:

专家推荐精品文档:http://www.ad.siemens.com.cn/Service/recommend.asp

“找答案”AS 版区:http://www.ad.siemens.com.cn/service/answer/category.asp?cid=1027

版权 西门子(中国)有限公司2001-2008 版权保留

复制、传播或者使用该文件或文件内容必须经过权利人书面明确同意。侵权者将承担权利人的全

部损失。权利人保留一切权利,包括复制、发行,以及改编、汇编的权利。

西门子(中国)有限公司


相关文章

  • 石油设计工作试用期自我工作总结
  • 石油设计工作试用期自我工作总结 每个公司都在寻找那些能够“送信给加西亚”的人,目前,我还不是这个人,因为工艺知识的欠缺和技术技能的不完善,但是我有敬业的精神和努力的实践,我相信,不久的将来,我一定可以完成那样的任务。 以下以时间为序,对两个月试用期的工作进行简单的回顾总结: 4月10日,我到公司报到 ...

  • 20XX年金工实习总结报告
  •   听说金工实习已久矣,大概在十几个月以前就听说了它的尊姓大名,但只闻其名,未谋其面。那时金工实习对于我来说就像蒙着面纱的女郎,充满了神秘、充满了好奇、充满了向往。满是期盼的等待着金工实习的到来。有人说金工实习是很有趣的,很好玩的,也有人说它是无聊的,枯燥的。但至于它到底是怎样的,我只能在期待中慢慢 ...

  • PLC自动化专业实习报告范文
  • 来上海有一个月了,每天都在不断接受新知识、开阔新视野可编程控制器是集计算机技术、自动控制技术、通信技术为一体的新型自动控制装置。由于它可通过软件来改变控制过程,而且具有体积小、组装维护方便、编程简单、可靠性高、抗干扰能力强等特点,已广泛应用于工业控制的各个领域,是现代工业自动化三大支柱之一。随着技工 ...

  • plc实训心得体会范文
  • PLC实训总结报告范文 这个学期开设了电气控制与PLC实训的课程,跟以前所有开设的课程有很大的区别,这门课程的灵活性很强,充分发挥自己的潜力;其实学习的过程当中并不一定要学到多少东西,个人觉得开散思维怎样去学习,这才是最重要的,而这门课程恰好体现了这一点。此次的实训以班级为主体,以小组为单位而开展的 ...

  • 金工实训个人小结2篇
  • 我们就迎来了金工实习。为期两周的金工实训让我们学到了很多东西,特别是实践的一些心得,我个人感觉真是终身受益,但随着金属的摩擦声,同学们实习后的欢笑声,金工实训也就即将结束。最让我佩服的就是数控和钳工! 我们的第一个工种就是数控车床的操作。就是通过编程来控制车床进行加工。通过数控车床的操作及编程,我深 ...

  • 金工实习报告--材料高分子丙班 112
  • 金工实习报告 转眼间,为期十天的金工实习结束了.怀着喜悦的心情,我们暂时告别"工厂". 说来惭愧,当我看到铣工时,我还不知道铣工是干什么的.那时我感到很茫然.同时对这新奇的事物产生出好奇. 进入车间后,一台台铁家伙在我们的眼前静静的躺着.一时间,一种莫名的冲动涌上心头.我感到&q ...

  • 20XX年金工实习报告
  •   这个学期刚开学,我们就迎来了为期三周的金工实习。因为上个学期已经实习过一次了,所以这次都做好了准备,不再像上次开始那样那么彷徨。这次金工的内容主要是数控加工技术方面的,有电火花加工、线切割加工、数控车削加工、数控铣削加工、加工中心加工、热处理、快速成型还有plc。每一个工种的学习,都让我受益匪浅 ...

  • 机械类实习报告
  • 一、 毕业实习单位状况概述   汉阳(邯郸)包装机械有限公司是韩国汉阳包装机械株式会社[公司总部在韩国仁川,已有30余年的发展历史在华投资的跨国企业。公司全套引进国外技术与管理,汇集优秀人才,全心致力于热收缩设备的研制开发与生产制造,产品有l式、袖筒式、枕式三大系列,160多个品种.产品科技含量高, ...

  • 维修电工技师自我鉴定
  • 1月19日-20日,来自昆烟生产一线的27位电气维修人员在职教科教室参加了烟机设备维修电工技师鉴定论文答辩,这是昆明卷烟厂开展烟机设备维修电工技师鉴定的最后一项考核内容。由云南省第155国家职业技能鉴定所和云南省烟草专卖局职业技能鉴定站组织的专家组认真评审了每一个考生的论文,并针对论文写作中反映出来 ...

  • plc设计心得体会
  • 和学别的学科一样,在学完plc理论课程后我们做了课程设计,此次设计以分组的方式进行,每组有一个题目.我们做的是机械手臂的plc控制系统.由于平时大家都是学理论,没有过实际开发设计的经验,拿到的时候都不知道怎么做.但通过各方面的查资料并学习.我们基本学会了plc设计的步聚和基本方法.分组工作的方式给了 ...