作者 | 主题 |
---|---|
空果仁 侠圣 经验值: 4925 发帖数: 210 精华帖: 47 |
楼主 2020-03-17 20:27:05
主题:【5】寄存器间接寻址——从S7-300_400到S7-1500看变址寻址的改变系列故事之五 2 寄存器间接寻址 与存储器间接寻址不同,寄存器间接寻址使用CPU内部集成的两个32位地址寄存器AR1、AR2存储地址指针。寄存器间接寻址分为32位内部区域指针和32位交叉区域指针。 2.1 访问地址寄存器AR1、AR2的指令 寄存器的访问需要使用特殊的指令。指令如下所示: LAR1 : 将ACCU1存储的地址指针写入AR1。 LAR1 <D> : 将指明的地址指针写入AR1,例如LAR1 P#20.0或LAR1 MD20。 LAR1 AR2 : 将AR2的内容写入AR1。 LAR2 : 将ACCU1存储的地址指针写入AR2。 LAR2 <D> : 将指明的地址指针写入AR2,与LAR1 <D>方式相同。 TAR1 : 将AR1存储的地址指针传输给ACCU1。 TAR1<D> : 将AR1存储的地址指针传输给指明的变量中。 TAR1 AR2 : 将AR1存储的地址指针传输给ACCU2。 TAR2 : 将AR2存储的地址指针传输给ACCU1。 TAR2 <D> : 将AR1存储的地址指针传输给指明的变量中。 CAR : 交换AR1和AR2的内容。 2.2 使用地址寄存器AR1、AR2的限制 都是32位指针,为什么不使用存储器替代CPU内部的地址寄存器呢?使用方法上完全可以,除此之外,CPU还利用AR1、AR2做了一些系统内部的工作,如果没有AR1、AR2将造成程序的混乱(这节内容是引深介绍,不感兴趣可以跳过)。同样系统和用户都可以使用AR1、AR2,用户使用时需要考虑是否系统也在使用,否则也将造成程序的混乱,同时也不能改写。所以用户使用时会有限制,例如接口参数的传递中,STEP7使用地址寄存器AR1访问函数FC接口及函数块FB“INOUT”接口中定义的复合类型参数,如ARRAY、STRUCT、DATE_AND_TIME等,AR1和DB块寄存器中的内容将被覆盖,例如在FC1中“IN”接口中定义一个数组变量,在OB1中调用,使用OB1的L区域数据进行赋值,调用关系如图12所示。 图12 如果在FC1中访问数组变量的元素如ARR_TEST[1],地址寄存器AR1及DB块寄存器会发生变化,示例程序如图13所示。 图13 图13示例程序中前两条语句中打开DB1并将P#20.0装载到AR1中,在第三条语句访问数组的一个元素后AR1存储的地址指针变为P# V20.0(指向OB1中实参ARR_TEST的地址,参考图13),程序下传到CPU后将出现故障报警。将程序的执行次序进行修改,CPU即可运行,修改后的程序如下: L #ARR_TEST[1] //装载形参变量ARR_TEST[1]到累加器1中。 OPN DB 1 //打开DB1 LAR1 P#20.0 //将P#20.0装载到地址寄存器AR1中。 T DBW [AR1,P#0.0] //将累加器1中的值传送到DB1.DBW20中。 AR2和DI寄存器分别包含FB背景数据块的块号及在背景数据在背景数据块中偏移地址(多重背景数据块),在FB中使用AR2和DI寄存器将会覆盖系统存储的内容。如果必须在FB中使用AR2和DI寄存器,建议使用下面的方法处理AR2和DI寄存器,首先保存AR2和DI寄存器中的数据,程序如下:
TAR2 MD 100 //将AR2的数据存储于MD100中。 L DINO //将背景DB块块号存储于MW104中。 T MW 104 ///////用户程序/////////////// 然后编写用户程序,可以对AR2和DI寄存器进行操作,但是在程序中不能访问FB参数或静态变量。使用完成后恢复AR2和DI寄存器的系统值,程序如下:
LAR2 MD 100 //将MD100中存储的地址指针装载到AR2中。 OPN DI [MW 104] //打开DI数据块。 2.3 寄存器32位内部区域指针 寄存器32位内部区域指针用于I、Q、M、L、数据块等存储器中位、字节、字及双字的寻址,与32位存储器指针使用相同,不同之处只是指针存储的位置不同(几乎没有区别,就是表示格式不同)。32位内部区域地址指针的格式如图14所示。 图14 第0位~第2位作为寻址操作的位地址,第3位~第18位作为寻址操作的字节地址,第19位~第30位没有定义,第31为内部区域与交叉区域指针标识,0表示内部区域指针,1表示交叉区域指针。 32位内部区域指针地址寻址表示格式为:地址存储器标识符[地址寄存器,地址偏移常量],例如装载M存储器一个字节表示为: AR1/2 :AR1或者AR2。注意使用限制。 指针指向地址= 地址寄存器存储地址 + 地址偏移常量,如果AR1装载的地址为P#8.0,实际装载的地址为MB18。32位内部区域指针的使用方法参考下面的示例程序: OPN DB 1 //打开DB1。 LAR1 P#10.0 //将指针P#10.0 装载到地址寄存器1中。 L DBW [AR1,P#12.0] //将DBW22装载到累加器1中。 LAR1 MD 20 //将存储于MD20中的指针装载到地址寄存器1 中。 L DBW [AR1,P#0.0] //将DBW装载到累加器1中,地址存储于MD20中。 +I LAR2 P#40.0 //将指针P#40.0 装载到地址寄存器2中。 T DBW [AR2,P#0.0] //运算结果传送到DBW40中。
2.4 寄存器32位交叉区域指针 32位交叉区域指针与32位内部指针相比,地址指针中带有存储区域如I、Q、M等, 32位交叉区域地址指针的格式如图15所示。 图 15 第0位~第2位作为寻址操作的位地址,第3位~第18位作为寻址操作的字节地址,第24位~第26位为地址标识符,表示的地址区域如下: 000表示没有地址区,例如P#12.0; 001表示输入地址区I,例如P#I12.0; 010表示输出地址区Q,例如P#Q12.0; 011表示标志位地址区M,例如P#M12.0; 100表示数据块(DB)中的数据,例如P#DBX12.0 101表示数据块(DI)中的数据,例如P#DIX12.0 110表示区域地址区L,例如P#L12.0; 111表示调用程序块的区域地址区V,例如P#V12.0; 第31为内部区域与交叉区域指针标识,0表示内部区域指针,1表示交叉区域指针。使用交叉区域指针的表示方法(例如装载M存储器一个字节)为:
LAR1/2 P#M 20.0 //装载地址指针P#M20.0到AR1或AR2。 指针指向地址 = 地址寄存器存储地址 + 地址偏移常量,上例中实际装载的地址为MB30。如果访问一个位信号则没有访问宽度。32位交叉区域指针的使用方法参考下面的示例程序: LAR1 P#M 20.0 //将指针P#M20.0 装载到地址寄存器1中。 A [AR1,P#1.1] //M21.1“与”操作。 = Q 1.2 //如果M21.1为1,输出1.2为1。 L P#I 40.0 //将指针P#I40.0 装载到累加器1中。 LAR2 //将累加器1中存储的地址指针装载到地址寄存器2中。 L W [AR2,P#0.0] //装载IW40.0到累加器1中。 T MW 60 //将累加器1中存储的数值传送到MW60中。 2.5 使用寄存器间接寻址的思考 估计大家读完了寄存器间接寻址后,肯定有一些问题: 1:什么时候用地址寄存器间接寻址? 在我来看,地址寄存器是寄存器,利用寄存器间接寻址是使用寄存器存储指针,这两个要搞明白。地址寄存器是系统的,主要是系统处理内部的地址偏移和引用的问题,例如在FB块的开始写入指令T AR2,是指出在背景数据块数据开始的偏移地址(例如FB1调用多个FB块时,在OB1中调用FB1后生成一个多重背景DB块,其中包含各个调用FB块的数据区,如果没有编写上述的指令,那么调用FB块的数据区在背景数据块中将重叠),所有地址寄存器是不可或缺的!利用寄存器间接寻址使用最多的是拆分POINTER和ANY指针使用的(后续再介绍),其它使用的地方很少,还看个人的编程习惯吧。S7-1500没有绝对地址,所以也没有什么地址偏移的问题(即使有也不需要用户考虑),地址寄存器在S7-1500中是虚拟的,主要就是为了S7-300/400程序的移植,所以移植完成后还要测试一下程序,看看是否达到了原来的控制功能。 2:谁会使用地址寄存器? 很显然,地址寄存器还有数据块寄存器通常是程序块的开发人员使用,否则编程的程序块在有的调用方法上会出问题,主要是程序不完善造成的,程序块的使用者掌握存储器间接寻址就可以了,除非是特殊应用,例如使用指针变量(ANY 或者POINTER)赋值ANY 或者POINTER接口参数。 3:32位的存储器指针与32位的寄存器指针(交叉和内部)有什么区别? 我想应该是一样的,参考下面的一条指令: LAR1 MD 20 //将存储于MD20中的指针装载到地址寄存器1 中。
指针可以相互传达,说明是一样的,所以指令也可以这样写: LAR1 P#M10.0 //将指针P#M10.0装载到地址寄存器1 中。
L P#M10.0 //将指针P#M10.0装载到累加器1 中。 T MD 20 //传递到MD20中
指针类型虽然比较多,前面说了不好再归纳,因为再归纳反而不容易入门学习(划分),如果理解深刻了在你的头脑中就会形成自己的知识体系,便于记忆和使用,感觉就跟网络小说里面的“炼化”一样。 ---------------------------------------------------------------------------------------------------------- 上一篇:【4】存储器32位地址指针——从S7-300_400到S7-1500看变址寻址的改变系列故事之四 下一篇:【6】pointer 和ANY——从S7-300_400到S7-1500看变址寻址的改变系列故事之六
来自西门工业子技术支持 高级专家
|
yangchunbaixue 侠圣 经验值: 3694 发帖数: 555 精华帖: 0 |
1楼 2020-03-18 09:49:08
主题:回复:从S7-300_400到S7-1500看变址寻址的改变-5 |
CoolCool的猪 至圣 经验值: 16693 发帖数: 1307 精华帖: 2 |
2楼 2020-03-18 20:49:01
主题:回复:从S7-300_400到S7-1500看变址寻址的改变-5 谢谢啊
同一个问题ID下,已经先回答此问题的人,如再参考我答案而修改自己答案的,就是王八蛋!
|
木头515 侠圣 经验值: 2151 发帖数: 251 精华帖: 0 |
3楼 2020-03-19 10:24:22
主题:回复:从S7-300_400到S7-1500看变址寻址的改变-5 看了之后对寻址理解更加深刻了,谢谢分享。
低头做事,抬头做人!!
|