S7 Pointer Help

STL???

Member
Join Date
Sep 2005
Location
UK
Posts
879
Hi,
I'm trying get to grips with a FB in which an Array of 25 DINT's are passed into an IN variable assigned with the Data type "Pointer"

The start address and length with is passed in is P#db30.dbx0.0 and here's the code from the calling block:
LAR1 P##DATA //(IN)DATA TYPE - POINTER
L D[AR1,P2.0]
T #AREA_POINTER //STAT DINT
L W[AR1,P0.0]
T #DB_NUMBER //STAT INT



I couldnt find any useful Info in the S7 help file and the Berger stl book leaves me with more questions than answers!

Would i be correct in respect that the data queried is in "Any" format and stored in a 80 Bit format?

If so there are 3 different ANY pointers ~ Blocks,Timer/counter and Data types! i'm assuming its the Block type.

Looking at the values produced in the Accumulator against a 32 bit address register is also confusing!

1000_0100_0000_0000_0000_0000_0000_0000 Bin
84000000 Hex
-2080374784 Dec

0000_0000_0001_1110 Bin
1E Hex
30 Dec

Is there a shift within the Address register using P# offset to access all 80 bits? or have i got it totally wrong!!!

Thanks in advance for any enlightenment you could provide

STL
 
In program editor, select help and then from the drop down select contents. Follow the contents down to the bottom of the list and you will find appendix. In the appendix you will find the exact format of Pointers and Any values explained in good detail.Off the top of my head, the pointer is 3 words long, the first (bytes 0 and 1) is the DB address, if not a DB will be zero. The second and third words make a double word (bytes 2, 3, 4 and 5).

Byte 2 = data type, for example 84Hex = Data Bit, bytes 3, 4 and 5 are the word and bit address, the rh 3 bits of byte 5 is the bit address from 000 = 0 to 111 = 7 (binary).


Just to go through that bit of code.

LAR1 P##DATA:

This is loading the address register 1 (points to the area where you are going to read or write data) with the location in memory of the first byte.bit of the IN parameter #DATA. (which is a pointer to a datablock address)

L D[AR1,P2.0]:

Load the accumulator with the contents of byte 2, 3, 4 and 5; DW) In this case it will be byte 2 84 Hex, bytes 3, 4 and 5 will be zero, as the address you showed was DBX0.0.

T #AREA_POINTER //STAT DINT:

Presume #AREA_POINTER is a TEMP double word to hold that address.

L W[AR1,P0.0]:

This is the first word, the Data Block address, which in your example will equal 30.

T #DB_NUMBER //STAT INT:

Stores it in I presume a TEMP word.


Is there a shift, yes normally there is, if your word address was 6 instead of 0, in the pointer address the right hand 3 bits of the double word are bit address, therefore you would shift left double 3 the word address and store in the area pointer, before placing the 84 bhex into the first byte.


ANY = I think

Byte 1 always = hex 10
Byte 2 = format, 02 = Byte.
Word 3 = Length.
Word 4 = Data Block address.
DWord 5 = Data Type and word/bit address.

Words 4 and DWord 5 are a copy of the pointer.
 
Last edited:
Hi Peter,
Thanks for tip, i put a search in for "Any" and it only returned SCL related information. The appendix page is exactly what i was looking for!

Thanks
STL
 
Last edited:
Hi Peter,

The data access via WORD/DWORD pointer offsets i think i understand your explanation.

The part which still puzzles me is how Address register 1 can handle 80 bits when it is a 32 bit register.

am i correct in saying that dependant on the offset you apply, you can access the full data length?

The Dint/Int static variable transfers are used as parameters for another block call further down the code.

Thanks for your help
 
AR1 doesn't handle the whole 80 bits. As you said, it is a 32 bit variable, and just represents the data type and address. You can think of it being only bytes 6-9 of the Any Pointer.

By the way, there is a good way of building an Any Pointer without remembering all of the hex equivilents (i.e 84 for DBs) for the data type. Try this to configure the last four bytes to point to DBX 20.0 (I'm assuming for this example that the Any Pointer is in local bytes 0-9):

L 20
SLD 3
L P#DBX 0.0
OD
T LD 6

To point to M20.0, just substitute M for DBX:

L 20
SLD 3
L P#M 0.0
OD
T LD 6

It just makes it a little easier to see what's going on for yourself and others who have to read your code.
 
Hi S7Guy,
Thanks for clearing that up, i always welcome easier more understandable methods.

I downloaded your FB_UDT example whilst searching for similar "Any" pointer threads, One for the future as my understanding improves! ;)

Regards
STL
 
STL??? said:
I'm trying get to grips with a FB in which an Array of 25 DINT's are passed into an IN variable assigned with the Data type "Pointer"
Hi Guys

I just want remind for You one thing. If You handle FB's and You have several block calls into same multi-instance FB/DB -> You must remember to add TAR2 into ANY-variable, then you can get the correct start-address.
TAR2 // Start-address of current FB-call
L P##ANY_VARIABLE // Variable address
+D
LAR1 // Start-address of ANY_VARIABLE in current FB-call

If You use only P##ANY_VARIABLE, then the each FB-call must have own(individual) instance-DB.

Pete 🍺
 
Last edited:
S7Guy is quite right in the ability to directly access the temp local flags, just be aware when doing this, if a new temp is added before or removed before the tag you've assigned, the local flags change and your code could be screwed.

Pete[Fin] is spot on too, regarding AR2. On jumping into a block where it is nested into the STAT's of the previous block, AR2 points to the address of the first IDB byte.

You can capture this on the first scan and store, to enable offsetting throughout the block

example

AN -First Scan
JC -Over

TAR2
AD DW#16#FFFFFF // get rid of first 3 bytes
T #STAT_Offset

Over:
 
For the record, I would NEVER address the local data absolutely in my code. It is just too dangerous, because like you say, anyone could add a temp variable and throw everything off.

I used absolute addressing in my example above for the sake of simplicity just to show how the "L P#x0.0" could be useful, but in the real world I would have done something like this:

LAR1 P##tempPointer
L 20
SLD 3
L P#DIX 0.0
OD
T LD[AR1,P#6.0]
 
Hi guys,


Heres the part which still confuses me?

siemens A+D entry:11229421
  1. L B[AR1,P#1.0] //reads the ID of the data type of the actual parameter in Accu 1
  2. L W[AR1,P#2.0] //reads the repeat factor in Accu 1
  3. L W[AR1,P#4.0] //reads the DB number of the data block in which the actual parameter is stored in Accu 1.
  4. L D[AR1,P#6.0] //reads the cross-area pointer that points to the actual parameter in Accu 1.
Berger STL book
Byte 0 -16#10
Byte 1 -Type
Byte2+3 - Quantity
Byte4+5 - DataBlock number
Byte6,7,8+9 - Area Pointer

Which one is the more accurate discription?
Byte2+3 Quantity or repeat factor?

i dont see 16#10 either in Byte 0?

If you L B[ar1,P#0.0] and then Transfer to #Temp_Byte0, should you see this value?

Am i understanding correctly that if you use B[AR1,P#0.0] then you are pointing to the furthest Left Byte of the 80 bits?

i.e
80 bit

|Byte0|Byte1|Byte2|Byte3|Byte4|Byte5|Byte6|Byte7|Byte8|Byte9|


Hope this makes sense!!
Thanks STL
 
They both read the same to me, just different terminology, I would confuse you by calling it length.

Byto zero is always B#16#10, this signifies STEP 7 (don't know what else it could be??)

Furthest left, well yes I suppose so, I prefer to look at it as 5 successive words.

The format:

ANY.JPG



Word 1 = Byte 0, Byte 1 = W#16#10xx, where xx = data type as below.


ANY_TYPE.JPG



Word 2 = Byte 2, Byte 3 = Length

Word 3 = Byte 4, Byte 5 = Data Block Address

DWord 4,5 = Byte 6, Byte 7, Byte 8, Byte 9 = Memory Area and Address.

Memory area Hex values being as below:

ANY_MEM.JPG


Notice the 'V' previous local flags. If you use something like SFC20, block move and you are transferring for example, a chunk of data from a dat block into the local area (something I've done where I use FC's). Once you are in the SFC, the local area you are transferring into is in the previous block, i.e. NOT SFC20, therefore instead of the destination local area being L, it is V, therefore the calling blocks local area is written to.
 
Last edited:
I think using of POINTER and ANY is useful only with SFB and SFC. If you want to make some logic with data in DBs and want to address data indirectly, using DB numbers and offsets as separate parameters is much more easier. You don't need to create a S7 pointers before FC call and to divide it to separate fields in FC. For example, this:

L Var1_offset
sld 3
t pVar1
L Var2_offset
sld 3
t pVar2
L Var3_offset
sld 3
t pVar3
opn db[DBnum1]
l dbw[pVar1]
opn db[DBnum2]
l dbw[pVar2]
aw
opn db[DBnum3]
t dbw[pVar3]
 
Hi Peter,

This is the Test i tried:

L P##DATA
LAR1
L B [AR1,P#0.0]
T #STAT_BYTE_0
L B [AR1,P#1.0]
T #STAT_BYTE_1
L B [AR1,P#2.0]
T #STAT_BYTE_2
L B [AR1,P#3.0]
T #STAT_BYTE_3
L B [AR1,P#4.0]
T #STAT_BYTE_4
L B [AR1,P#5.0]
T #STAT_BYTE_5
L B [AR1,P#6.0]
T #STAT_BYTE_6
L B [AR1,P#7.0]
T #STAT_BYTE_7
L B [AR1,P#8.0]
T #STAT_BYTE_8
L B [AR1,P#9.0]
T #STAT_BYTE_9


Which returned the following values for P#DB30.DBX0.0
DB.JPG


Byte_1 = 1E Hex 30 dec ~ DB30
Byte_2 = Hex84 ~ DB

Byte_0 is empty? as is the rest of the Bytes?
 
Byte_0 is empty because you use POINTER, not ANY_POINTER.

Format of the Parameter Type POINTER



The following figure shows the type of data that is stored in each byte.





BAS00348.gif




The parameter type POINTER stores the following information:



  • DB number (or 0 if the data are not stored in a DB)
  • Memory area in the CPU (the following table shows the hexadecimal codes of the memory areas for the parameter type POINTER)

Hexadecimal Code
Memory Area
Description
b#16#81
I
Input area
b#16#82
Q
Output area
b#16#83
M
Bit memory area
b#16#84
DB
Data block
b#16#85
DI
Instance data block
b#16#86
L
Local data (L stack)
b#16#87
V
Previous local data




  • Address of the data (in the format Byte.Bit)
STEP 7 provides the pointer format: p#memory_area byte.bit_address. (If the formal parameter was declared as the parameter type POINTER, you only need to indicate the memory area and the address. STEP 7 automatically reformats your entry into pointer format.) The following examples show how you enter the parameter type POINTER for the data that start at M50.0:



  • P#M50.0
  • M50.0 (if the formal parameter was declared as POINTER).
 

Similar Topics

i write code STL and simulate but result Q2.7 not set , i dont know why :scratch: , help me plz thanks LAR1 P#Q2.7 S [AR1,P#0.0] or LAR P#2.7...
Replies
3
Views
1,702
Hi Folks, I'm having problems completing a FB and suspect my pointer programming maybe the issue. The purpose of the FB is to transfer a...
Replies
13
Views
10,611
I just want to set db2.dbx0.0 when q100.0 is on, just trying to learn pointer. Please help what i m doing wrong. thank for help..... L 2...
Replies
8
Views
1,643
Hi all, I have the following FC: FC100 INPUT TRACK_NR := dint FUNCTIE_NR := dint BITJE := bool INPUT/OUTPUT FUNCTIE_WOORDEN :=...
Replies
5
Views
2,052
Hi I am looking into code to set a block of 8 booleans within a datablock, depending on the condition of 8 'flags'. The start bit of the 8 bools...
Replies
13
Views
3,582
Back
Top Bottom