-->

Converting 32-Bit Real to 2x 16-Bit Bytes

2019-09-08 00:13发布

问题:

I'm trying to send a 32-Bit Real across a CAN communications (IFM) but the CAN comms only accepts a 16-Bit value.

If the value I'm trying to send goes above 255, it resets back to 0 and continues in that pattern. I therefore need to split the 32-Bit Real value in to two 16-Bit values and then reassemble on the other side of the comms.

I just can't seem to get my head around how to do it in structured text.

Any help would be appreciated

回答1:

I know I am a little late to the party but wanted to add this as a solution.

VAR
  rRealVar  :   REAL;
  awWordArray   :   ARRAY[0..1] OF WORD;
  pTemp     :   POINTER TO REAL;
  pTemp2        :   POINTER TO REAL;
END_VAR

// Get a pointer to the REAL variable
pTemp := ADR(rRealVar);

// Get a pointer to the ARRAY base
pTemp2 := ADR(awWordArray);

// Assign the value of the REAL variable into the ARRAY base
pTemp2^ := pTemp^;

(* Index 0 := Bits 15-0
   Index 1 := Bits 31-16

This is similar to Felix Keil's answer but it makes use of 2 pointer variables and a word array to retrieve the information directly.



回答2:

First. I have no experience with CAN and I don't know which FBs you use to send them. But if it resets over 255 it seems like you can only send 8bit-values (bytes) instead of 16bit.

Second. I would suggest an UNION Solution (REAL_BYTE_SIZE = 4):

The variables in an UNION share the same memory. Therefore they can be interpreted in different ways

TYPE U_RealForCanBus :
UNION
rValue : REAL;
arrbyBytes : ARRAY[1..REAL_BYTE_SIZE] OF BYTE;
END_UNION
END_TYPE

If you declare a

uRealToSendOverCan : U_RealForCanBus;

you can set uRealToSendOverCan.rValue and read uRealToSendOverCan.arrbyBytes

Or you could just do MEMCPY if you don't want the variables to share the memory:

rValue : REAL;

arrbyToSend : ARRAY[1..REAL_BYTE_SIZE] OF BYTE;


MEMCPY(ADR(arrbyToSend ),ADR(rValue),REAL_BYTE_SIZE);

Or you can always use a pointer to interpret the memory in a different way:

rValue : REAL;

parrbyToSend : POINTER TO ARRAY[1..REAL_BYTE_SIZE] OF BYTE;


parrbyToSend := ARD(rValue); //Initialize pointer

parrbyToSend^[2] ... //Second Byte of rValue