技术论坛

 回复:AR2地址寄存器引发的FB问题

返回主题列表
作者 主题
Letham
至圣

经验值:14191
发帖数:2021
精华帖:43
楼主    2014-11-04 22:25:29
主题:AR2地址寄存器引发的FB问题 精华帖 
前段时间,为同事编写一段通过绝对值编码器进行位置定位的程序,使用的FB,程序设计完成后,进行测试,在OB1中,以 CALL,FBx,DBx的形式进行调用。所有功能测试完毕,全部正确执行,所以就把程序的STL源文件发给他了,前几天传来信息,程序不能正确执行CPU冒红灯了,我上线一看傻眼了,肯定指针编程错误了。

由于我们公司的标准程序里,每个设备都会编写一个FB 块控制程序(比如电机,DI点,DO 点,阀门,AO,AI 等),然后再按照生产线流程把相关的设备分到一个组里面进行控制,每个组用一个FB 来完成程序控制,对于划分到该组里面的每一个设备所对应的FB ,在组控制FB里面以多重背景的方式进行调用。

举例说明某个组(Group100)的FB 控制程序为FB100,分到这个组里面的设备有2台电机(FB10),一个安全开关DI点(FB11).则FB100的STAT变量里有类型为FB10的这个变量和一个类型为FB11的变量。其实估计大家都应该明白,就是FB的多重背景调用罢了。

问题就是出在,在编写程序时,没有考虑到多重背景调用的情况,因为为了提高程序的通用性,我在编写编码器定位控制的FB块时,使用了区域内寄存器寻址,从而导致了FB块以多重背景调用方式的时候出现了问题。
请看下面我的编码器定位控制FB的STAT变量Bins为一个64的数组,数组元素类型为一个STRUCT.
Bins : ARRAY [1 .. 64 ] OF //仓数据区
STRUCT
ParPostionAbsolute : INT ; //虚拟仓位置所对应的格雷码转换为二进制的值
PostionOffset : INT ; //仓位置所允许的误差
ParPostionToOutPort : INT ; //虚拟仓转到取料口时,编码器所对应的格雷码转换为二进制的值
END_STRUCT ;
在FB 程序里面,我对此处类容进行了间接寻址 ,见下面代码:
//--Serch the selectedt bin postion
LAR1 P##Bins;
L #InTargetBinIndex;
+ -1;
ITD ;
L P#6.0;
*D ;
+AR1 ;
L DIW [AR1,P#4.0];
T #SelectedBinTarPostion;
L DIW [AR1,P#2.0];
T #SelectedBinOffset;
//--Serch the selectedt bin postion end
编写完成后,进行FB测试,没有问题。但是以多重背景方式调用时,出现问题了。原因是什么了?
让大家更明白,我们约定以多重背景方式在其他FB块里面被调用的FB块称之为“子FB块”吧,调用该“子FB块”的FB块为“父FB块”吧,呵呵,有点不专业额。
大家知道在SIMENES PLC中有2个地址寄存器,AR1和AR2,以及2个数据块寄存器DB,DI。其中AR2地址寄存器和DI数据块寄存器相对特殊,主要用在FB中进行寻址。当我们在程序里进行调用FB块时,AR2寄存器类容被初始化为16#85000000.实际上在该FB期间AR2一直保持为16#85000000,当该FB块为一个“父FB块”时,在调用到“子FB块”时,AR2类容变为什么了?答案是在调用"子FB块"过程中AR2类容变为16#85000000+"子FB块"在“父FB块”中的偏移地址。但这个问题和程序出错又有什么关系了?
:) 因为在“子FB块”我以 LAR1 P##Bins; 语句取出的Bins的起始地址仅仅是在”子FB块“中的偏移地址。如果“在FB块”在“父FB块”以多重背景方式调用时,我们应该为该偏移地址再加上“子FB块”在“父FB块”中的偏移地址。
说到这里我想大家应该也明白问题所在了。因此我将上面代码稍作修改,程序即可正确执行了。
//--Serch the selectedt bin postion
LAR1 P##Bins;
TAR2 //新增加语句,取出“子FB块"在”父FB块“中的偏移地址
+AR1 //新增语句,加上该偏移地址,从而得到BINS在“父FB块”中的偏移地址
L #InTargetBinIndex;
+ -1;
ITD ;
L P#6.0;
*D ;
+AR1 ;
L DIW [AR1,P#4.0];
T #SelectedBinTarPostion;
L DIW [AR1,P#2.0];
T #SelectedBinOffset;
//--Serch the selectedt bin postion end

SIEMENS PLC 相对于其他PLC 来说虽然性价较高,但是STEP7在编程方面做的的确没有诸如AB,GE之类的PLC 来的方便,尤其是在间接寻址编程方面,尤其复杂。不知道各位大侠们在STEP7 编程中是否也遇到一些间接寻址编程方面的问题了?
人生就像一场旅行!
Sampson.cui
侠客

经验值:647
发帖数:51
精华帖:0
18楼    2014-12-23 16:15:19
精编帖  主题:回复:AR2地址寄存器引发的FB问题
感谢楼主letham为大家做的分享和精彩讲解,但我觉得其中有点小错误:
------“当我们在程序里进行调用FB块时,AR2寄存器类容被初始化为16#85000000.实际上在该FB期间AR2一直保持为16#85000000,当该FB块为一个“父FB块”时,在调用到“子FB块”时,AR2类容变为什么了?答案是在调用"子FB块"过程中AR2类容变为16#85000000+"子FB块"在“父FB块”中的偏移地址”-------其中的AR2内容应为“16#84000000”或“16#84000000+"子FB块"”。
那么在程序中怎么能正确获得背景数据的地址呢?那是因为CPU先执行了“LAR1 P##Bins”,此后的“+AR1 ”并不影响区域ID.再说下面程序再使用变址寻址时又是区域内寻址。所以程序能如愿执行。
修德广业
Letham
至圣

经验值:14191
发帖数:2021
精华帖:43
19楼    2014-12-23 18:50:27
精华帖  主题:回复:AR2地址寄存器引发的FB问题
quote:以下是引用*在2014-12-23 16:15:19的发言:
感谢楼主letham为大家做的分享和精彩讲解,但我觉得其中有点小错误:
------“当我们在程序里进行调用FB块时,AR2寄存器类容被初始化为16#85000000.实际上在该FB期间AR2一直保持为16#85000000,当该FB块为一个“父FB块”时,在调用到“子FB块”时,AR2类容变为什么了?答案是在调用"子FB块"过程中AR2类容变为16#85000000+"子FB块"在“父FB块”中的偏移地址”-------其中的AR2内容应为“16#84000000”或“16#84000000+"子FB块"”。
那么在程序中怎么能正确获得背景数据的地址呢?那是因为CPU先执行了“LAR1 P##Bins”,此后的“+AR1 ”并不影响区域ID.再说下面程序再使用变址寻址时又是区域内寻址。所以程序能如愿执行。


对 是有点笔误,AR2内容为16#8500开始的,FB块内调用多重背景后,AR2内容会变成多重背景在FB背景DB块的偏移地址,比如P#DIX200.0,在多重背景调用结束后AR2内容会自动回到P#DIX0.0
这个过程是由CPU操作系统来做的。
但是你的理解有误,我不是想要说明是指针的存储区域的改变与否,在我的程序中AR1,AR2内容始终是P#DIX x.y。
LAR1 P##Bins;
这个语句 仅仅得到的是BINS在被多重背景调用的FB块中的首地址,但是多重背景FB没有自己的DB块,它正确执行,需要调用多重背景的FB块的背景DB块,但是多重背景FB的偏移地址很可能 不是从0开始的,所以为了 正确定位到 多重背景FB所使用的数据区,必须 加上AR2的内容,才能正确对应到DB块的数值,这就是TAR2,后+AR1目的所在,没有这2句,FB块直接调用 不会有任何问题!但以多重背景方式调用,就不会正确执行了!

所以 整个程序讨论的重点 和32位指针的区域ID 是否改变没有任何关系。
我可以
T W[AR1,P#0.0]
来做 ,它也不会出错。
人生就像一场旅行!
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。