You are not registered yet. Please click here to register!


 
 
plc storereviewsdownloads
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc.
 
Try our online PLC Simulator- FREE.  Click here now to try it.

New Here? Please read this important info!!!


Go Back   PLCS.net - Interactive Q & A > PLCS.net - Interactive Q & A > LIVE PLC Questions And Answers

Reply
 
Thread Tools Display Modes
Old August 7th, 2007, 02:37 PM   #1
drspanda
Member
India

drspanda is offline
 
Join Date: Oct 2005
Location: Damanjodi
Posts: 155
Question Not able to understand this S7-code

Dear S7 Experts,

After several attempts I have come to conclusion that I should seek your help...The below is the stl source code.

FC311 calls FC1008 and DB900 is the data block which is passed into FC1008..

I am not able to intrepret the code and the data movement/manuplation in the DB900...and also I am not getting the concept why the programmer is using SLD3 for multiplication by 8.

Advance thanks.


FUNCTION FC 311 : VOID
TITLE =Pusher
VERSION : 0.1


VAR_TEMP
sp_push_time_int : REAL ;
table : ARRAY [0 .. 19 ] OF REAL ;
END_VAR
BEGIN
NETWORK
TITLE =Pusher-Speed_ convert time to valve position (lookUpTable)


A M 0.1;
= L 84.0;
BLD 103;
CALL FC 1008 (
Table := DB 900,
Input := MD 1652,
low := 7.500000e+001,
high := 2.100000e+002,
invert := L 84.0,
output := MD 1644);
NOP 0;
END_FUNCTION


DATA_BLOCK DB 900
TITLE =
VERSION : 0.1



STRUCT
POS_0 : REAL := 7.500000e+001;
POS_05 : REAL := 7.600000e+001;
POS_10 : REAL := 7.700000e+001;
POS_15 : REAL := 7.800000e+001;
POS_20 : REAL := 7.900000e+001;
POS_25 : REAL := 8.100000e+001;
POS_30 : REAL := 8.500000e+001;
POS_35 : REAL := 9.000000e+001;
POS_40 : REAL := 9.900000e+001;
POS_45 : REAL := 1.290000e+002;
POS_50 : REAL := 1.500000e+002;
POS_55 : REAL := 1.800000e+002;
POS_60 : REAL := 2.100000e+002;
POS_65 : REAL := 2.100000e+002;
POS_70 : REAL := 2.100000e+002;
POS_75 : REAL := 2.100000e+002;
POS_80 : REAL := 2.100000e+002;
POS_85 : REAL := 2.100000e+002;
POS_90 : REAL := 2.000000e+003;
POS_95 : REAL := 2.100000e+003;
POS_100 : REAL := 2.100000e+002;
END_STRUCT ;
BEGIN
POS_0 := 7.500000e+001;
POS_05 := 7.600000e+001;
POS_10 := 7.700000e+001;
POS_15 := 7.800000e+001;
POS_20 := 7.900000e+001;
POS_25 := 8.100000e+001;
POS_30 := 8.500000e+001;
POS_35 := 9.000000e+001;
POS_40 := 9.900000e+001;
POS_45 := 1.290000e+002;
POS_50 := 1.500000e+002;
POS_55 := 1.800000e+002;
POS_60 := 2.100000e+002;
POS_65 := 2.100000e+002;
POS_70 := 2.100000e+002;
POS_75 := 2.100000e+002;
POS_80 := 2.100000e+002;
POS_85 := 2.100000e+002;
POS_90 := 2.100000e+002;
POS_95 := 2.100000e+002;
POS_100 := 2.100000e+002;
END_DATA_BLOCK


FUNCTION FC 1008 : VOID
TITLE =
VERSION : 0.1



VAR_INPUT
Table : BLOCK_DB ;
Input : REAL ;
low : REAL ;
high : REAL ;
invert : BOOL ;
END_VAR
VAR_OUTPUT
output : REAL ;
END_VAR
VAR_TEMP
index : INT ;
pointer_min : DINT ;
pointer_max : DINT ;
min : REAL ;
max : REAL ;
input_int : REAL ;
dummy : REAL ;
END_VAR
BEGIN
NETWORK
TITLE =limit imput value


A M 0.1;
= L 26.0;
A L 26.0;
JNB _001;
L #Input;
T #input_int;
_001: NOP 0;
A L 26.0;
A( ;
L #Input;
L #high;
>R ;
) ;
JNB _002;
L #high;
T #input_int;
_002: NOP 0;
A L 26.0;
A( ;
L #Input;
L #low;
<R ;
) ;
JNB _003;
L #low;
T #input_int;
_003: NOP 0;
NETWORK
TITLE =


OPN #Table;

NETWORK
TITLE =
//5*(index-((max-input)/(max-min)))
L 1; //start index
T #index;


loop: L #index; //create pointer
L 4;
*I ;
SLD 3;
T #pointer_max;


L #index; //create pointer+1
L 1;
-I ;
L 4;
*I ;
SLD 3;
T #pointer_min;



//compare
L #input_int;
L DBD [#pointer_max];
<=R ;
JCN inc;


//calc
L DBD [#pointer_max];
L DBD [#pointer_min];
-R ;
L 1.000000e-009; // no div by 0
+R ;
T #dummy;


L DBD [#pointer_max];
L #input_int;
-R ;
L #dummy;
/R ;


L #index;
ITD ;
DTR ;
TAK ;
-R ;
L 5.000000e+000;
*R ;
T #output;
JU end;


inc: L #index;
L 1;
+I ;
T #index;
JU loop;


end: NOP 0;



NETWORK
TITLE =invert output


A #invert;
JCN end1;
L 1.000000e+002;
L #output;
-R ;
T #output;
end1: NOP 0;
END_FUNCTION




  Reply With Quote
Old August 7th, 2007, 02:48 PM   #2
PeterW
Member
Canada

PeterW is offline
 
Join Date: Jun 2006
Location: Calgary, AB
Posts: 2,531
'also I am not getting the concept why the programmer is using SLD3 for multiplication by 8.'

This is OK if you are confident the result will not overflow.

Its to do with binary.

Shift Left 1 = Multiply by 2
Shift Left 2 = Multiply by 4
Shift Left 3 = Multiply by 8
Shift Left 4 = Multiply by 16
etc.

Example for 8 bits.

0000 0001 = 1
Shift by 1 = 0000 0010 = 2
Shift by 2 = 0000 0100 = 4
Shift by 3 = 0000 1000 = 8
Shift by 4 = 0001 0000 = 16
etc..



edit: had to edit the Shift, I had accidently left out the 'f' and the then cut and paste, result loads of ****

Last edited by PeterW; August 7th, 2007 at 02:50 PM.
  Reply With Quote
Old August 7th, 2007, 02:57 PM   #3
PeterW
Member
Canada

PeterW is offline
 
Join Date: Jun 2006
Location: Calgary, AB
Posts: 2,531
I also don't have S7, so looking at the code is awkward, but just noticed, the SLD3 is not multiplying by 8, but setting up a pointer. (Should have guessed really).

Pointer format, 32 bits

mmmm mmmm 0000 0bbb bbbb bbbb bxxx

where:

m = code for data type
0 = not used
b = byte address
x = bit address

so the SLD3 is moving the byte address over to the correct area of the double word.
  Reply With Quote
Old August 7th, 2007, 03:21 PM   #4
PeterW
Member
Canada

PeterW is offline
 
Join Date: Jun 2006
Location: Calgary, AB
Posts: 2,531
From this point:

Code:
 NETWORK
  TITLE =
  //5*(index-((max-input)/(max-min)))
  L 1; //start index
  T #index;
 


Presets index to 1.

Code:
 loop: L #index; //create pointer
  L 4; 
  *I ; 
  SLD 3; 
  T #pointer_max;
 


the loop: part indicates he jumps back to here (as opposed to a LOOP instruction)


On the first run index =1, therefore 1 * 4 = 4, shift left 3 and stores at pointer max., this will point to byte 4.

Code:
 L #index; //create pointer+1
  L 1; 
  -I ; 
  L 4; 
  *I ; 
  SLD 3; 
  T #pointer_min;
 


Index = 1, therefore 1-1 = 0, 0*4 = 0, after shifting will point to byte 0.

Code:
 //compare
  L #input_int; 
  L DBD [#pointer_max]; 
  <=R ; 
  JCN inc;
 


This is comparing the input against DBD4


If the input is NOT less than or equal to DBD4, it will jump to label inc.

Code:
 //calc
  L DBD [#pointer_max]; 
  L DBD [#pointer_min]; 
  -R ; 
  L 1.000000e-009; // no div by 0
  +R ; 
  T #dummy; 
  
  L DBD [#pointer_max]; 
  L #input_int; 
  -R ; 
  L #dummy; 
  /R ; 


Subtract DBD0 from DBD4 and adds 1 (edit: sorry not 1, but a very small number) (=dummy), he then subtracts the INPUT from DBD4 and divides by the dummy value.

Code:
 L #index; 
  ITD ; 
  DTR ; 
  TAK ; 
  -R ; 
  L 5.000000e+000; 
  *R ; 
  T #output; 
  JU end;


Then he takes the INDEX value and converts from Integer to Double Integer (ITD), then from Double Integer to real (DTR).

TAK swaps the ACCUís around, so the modified INDEX goes to ACCU2 and the previous calc value returns to ACCU 1.

He then subtracts the index value from the previous calc and multiples by 0.5.

Then transfers it to the output.

Had he jumped to inc after the earlier compare, he increments INDEX and goes back to loop.

Thereís a little bit at the end where he inverts the output if required.


I donít know if I missed it but it looks as if it could go in an eternal loop! If the comparison never allows the program to flow through.

Last edited by PeterW; August 7th, 2007 at 03:23 PM.
  Reply With Quote
Old August 8th, 2007, 10:06 AM   #5
drspanda
Member
India

drspanda is offline
 
Join Date: Oct 2005
Location: Damanjodi
Posts: 155
Question Am I missing simple thing?

Dear PeterW,

I am not able to understand why on the first scan #pointer_max contains/refers to the location DBD4?
#pointer_max should contain 32 and L DBD [#pointer_max] should refer to DBD32...Why it is not so here??

OPN #Table //Data Block
L #index //index =1 on first instance.
L 4
*I
SLD 3
T #pointer_max

Am I missing a simple thing?
  Reply With Quote
Old August 8th, 2007, 10:22 AM   #6
jacekd
Member
Poland

jacekd is offline
 
jacekd's Avatar
 
Join Date: Jan 2004
Location: Radom/Poland
Posts: 262
Yes. The last 3 bits in pointer are decoded as number of a bit. That's why there's "SLD 3".
__________________
jacekd
  Reply With Quote
Old August 8th, 2007, 11:54 AM   #7
PeterW
Member
Canada

PeterW is offline
 
Join Date: Jun 2006
Location: Calgary, AB
Posts: 2,531
Quote:
Originally Posted by PeterW
I also don't have S7, so looking at the code is awkward, but just noticed, the SLD3 is not multiplying by 8, but setting up a pointer. (Should have guessed really).

Pointer format, 32 bits

mmmm mmmm 0000 0bbb bbbb bbbb bxxx

where:

m = code for data type
0 = not used
b = byte address
x = bit address

so the SLD3 is moving the byte address over to the correct area of the double word.

To answer your question, re-look at this.

The SDL3 is NOT multiplying by 8.

The SLD3 is moving the Number, in the first case 4, to match up with the byte address.

4 = 100 in binary, after SLD3 it = 100000, now match this to the pointer format.

mmmm mmmm 0000 0bbb bbbb bbbb bxxx
0000 0000 0000 0000 0000 0010 0000

Taking just the b's which is the byte address

bbb bbbb bbbb b
000 0000 0010 0

this = byte 4.
  Reply With Quote
Old August 8th, 2007, 01:51 PM   #8
drspanda
Member
India

drspanda is offline
 
Join Date: Oct 2005
Location: Damanjodi
Posts: 155
Smile Thank You Very Much

Dear PeterW,

Thank you very much...now I have understood the concept...

L 4.000000e+000
T DB1.DBD 24

//In this case the 4.0 will be transferred to DB1.DBD 24
//open DB1
OPN DB1
// load decimal 36
L 36
// multiply with 8
SLD 3
// Transfer the result 8x8=64 to MD30.
T MD 30
// Load real number 10.8
L 1.080000e+001
// Transfer to already opened DB1 at memory byte
// location specified by the pointer MD30
T DBD [MD 30]
So When we use square brackets then compiler treats MD30 as a pointer not its value, which is 64....Binary equivalent of 64 is taken and from that, using rules of pointer addressing its value is obtained to be 36.

And finally 10.8 is transferred to DB1.DBD36
  Reply With Quote
Old November 13th, 2007, 02:06 PM   #9
drspanda
Member
India

drspanda is offline
 
Join Date: Oct 2005
Location: Damanjodi
Posts: 155
Exclamation better late than never...

Quote:
Originally Posted by drspanda
SLD 3
// Transfer the result 8x8=64 to MD30.
T MD 30
// Load real number 10.8
L 1.080000e+001
// Transfer to already opened DB1 at memory byte
// location specified by the pointer MD30
T DBD [MD 30]
So When we use square brackets then compiler treats MD30 as a pointer not its value, which is 64....Binary equivalent of 64 is taken and from that, using rules of pointer addressing its value is obtained to be 36.

And finally 10.8 is transferred to DB1.DBD36
I have made a mistake and today when I am refering to my own thread feel to correct it....
SLD 3
// Transfer the result 36x8=288 to MD30.
T MD 30
// Load real number 10.8
L 1.080000e+001
// Transfer to already opened DB1 at memory byte
// location specified by the pointer MD30
T DBD [MD 30]
So When we use square brackets then compiler treats MD30 as a pointer not its value, which is 288....Binary equivalent of 288 is taken [0001_0010_0000]and from that, using rules of pointer addressing its value is obtained to be [0001_0010_0] or simply [100100]....is equivalent to 36.

And finally 10.8 is transferred to DB1.DBD36
  Reply With Quote
Reply
Jump to Live PLC Question and Answer Forum


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Topics
Thread Thread Starter Forum Replies Last Post
Simplify some S7 STL code userxyz LIVE PLC Questions And Answers 13 November 9th, 2006 08:19 AM
S7 code optimizing... Borte LIVE PLC Questions And Answers 8 September 7th, 2005 04:06 AM
S7 - what's wrong with this code which could cause an endless loop? RMA LIVE PLC Questions And Answers 7 June 14th, 2005 11:40 AM
Simulator, Simulation, Shadow Code Terry Woods LIVE PLC Questions And Answers 1 January 2nd, 2005 03:40 PM
Self Tuned Pid Code For S7 200 GOKALP LIVE PLC Questions And Answers 1 April 12th, 2003 02:07 PM


All times are GMT -4. The time now is 09:18 PM.


.