S7 dynamic addressing PIW area

andyhill

Member
Join Date
Sep 2003
Location
Aberdeen
Posts
5
What I need to do is be able via code suitable for S70-315DP ( STL, LAD etc) to store a base address eg PIW 216 and then read the next 8 addresses eg PIW 216 , PIW 220, PIW224 ... PIW 232 using some sort of for next loop.


If this was written in VB/Delphi (high level language it may look like

base = 216
j = 0
for i = 0 to 7
// Build Up Read Address eg PIW 216 or PIW 218 etc.

Address = "PIW" + BASE + J
// read value from Address
Val = Read ( Address)
//Increment Counter
J = J + 4
next i

Result of this block would end up with an array filled with the valves read in from the PIW addresses.


I have tried to define a "pointer" and add p#PIW216 but it won't take this. banghead Alternately If I could store the addresses in a Datablock and read eg DB1.Firstaddress then use that to read to PIW.

I need this functionality from both PIW and PQW areas of memory.



Andy :confused:
 
Hi Andy-
I think you want to use what is called 'memory indirect addressing'. In your Step7 Manager, go to Help -> Contents and type "memory indirect" in the find box. Then select 'Using the parameter type POINTER' from the topic list. This will give you the general idea.

Basically you know the data area you want to access (PIW or PQW). So you dont need to bury that in the pointer. you are just worried about memory offsets inside a given area. Your pointer manipulation would look kind of like this:

L P#216.0 ;sets the base of the pointer offset
T MD20 ;transfer pointer base to a double
L P#30.0 ;sets base for destination
T MD24 ;transfer pointer base to double

NewW: L PIW[MD20] ;load in the word pointer to
T MW[MD24] ;transfer value to destination
L MD20 ;load in peripheral word pointer
L P#2.0 ;load word offset for next word as pointer
+D ;add pointer and offset
T MD20 ;transfer to peripheral word pointer
L MD24 ;load destination pointer
L P#2.0 ;load word offset in pointer format
+D ;add pointer and offset
T MD24 ;transfer to destination word pointer

;required iteration check logic

JCN NewW ;return to top of read section

I hope this helps.

Keith
 
Last edited:
I have a question which fits in with this dynamic addressing. How can I use this type of indexing with a Data Block? or can I ?


Thanks

Joe
 
Hi Andy..

You can use also something like this:

L P#216.0 // sets the base of the pointer offset
L LAR1 // charge the register of address

L P#30.0 // sets base for destination
L LAR2

NewW: L PIW[LAR1, 0.0] // load in the word pointer to
T MW[LAR2, 0.0] // transfer value to destination

+ AR1, 2.0 // load word offset for next word as pointer
+ AR2, 2.0 // load word offset in pointer format

loop NewW

CLR

I hope this helps. ;)
 
Hi Joe-
I haven't been able to find a way to convert a whole DB address to a pointer. I think part of the problem is that a full pointer including the DB number would cover 6 bytes. Most of the processors in the S7-300 family only have 4 bytes worth of accumulator room.
I have done DB access using pointers in the past. I did it as a two step process to define both the DB number and the register location.

Here is what I did:

L   16                   ;load or calculate the DB number
T MW10 ;transfer to DB pointer location
L P#0.0 ;load register base address as pointer
T MD20 ;transfer to register pointer location

OPN DB[MW10] ;open the desired DB
L DBD[MD20] ;load the register pointed to




You can manipulate both MW10 and MD20 as required to get what you want. Pointers are bit sensitive. If you look at the pointer format three bits in the pointer are used to define a bit location. So if you are going to increment by a known byte count an easy way to do this is something like:

L P#2.0
L MD20
+D
T MD20

If your byte index is variable you can do something like:

L Byte_Location
L 8
*I
L MD20
+D
T MD20

I hope this helps.

Keith
 
Some code I just happen to be working on.

This copies data ( reals ) from a Instance DB to a DB somewhere in the S7. I just got through testing this so I know it works. These parts are a fragment of a FB that handle transfering back and forth between an S7 and a motion controller using Profibus DP.

My conventions. Local and Stat variables start with a _. All simple types start with a letter that signifies its type.

I used a memory and register pointer because one should use DI and AR2 in project that support multi instance FBs.

Code:
      L     P##_RMC75RD                 // Need to point to _RMCRD.Data[0]
      L     P#4.0
      +D    
      T     #_pRMC                      // Use indirect pointer because we can't use AR2 or DI

      L     #_nS7DB                     // Need to do this as OPN DB does not
      T     #_wTemp                     // work with STAT data.
      OPN   DB [#_wTemp]

      L     #_pS7                       // Load area crossing pointer dw#8400000
      LAR1  

      L     #_nCount                    // copy here
L31:  T     #_nI
      L     DID [#_pRMC]
      T     DBD [AR1,P#0.0]             // Store in the S7 somewhere
      L     #_pRMC                      // increment pSrc
      L     P#4.0
      +D    
      T     #_pRMC
      +AR1  P#4.0                       // increment pDst
      L     #_nI
      LOOP  L31

This copies data from some where in the S7 to the instance data block


Code:
L65:  L     P##_RMC75WR                 // Need to point to _RMCRD.Data[0]
      L     P#4.0
      +D    
      T     #_pRMC                      // Use indirect pointer because we can't use AR2 or DI

      L     #_nS7DB                     // Need to do this as OPN DB does not
      T     #_wTemp                     // work with STAT data.
      OPN   DB [#_wTemp]

      L     #_pS7                       // Load area crossing pointer dw#8400000
      LAR1  

      L     #_nCount                    // Get data to send.
L67:  T     #_nI
      L     DBD [AR1,P#0.0]             // Get from S7 somewhere
      T     DID [#_pRMC]                // Store in RMC75WR
      L     #_pRMC                      // increment pSrc
      L     P#4.0
      +D    
      T     #_pRMC
      +AR1  P#4.0                       // increment pDst
      L     #_nI
      LOOP  L67
 
Solutions look good . I'll go and give they a try. From what I can see these look like they'll work.

Thanks All


Andy :site:
 
Poiter on S7

My idea:
Code:
[FONT=monospace]
L     #Count[/FONT]
[FONT=monospace]INC   1                          //counter increment
[/FONT][FONT=monospace]T     #Count

L     #Count
SLW 4
T     #Pointer_Word_in_DB        //create pointer with counter

OPN DB1
L DBW[#Pointer_Word_in_DB]       // ACU is load DB1.DBWCounter[/FONT]
My idea example picture

Struktura_Wska%C5%BAnika_S7.png


Example 2.

Code:
[FONT=monospace]
[/FONT]//PIW277 Analog card 
L 277 
SLW 3
T #Adres_Analog
L PIW[#Adres_Analog]

 
Last edited:
Wow, an 11 year old topic raised from the dead. Must be a record :).
 

Similar Topics

Hey, I'm having trouble with moving data within a DB and I think the problem is rooted in my lack of understanding of programming 'pointers' so...
Replies
27
Views
6,018
Hey Guys! Wondering if anyone here knows if it's possible to address area blocks in a PLC via pointers in WinCC Flexible. I need to...
Replies
6
Views
4,493
Rockwell Tech Support seemed to have hit a wall with this question. Already updated the version to 5.00.13 per their suggestio but am still...
Replies
1
Views
58
Maybe this is just not possible, or maybe I am doing something wrong. Background; I have a data array of over 1500 products. For sorting I...
Replies
6
Views
727
HEllo, still satruggling with the curse WinCC Unified. See attached picture. I just want to change the fill colour from turqoise to grey and then...
Replies
5
Views
407
Back
Top Bottom