Trying to split Double Word in S7

uptown47

Lifetime Supporting Member
Join Date
Feb 2008
Location
Over there, next to those boxes
Posts
1,146
Hi all

I'm trying to convert an S5 program to S7 and part of the old S5 program calls FB242. This was a special function block that had the following description:
FB 242 - Multiplier
Use function block FB242 to multiply one fixed point binary number (16 bits) by another. The product is represented by two fixed-point binary numbers (16 bits each). The result is also scanned for zero. An eight-bit number must be transferred to a 16-bit word prior to multiplication.

The following are accepted and returned by the function FB242
Z1 - Multiplier (word)
Z2 - Multiplicand (word)
Z3 - Zero (bool) comes on if result is zero
Z32 - Product, high order word
Z31 - Product, low order word

I've started writing the code for this in its own function within S7 then I can just call it everytime I need it. I've got so far but then got stuck.

I convert the two words passed into function into Double Words so I can use a *D to multiply them. I get the result but how do I split it into a High order word and Low order word??

I've attached the source of my block so far.


FUNCTION "EQUIVALENT OF FB242" : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
MULTIPLIER : WORD ;
MULTIPLICAND : WORD ;
END_VAR
VAR_OUTPUT
RESULT_HIGH_WORD : WORD ;
ZERO_RESULT : BOOL ;
RESULT_LOW_WORD : WORD ;
END_VAR
VAR_TEMP
MULTIPLIER_DWORD : DINT ;
MULTIPLICAND_DWORD : DINT ;
RESULT_DWORD : DINT ;
END_VAR
BEGIN
NETWORK
TITLE =ZERO THE TEMP DOUBLE WORD VALUES
A( ;
L L#0;
T #MULTIPLIER_DWORD;
SET ;
SAVE ;
CLR ;
A BR;
) ;
JNB _001;
L L#0;
T #MULTIPLICAND_DWORD;
_001: NOP 0;
NETWORK
TITLE =MAKE THE INITIAL WORD VALUES INTO DOUBLE WORD FOR MULTIPLICATION
A( ;
L #MULTIPLIER;
T #MULTIPLIER_DWORD;
SET ;
SAVE ;
CLR ;
A BR;
) ;
JNB _002;
L #MULTIPLICAND;
T #MULTIPLICAND_DWORD;
_002: NOP 0;
NETWORK
TITLE =RESULT OF MULTIPLICATION AS DOUBLE WORD
L #MULTIPLIER_DWORD;
L #MULTIPLICAND_DWORD;
*D ;
T #RESULT_DWORD;
NOP 0;
NETWORK
TITLE =CHECK IF RESULT IS ZERO. IF IT IS SET THE ZERO_RESULT BIT.
L #RESULT_DWORD;
L L#0;
==D ;
= #ZERO_RESULT;
END_FUNCTION




A big thanks if you can help me out

Cheers

:)
 
Are the words being multiplied together being treated as unsigned numbers (0-65535) or signed numbers ?
 
You don't need the first segment, you are transferring in values, the high word will be zero after the transfer in any case.

Code:
 [font=courier]L     #MULTIPLIER; 
 T     #MULTIPLIER_DWORD; 
 L     #MULTIPLICAND; 
 T     #MULTIPLICAND_DWORD;

Unless you want to know if the result is zero first, such as

Code:
 // Clear Zero Result
 SET
 R     #ZERO_RESULT;  
 
 //Zero Result
 [font=courier][font=courier]L     0; 
 T     #[/font][/font][/font]RESULT_HIGH_WORD[font=courier][font=courier][font=courier];  
 T     #[/font][/font][/font]RESULT_LOW_WORD[font=courier][font=courier][font=courier];
 
 [font=courier][font=courier][font=courier][font=courier]// Will Result = Zero, if so end here
 L     #MULTIPLICAND;
 L     #MULTIPLIER
 AW
 L     0
 ==I
 S     #ZERO_RESULT;
 BEC
 [/font][/font][/font][/font]// Prepare DWords for muliplication
 L     #MULTIPLIER; 
 T     #MULTIPLIER_DWORD; 
 L     #MULTIPLICAND; 
 T     #MULTIPLICAND_DWORD;
[/font][/font]
[/font]
 
In this case its easier to use a scratch marker double word :whistle:

MD500 can be split easily as MW500 and MW502.

To split the TEMP double word, it can be done easily by accessing the Local area.

If you look at where you declared the TEMP, on the left of the description is the address, the first will be 0, the next 4 and finally 8 (as these are all bytes).

The RESULT you will see 8 next to it, so the DOUBLE WORD Result uses Bytes 8, 9, 10 and 11.

Therefore it can be easily split by directly addressing

L LW8
T High_Byte
L LW10
T Low_Byte

This will work, but if anyone ever modifies the declaration table and adds a new TEMP between Result and the others then the absolute address will change, i.e. Local Double (LD) 8, will no longer be the absolute address of Result.

The best way is to use pointers, I will leave that to Simon as that's his speciality ;)
 
Here's my implementation .... no indirect addressing :)
Code:
	  L	 #MULTIPLICAND
	  ITD   
	  L	 #MULTIPLIER
	  ITD   
	  *D	
	  T	 #RESULT_DWORD
	  T	 #RESULT_LOW_WORD
	  SSD   16
	  T	 #RESULT_HIGH_WORD
	  L	 #RESULT_DWORD
	  L	 L#0
	  ==D   
	  =	 #ZERO_RESULT
 
Peter

I wasn't sure if I could address local data like that. I've read a few things about "local" data but I've never actually addressed the variables like that.

A big thank you for clearing that up for me.

Cheers

:)
 
As already noted, do not refer to local data using LW, create a named variable and use indirect addressing to acces the parts you want, e.g.

Code:
	  L	 #MULTIPLICAND
	  ITD   
	  L	 #MULTIPLIER
	  ITD   
	  *D	
	  T	 #RESULT_DWORD
	  LAR1  P##RESULT_DWORD
	  L	 W [AR1,P#2.0]
	  T	 #RESULT_LOW_WORD
	  L	 W [AR1,P#0.0]
	  T	 #RESULT_HIGH_WORD
	  L	 #RESULT_DWORD
	  L	 L#0
	  ==D   
	  =	 #ZERO_RESULT
 
L D[AR2 said:
As already noted, do not refer to local data using LW, create a named variable and use indirect addressing to acces the parts you want, e.g.

Code:
	 L	 #MULTIPLICAND
	 ITD 
	 L	 #MULTIPLIER
	 ITD 
	 *D	
	 T	 #RESULT_DWORD
	 LAR1 P##RESULT_DWORD
	 L	 W [AR1,P#2.0]
	 T	 #RESULT_LOW_WORD
	 L	 W [AR1,P#0.0]
	 T	 #RESULT_HIGH_WORD
	 L	 #RESULT_DWORD
	 L	 L#0
	 ==D 
	 =	 #ZERO_RESULT

My word!!!!!

Easy when you know how eh?!??!

Brilliant that Simon. Many thanks. I'll be using that instead of my convoluted effort.

Cheers

:geek:
 

Similar Topics

I can't seem to get the Panel View Plus 7 standard edition to downgrade to V_11, when I check the AB downloads and compatibility websites for this...
Replies
1
Views
135
Hi I used to be able to launch PLCsim without any problem. Now it tells me " STEP 7 Professional Licence is required to simulate this PLC"...
Replies
15
Views
516
Hello! When trying to load the hardware configuration I get error 0050-133 2 2458, check the diagnostic buffer. When checking the buffer, it says...
Replies
4
Views
183
We have a keg check weigher that that lost a fight to a forklift. The scale was previously a Systec IT3000, which was the only PROFIBUS slave...
Replies
5
Views
672
Back
Top Bottom