首页 理论教育 PLC指令FieldRead实现间接寻址及应用场景

PLC指令FieldRead实现间接寻址及应用场景

时间:2023-06-30 理论教育 版权反馈
【摘要】:间接寻址的优点是可以在程序运行期间,通过改变指针的值,动态地修改指令中操作数的地址。此外,存储区可能会无意中被间接寻址的错误值覆盖,从而导致PLC的意外动作。指令FieldRead用来实现间接寻址,其参数INDEX是要读写的数组元素的下标。图4-28 OB1调用FC1的程序、监控表与数据块13.数组元素的间接索引要寻址数组的元素,可以用常量作下标,也可以用DInt数据类型的变量作下标。

PLC指令FieldRead实现间接寻址及应用场景

间接寻址的优点是可以在程序运行期间,通过改变指针的值,动态地修改指令中操作数地址。某发电机在计划发电时每个小时有一个有功功率给定值,从0时开始,这些给定值被依次存放在连续的24个整数中。可以根据读取的PLC的实时时钟的小时值,用间接寻址读取当时的功率给定值。

用循环程序来累加一片连续的地址区中的数值时,每次循环累加一个数值。累加后修改地址指针值,使指针指向下一个地址,为下一次循环的累加运算做好准备。没有间接寻址,就不能编写查表程序和循环程序。

地址指针就像收音机调台的指针,改变指针的位置,指针指向不同的电台。改变地址指针值,指针“指向”不同的地址。

旅客入住酒店时,在前台办完入住手续,酒店就会给旅客一张房卡,房卡上面有房间号,旅客根据房间号使用酒店的房间。修改房卡中的房间号,旅客用同一张房卡就可以入住不同的房间。这里房间相当于要寻址的存储单元,房间号就是地址指针值,房卡就是存放指针的存储单元。

由于是在运行期间通过间接寻址计算操作数地址,因此可能会出现访问错误,而且程序可能会使用错误值来操作。此外,存储区可能会无意中被间接寻址的错误值覆盖,从而导致PLC的意外动作。因此,使用间接寻址时需要格外小心。

1.用FieldRead与FieldWrite指令实现间接寻址

在项目“间接寻址”中生成名为“数据块1”的全局数据块DB1,在DB1中生成名为“数组1”的数组,其数据类型为Array[1..5]ofInt(见图4-25)。

使用指令FieldRead(读取域)和FieldWrite(写入域),可以实现间接寻址。这两条指令在指令列表的文件夹“\移动操作\原有”中。

单击生成的指令框中的“???”,用下拉式列表设置要写入或读取的数据类型为Int(见图4-25)。两条指令的参数MEMBER的实参必须是上述数组的第一个元素“数据块1”.数组1[1]。

指令的输入参数索引值“INDEX”是要读写的数组元素的下标,数据类型为DInt(双整数)。参数“VALUE”是要写入数组元素的操作数或保存读取的数组元素的值的地址。

选中项目树中的PLC_1,单击工具栏上的“开始仿真”按钮978-7-111-58719-4-Chapter04-35.jpg,打开S7-PLCSIM。将程序下载到仿真PLC,后者进入RUN模式。打开OB1,单击工具栏上的978-7-111-58719-4-Chapter04-36.jpg按钮,启动程序状态监视功能。

978-7-111-58719-4-Chapter04-37.jpg

图4-25 间接寻址的程序与数据块

用鼠标右键单击指令FieldWrite的输入参数INDEX的实参MD10,执行出现的快捷菜单中的命令“修改”→“修改值”,用出现的“修改”对话框将MD10的值修改为3。启用数据块1的监视功能(见图4-25),可以看到输入参数VALUE的值25被写入下标为3的数组元素“数据块1”.数组1[3]。再次修改INDEX的值,VALUE的值将被写入INDEX对应的数组元素。

用上述方法设置指令FieldRead的输入参数INDEX的值为3,输出参数VALUE的实参MW18中是读取的下标为3的数组元素“数据块1”.数组1[3]的值。

2.使用间接寻址的循环程序

循环程序用来完成多次重复的操作。S7-1200/1500的梯形图语言没有循环程序专用的指令,为了编写循环程序,可以用FieldRead指令或MOVE指令实现间接寻址,用普通指令来编写循环程序。

978-7-111-58719-4-Chapter04-38.jpg

图4-26 FC1的接口区

在项目“间接寻址”的DB1中生成有5个DInt元素的数组“数组2”,数据类型为Array[1..5]of DInt(见图4-25的下图),设置各数组元素的初始值。

生成一个名为“累加双字”的函数FC1,图4-26是它的接口区中的局部变量。输入参数“数组IN”的数据类型为Array[1..5]of Dint,应与其实参(数据块1中的数组2)的结构完全相同。

FC1的程序首先将变量“累加结果”清零(见图4-27),设置数组下标的初始值为1,程序段2的跳转标签Back表示循环的开始。指令FieldRead用来实现间接寻址,其参数INDEX是要读写的数组元素的下标。参数MEMBER的实参“数组IN[1]”是数据类型为数组的输入参数“数组IN”的第一个元素,参数VALUE中是读取的数组元素的值。

读取数组元素值后,将它与输出参数“累加结果”的值相加,将数组的下标(即临时变量“下标”)加1,它指向下一个数组元素,为下一次循环做好准备。将作为循环次数计数器的“累加个数”减1。减1后如果非0则返回标签Back处,开始下一次循环的操作。减1后如果为0则结束循环。

在OB1中调用FC1“累加双字”(见图4-28的上图),求数据块1中的数组2从第一个元素开始,若干个数组元素之和,运算结果用MD20(“累加值”)保存。

978-7-111-58719-4-Chapter04-39.jpg

图4-27 FC1的程序

将程序下载到仿真PLC,CPU切换到RUN模式。用MW24设置要求和的数组元素的个数为5,FC1中设置的数组元素的下标的起始值为1。单击监控表工具栏上的978-7-111-58719-4-Chapter04-40.jpg按钮(见图4-28的左图),启动监视功能。首先令“累加启动”信号M2.0的修改值为0(FALSE),单击978-7-111-58719-4-Chapter04-41.jpg按钮,将修改值写入CPU。再令M2.0的修改值为1(TRUE),将修改值写入CPU以后,在M2.0的上升沿调用FC1“累加双字”(见图4-28的上图),通过循环程序计算出数组2的5个元素(见图4-28的右图)的累加值为15。

978-7-111-58719-4-Chapter04-42.jpg

图4-28 OB1调用FC1的程序、监控表与数据块1

3.数组元素的间接索引

要寻址数组的元素,可以用常量作下标,也可以用DInt数据类型的变量作下标。使用变量作下标可以实现间接寻址,可以用多个变量作多维数组的下标,实现多维数组的间接寻址。

将项目“间接寻址”中的FC1复制为名为“间接索引”的FC2,用图4-29中的MOVE指令取代图4-27中的FieldRead指令。MOVE指令中的输入参数IN的实参“#数组IN[#下标]”中的“下标”是DInt数据类型的临时变量,是输入参数“数组IN”的下标。用INC指令将它加1(见图4-27),下一次循环就可以读取数组的下一个元素的值。图4-29的右图是OB1中调用FC2的程序。

将程序下载到仿真PLC后,打开OB1,启动程序状态监控,右键单击“元素个数2”(MW26),用快捷菜单中的“修改”命令设置其值为5。右键单击“累加启动2”(M2.2),用快捷菜单中的“修改”命令产生它的上升沿,可以看到“累加值2”(MD30)中的累加结果为15。

如果下标变量的值超出允许的范围1~5(例如为0),出现区域长度错误,CPU的“ERROR”LED将会闪动。最好将数组下标的起始值设置为0。

978-7-111-58719-4-Chapter04-43.jpg

图4-29 FC2中的间接寻址与OB1调用FC2的程序

4.STL语言中的存储器间接寻址

S7-1500的STL(语句表)编程语言中的间接寻址分为存储器间接寻址和寄存器间接寻址,用得最多的是存储器间接寻址。详细情况见作者编写的《S7-300/400 PLC应用技术第4版》。SCL语言的间接寻址指令将在5.5节中介绍。(www.xing528.com)

在存储器间接寻址中,要寻址的变量的地址称为指针,它存放在方括号表示的一个地址(存储单元)中。存放指针的变量的数据类型可以是Word(16位指针)或DWord(32位指针),可以使用DB、M或L存储区。S7-1500也可以用FB参数保存地址。如果该变量在数据块中,必须是没有激活优化的块访问属性的可标准访问数据块。

(1)16位指针的存储器间接寻址

SIMATIC定时器/计数器、DB、FB和FC的编号范围小于65535,因此它们使用16位指针的存储器间接寻址。

生成项目“STL间接寻址”(见随书光盘中的同名例程),CPU为CPU 1511-1PN。在OB1中插入STL程序段,在其中生成下面的16位指针的存储器间接寻址的程序。MW8中的指针值为3,T[MW8]相当于SIMATIC定时器T3。

L 3 //将指针值装载到累加器1

T MW8 //将指针值传送给MW8

A M2.0 //SIMATIC定时器启动信号

L S5T#6S //定时器预设时间

S DT[MW8] //启动接通延时定时器T3

选中项目树中的PLC_1,单击工具栏上的“开始仿真”按钮978-7-111-58719-4-Chapter04-44.jpg,打开S7-PLCSIM,将程序下载到仿真PLC。S7-1500的仿真表不能直接对STL语言中的变量进行监控。在程序运行时可以用监控表监控变量的值(见图4-30)。

978-7-111-58719-4-Chapter04-45.jpg

图4-30 监控表

在监控表中令T3的启动信号M2.0为1状态,T3开始定时,它的剩余时间值开始变化,说明间接寻址的操作数T[MW8]的确是T3。修改程序中MW8中的地址指针值,下载后可以用新地址指定的定时器定时。

(2)32位指针的存储器间接寻址

32位指针可以对I、Q、M、DB等地址区的位、字节、字和双字进行间接寻址,地址指针包含了地址中的字节和位的信息。这些地址区的间接寻址使用双字指针,指针格式如图4-31所示。第0~2位为被寻址地址中位的编号(0~7),第3~18位为被寻址地址的字节编号(0~65535)。32位指针的数值实际上是以位(bit)为单位的双字。

如果要用双字格式的指针访问一个字节、字或双字存储器,必须保证指针的位编号为0,例如P#20.0,否则程序将会出错。

978-7-111-58719-4-Chapter04-46.jpg

图4-31 存储器间接寻址的双字指针格式

在OB1中插入STL程序段,在其中生成图4-32中32位指针的存储器间接寻址的程序。将程序下载到仿真PLC后,启用程序状态监控功能。右边监控区的“值”列是该行指令中变量的数值,“额外”列是该行的间接寻址的地址指针值。前两条指令将指针值P#10.0传送到MD20。第3行的“额外”列的值表示MD20中的地址指针值为P#10.0,地址的字节部分为10,因此间接寻址的QB[MD20]的地址为QB10。在监控表中将16#23写入QB10(见图4-30),执行指令“LQB[MD20]”之后,QB10中的16#23被装载到累加器1中。第3行的“值”列为16#23,说明QB[MD20]对应的地址的确是QB10。

978-7-111-58719-4-Chapter04-47.jpg

图4-32 使用32位指针的存储器间接寻址程序

第5、6条指令将指针值P#4.3传送到MD30。第7行的“额外”列的值表示MD30中的地址指针值为P#4.3,因此M[MD30]的地址为M4.3。第7、8行的程序用M4.3控制Q5.0,这两行的“值”列中分别是M4.3和Q5.0的值。在监控表中改变M4.3的状态(见图4-30),它控制的Q5.0的状态随之而变。说明M[MD30]对应的地址的确是M4.3。

P#10.0的值为2#0000 0000 0000 0000 0000 0000 0101 0000(16#50)。所以第2行的“值”列的十六进制格式的数值为16#0000_0050。

P#4.3的值为2#0000 0000 0000 0000 0000 0000 0010 0011(16#23)。所以第6行的“值”列的十六进制格式的数值为16#0000_0023。

5.STL语言中的寄存器间接寻址

S7-1500可以用地址寄存器AR1和AR2对各地址区的地址作寄存器间接寻址。地址寄存器中的指针值加上地址偏移量,形成地址指针值,指向数据所在的存储单元。寄存器间接寻址分为区域内的间接寻址和跨区域间接寻址。

图4-33是地址寄存器间接寻址的双字地址指针的格式,其中第0~2位(xxx)为被寻址地址中位的编号(0~7),第3~18位为被寻址地址的字节的编号。第24~26位(rrr)为被寻址地址的区域标识号,第31位x=0为区域内的间接寻址,为1则为跨区域的间接寻址。最高字节的值与表2-6中的基本上相同(不包括代码16#1和16#2)。

978-7-111-58719-4-Chapter04-48.jpg

图4-33 寄存器间接寻址的双字指针格式

用寄存器间接寻址访问一个字节、字或双字时,必须保证指针的位地址编号为0。

(1)寄存器区域内间接寻址

寄存器区域内间接寻址的地址指针不包括地址的区域标识号,指针的最高位字节为0。在OB1中插入STL程序段,在其中生成图4-34中的寄存器间接寻址的程序。前两条指令将指针值P#2.0传送到AR1,MW[AR1,P#8.0]方括号中AR1的指针值P#2.0加上偏移量P#8.0,得到地址指针值P#10.0,其字节地址为10,因此MW[AR1,P#8.0]的地址为MW10。在监控表中将16#ABCD写入MW10(见图4-30),第3条指令将MW10中的16#ABCD装载到累加器1(见图4-34),说明MW[AR1,P#8.0]的地址的确是MW10。第3行的“额外”列中的P#10.0是AR1中的指针值加上偏移量得到的地址指针值。

978-7-111-58719-4-Chapter04-49.jpg

图4-34 寄存器间接寻址程序

(2)寄存器区域间的间接寻址

第4、5条指令将指针值P#M6.0传送到AR1,因为地址指针P#M6.0已经包含有区域信息“M”,间接寻址的指令“LW[AR1,P#10.0]”省略了地址标识符M。W[AR1,P#10.0]方括号中AR1的指针值P#M6.0加上偏移量P#10.0,得到地址指针值P#M16.0,其字节地址为16,因此W[AR1,P#10.0]的地址为MW16。在监控表中将16#8320写入MW16(见图4-30),第6条指令将MW16中的16#8320装载到累加器1,说明W[AR1,P#10.0]的地址的确是MW16。第6行的“额外”列中的P#16.0是AR1中的指针值加上偏移量得到的地址指针值。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈