前言
在西门子系列的PLC中绝大多数都可以对AR2地址寄存器进行操作。绝大多数指S5系列PLC,S7-300/400/1500的PLC。当我们在用西门子PLC的STL语言编程中,很可能避不开AR2地址寄存器。当然现在有了SCL语言后,用STL语言进行编程的场景越来越少了。但是当我们看到已有的STL程序时也要做到心中有数。在STL语言中有一个难点:AR2地址寄存器。今天就和大伙说说这个AR2地址寄存器。
官方的文档
在了解AR2之前,我们先看看官方的文档如何描述AR2。
Two address registers are available for the indirect addressing of operands: address register 1 (AR1), and address register 2 (AR2). The address registers are equal and are 32 bits in length. You can store area-internal and cross-area pointers in the address registers. To define the address of an operand, you can call the stored data in the program.
Data is exchanged between the registers and the other available memory areas with the assistance of load and transfer instructions.
我简单翻译这段文字。
可以通过2个地址寄存器间接寻址操作数,AR1和AR2。他们地位相同,并且是32位长度。可以存储区域内或者区域间指针。要定义操作数的地址,你可以调用程序中存储的数据。
用load与transfer指令可以在地址寄存器与其他存储单元之间交换数据。
这段文字有一句话是容易使人产生误解的。“2个地址寄存器地位相等。”这里面讲的地位相等特指在指令层面上地位相同。凡是AR1有的指令AR2都有,所以官方的说明才说地位相同。但是我可以负责任的讲,凡是熟悉STL语言的伙计们都知道这2个寄存器的地位肯定不是相同的。我们下文会探讨这个。
AR的常规用法
本小节先探讨AR的常规用法。在这里我们用AR1举例。例子中用1500非优化块。在OB1中调用Block_2

图1.1
Block_2的程序及监控结果,如下图,

图1.2
本FB块的功能是将输入传递给输出。我们可以用前2行符号寻址完成这个功能。也可以用后3行完成这个功能。既然能用符号寻址完成的功能,为什么还要用后3行的间接寻址完成这个功能?这是因为本例子旨在让大伙对地址存储器有一个初步的认识。对于AR来讲,更深入的用法是地址寄存器配合ANY指针的用法,由于这不是本篇所重点探讨的内容,所以ANY配合地址寄存器的用法不在这里讨论。
在图1.2中,
第4行含义:将in所在的背景数据块偏移量传输给AR1,内容是P#DIX0.0。这有2个信息:1,指针指向背景数据块(DI);2,in存储在偏移量是0.0的地址中。
第5行含义:取AR1所指向起始地址的16位数据的值,并将这个值放入到累加器1中。
第6行含义:将累加器1中的内容放入到out中。
通过这个例子,我们大致对AR的用法有了一个初步的了解。这种了解是下文的基础,所以不得不用一些篇幅探讨。
AR2的特殊性
本小节是本篇的重点。前文述及AR2与AR1是不同的。本小节探讨AR2的专用性。
例2:
我们把block_2放到另外一个FB:block_1中调用。block_1设置为非优化快,并在OB1中调用。
在block_1中用多重背景数据作为block_2的背景数据,在这个多重背景数据块前面增加一个占用4字节的变量statDUMMY,如图2.1

图2.1
我们发现图2.1的结果不对了,虽然block_2中的程序并未更改。监控block_2,得到下图

图2.2
我们更改block_2中的内容如下

图2.3
从图2.3结果看出来,我们需要的88又回来了。为了说明问题,我们在图2.3基础上增加一行不影响代码运行的代码。

图2.4
我们详细解释一下图2.4中的代码。
TAR2 //将AR2中的地址放入到累加器1。
LAR2 //将累加器1中的内容赋值给AR2。为了看清AR2或者累加器1中内容,我们增加了这行。有了这行我们知道累加器1中的内容和AR2中的内容是P#DBX4.0,P#DBX4.0与16#8400_0020是相同的值,只是表示法不同。一个用指针表示,一个用16进制表示。
这里是重点:当CPU调用FB块时,CPU会将数据块中有关该FB所占用的数据区的起始地址自动赋值给AR2。在BLOCK_1的背景数据块中,BLOCK_2的起始地址是4.0。这一点在图2.1中变量声明区就可以知晓了。
+AR1 //将累加器1中的地址与AR1中的地址相加,相加的结果放入AR1。就得到DIX4.0
L W [AR1 , P#0.0] //取以DIX4.0为起始地址,长度16位的数据。
通过这个例子我们可以理解AR2与AR1是不同的。AR2有特殊性
对AR2的操作原则
在图2.4中,代码第5行的颜色是黄色。这是博图为了提醒我们而用的醒目的黄色。为什么提醒我们。因为这行代码修改了AR2中的内容。这是很危险的。
在例子2中我们知道在FB运行之初AR2是系统自动赋值的,其内容是背景数据块中的偏移量。如果我们用代码手动更改了AR2中的内容,那么很可能会出现寻址错误。所以这里面有一个原则:在STL编程中,不要修改AR2中的内容。
但是例子2中我们修改了似乎也没问题。这是因为在例子2中,我们把AR2中的内容放入到了ACC1,然后又把ACC1中的内容赋值给了AR2。本质上AR2中的内容并未发生改变。
小结
本篇首先解释了西门子官方文件中对AR1和AR2的说明,尤其解释了AR1与AR2地位相同这句话的含义。
再次本篇探讨了STL语言中AR1与AR2的不同,并知道AR2在调用FB中的重要作用。我们还知道在FB中不能轻易更改AR2的内容。
本篇中以上探讨的这些内容在S5,S7-300/400/1500中特性是相同的。总结一句话,在以上这些CPU中当用STL语言给FB编程时,并且用AR2地址寄存器进行间接寻址时,这些类型的PLC特性相同。
另外,如果在FB中用STL语言编程,并且更改了AR2的内容,并且用了符号寻址而不是间接寻址。300/400与1500中是略有不同的。1500修正了300/400中容易犯错的地方。由于300/400已经是上一个时代的产品了,所以本篇不再讨论。
已经有2篇是精华帖。不知道这篇是否合大伙的胃口。