![]() ![]() ![]() ![]() ![]() ![]() |
||
![]() |
||
![]() ![]() ![]() ![]() This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc. |
||
![]() |
![]() |
#1 |
Member
![]() ![]() Join Date: Sep 2003
Location: Aberdeen
Posts: 5
|
S7 dynamic addressing PIW area
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[i] = 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 ![]()
__________________
Scot's do it better in Kilts !!! |
![]() |
![]() |
#2 |
Member
|
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 by kamenges; September 10th, 2003 at 01:57 PM. |
![]() |
![]() |
#3 |
Member
|
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 |
![]() |
![]() |
#4 |
Member
|
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. ![]()
__________________
Tony ![]() |
![]() |
![]() |
#5 |
Member
|
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 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 |
![]() |
![]() |
#6 |
Member
|
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 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 |
![]() |
![]() |
#7 |
Member
![]() ![]() Join Date: Sep 2003
Location: Aberdeen
Posts: 5
|
![]()
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 ![]()
__________________
Scot's do it better in Kilts !!! |
![]() |
![]() |
#8 |
Member
|
Thanks...I am going to give this a try.
Joe |
![]() |
![]() |
#9 |
Member
![]() ![]() Join Date: Jan 2015
Location: dfasdf
Posts: 1
|
Poiter on S7
My idea:
Code:
L #Count INC 1 //counter increment 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 ![]() Example 2. Code:
//PIW277 Analog card L 277 SLW 3 T #Adres_Analog L PIW[#Adres_Analog] Last edited by mateczek; January 18th, 2015 at 03:54 PM. |
![]() |
![]() |
#10 |
Lifetime Supporting Member + Moderator
![]() ![]() Join Date: Feb 2008
Location: OKC
Posts: 1,614
|
Wow, an 11 year old topic raised from the dead. Must be a record
![]() |
![]() |
![]() |
Bookmarks |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Display Modes | |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Siemens s7 ladder indirect addressing | guest | LIVE PLC Questions And Answers | 22 | March 7th, 2022 10:17 AM |
Siemens S7 indexed addressing | PLCdave | LIVE PLC Questions And Answers | 15 | March 25th, 2015 06:43 PM |
MPI comunication | Manuel Raposo | LIVE PLC Questions And Answers | 22 | July 16th, 2007 07:24 AM |
S7 - DP Addressing | RMA | LIVE PLC Questions And Answers | 16 | February 9th, 2005 03:56 AM |
S7 Area Length Fail | kennyb | LIVE PLC Questions And Answers | 6 | January 31st, 2005 04:37 PM |