我想实现多个数据在一个区域里按顺序存储的功能,也就是"ATT"功能,但我不想用西门子现成的块。我也是用存储区域的第二个字来保存可以存储的数据的数量。用第一个字来存储现有的数量。在块里声明了一个临时变量TEMP0来计算下一个存储进来的数据要存储的位置。具体编程见下图,可是指针编程的偏移量只能用地址常数来表示,但我的现有数据个数的值是变化的,那我这个功能应该怎么实现呢?
图片说明:
最佳答案
1:你上个问题还没确认了 老兄,不确认会扣分的。你这个程序问题很大。
2:ANY 用法不是这样来用的,请见图ANY 的结构.用ANY 类型之前 必须对ANY 进行分析(得出实参所指向的存储区域)。你没有这个过程。分析过程参考下面
L P##AlarmBit //any 类型
LAR1 //get the start address of the any pointer
L B [AR1,P#0.0] //head for S7 serial b#16#10
T #AnyAlarmBit.HeadS7
L B [AR1,P#1.0] //DataType (01=bool;02=byte; 04=word;06=dword)
T #AnyAlarmBit.DataType
L W [AR1,P#2.0] //cyclic factor
T #AnyAlarmBit.RepetitionFactor
L W [AR1,P#4.0] //Data Block Number ,if source is not a DB area ,load the 0 for this area
T #AnyAlarmBit.DBNO
L D [AR1,P#6.0] //指针地址
T #AnyAlarmBit.AddrPointer
看看你程序里的 W[AR1,p#0.0] 是什么东西了?数值可能是W#16#1004
W [AR1,P#2.0] 是什么?比如是P#DB1.DBX1.0 WORD 10 中的10
2个比较有什么意义了?
比如 你的 SAVEED_AREA调用时实参为 P#DB1.DBX10.0 WORD 10
那么 经过分析后
L P#SAVEED_AREA
LAR1
B [AR1,P#0.0] =b#16#10
B [AR1,P#1.0] =B#16#04
W [AR1,P#2.0]=10
W [AR1,P#4.0] =1
D [AR1,P#6.0] =P#10.0=DW#16#15=80
你的指针是放在D [AR1,P#6.0]里面的,并不是方在AR1里面的。
3:对于你的问题,比如你知道指针地址后,你可以把
L D [AR1,P#6.0]
LAR1 //把地址存放在AR1 中
然后 可以把偏移地址就是你的TEMP0
L TEMP 0 //加上AR1前转换成指针地址。如果把地址存到起始地址下一字中则TEMP必须是16,而不是2(非常重要)
+AR1
后面 你就可以使用
L W[AR1,P#0.0]
L 1
+I
T W[AR1,P#0.0]
通过改变AR1 数值来实现地址偏移功能。不要死脑筋 只想改变[AR1,P#0.0]偏移地址P#0.0,这个是行不通的。
要不你直接使用存储器寻址 比如L W[MD0],地址在MD0里面。
最后 好好学学SIEMENS 的间接寻址的知识。SIEMENS 编程水平的高低就看你的间接寻址水平了。当然你如果使用SCL语言除外。
图片说明:
提问者对于答案的评价:
感谢指导!
原创文章,作者:more0621,如若转载,请注明出处:https://www.zhaoplc.com/plc229797.html