Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- FUNCTION "fc_Calc_CRC32_V15.0.4" : DWord
- { S7_Optimized_Access := 'TRUE' }
- VERSION : 0.1
- VAR_INPUT
- Buffer : Variant;
- END_VAR
- VAR_OUTPUT
- ob_Error : Bool; // Error with Varriant Input
- END_VAR
- VAR_TEMP
- tempBuffer : Array[0..#MaxArray] of Byte;
- tempByte : Byte;
- tempMaxIndex : UDInt;
- tempRetVal : Int;
- tempRem : DWord;
- tempI : Int;
- tempJ : Int;
- END_VAR
- VAR CONSTANT
- POLYNOMIAL : DWord := 16#ABCD_EF01; // oder besser 16#EDB8_8320 ?
- MaxArray : Int := 64;
- END_VAR
- BEGIN
- // Ist Varriant passend?
- IF IS_ARRAY(#Buffer) AND TypeOfElements(#Buffer) = Byte AND
- CountOfElements(#Buffer) < #MaxArray THEN
- #tempMaxIndex := CountOfElements(#Buffer);
- // Erzeuge eine Byte Array für den CRC32 Code
- #tempRetVal := MOVE_BLK_VARIANT(SRC := #Buffer, COUNT := #tempMaxIndex,
- SRC_INDEX := 0, DEST_INDEX := 0, DEST => #tempBuffer);
- // http://www.hedeby.net/2018/03/28/crc32-function-for-simatic/
- // If the function does not work as expected, it’s often because the endianess
- // is not correct between sender and receiver.
- // Change the #rem.%X0 bit to #rem.%X31 to see if it helps.
- #tempRem := 16#FFFF_FFFF;
- FOR #tempI := 0 TO UDINT_TO_INT(#tempMaxIndex) - 1 DO
- #tempRem := #tempRem XOR #tempBuffer[#tempI];
- FOR #tempJ := 0 TO 7 DO
- IF #tempRem.%X0 THEN // if leftmost (most significant) bit is set
- #tempRem := SHR(IN := #tempRem, N := 1) XOR #POLYNOMIAL;
- ELSE
- #tempRem := SHR(IN := #tempRem, N := 1);
- END_IF;
- END_FOR;
- END_FOR;
- #"fc_Calc_CRC32_V15.0.4" := #tempRem XOR 16#FFFF_FFFF;
- ELSE
- // NULL zurück wenn Varriant nicht passt
- #"fc_Calc_CRC32_V15.0.4" := 0;
- #ob_Error := true;
- END_IF;
- END_FUNCTION
- FUNCTION "fc_Zufall_DWord_V15.0.4" : DWord
- { S7_Optimized_Access := 'TRUE' }
- VERSION : 0.1
- VAR_INPUT
- idw_seed : DWord;
- END_VAR
- VAR_OUTPUT
- ob_Error : Bool; // Error with Varriant Input
- END_VAR
- VAR_TEMP
- temp_array : Array[0..15] of Byte;
- temp_dtl {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
- temp_dint : DInt;
- temp_int : Int;
- END_VAR
- BEGIN
- // Zeit lesen
- #temp_int := RD_SYS_T(#temp_dtl);
- #temp_dint := 0;
- // Zeit in Byte Array kopieren
- #temp_int := Serialize(SRC_VARIABLE := #temp_dtl, DEST_ARRAY => #temp_array, POS := #temp_dint);
- IF #temp_int = 0 THEN
- // Seed initialisieren
- #temp_array[12] := #idw_seed.%B0;
- #temp_array[13] := #idw_seed.%B2;
- #temp_array[14] := #idw_seed.%B1;
- #temp_array[15] := #idw_seed.%B3;
- // Berechne CRC32 aus Byte Array
- #"fc_Zufall_DWord_V15.0.4" := "fc_Calc_CRC32_V15.0.4"(Buffer := #temp_array, ob_Error => #ob_Error);
- ELSE
- #ob_Error := true;
- #"fc_Zufall_DWord_V15.0.4" := 0;
- END_IF;
- END_FUNCTION
- FUNCTION "fc_Zufall_Real_V15.0.4" : Real
- { S7_Optimized_Access := 'TRUE' }
- VERSION : 0.1
- VAR_INPUT
- minValue : Real; // minimal Value random can reach
- maxValue : Real; // maximal Value random can reach
- seed : Real;
- END_VAR
- VAR_OUTPUT
- ob_Error : Bool; // Error with Varriant Input
- END_VAR
- VAR_TEMP
- tempDWord : DWord;
- tempReal : Real;
- END_VAR
- BEGIN
- #tempReal := NORM_X(MIN := #minValue, VALUE := #seed, MAX := #maxValue);
- #tempDWord := "fc_Zufall_DWord_V15.0.4"(idw_seed:=SCALE_X(MIN := 0, VALUE := #tempReal, MAX := 16#FFFF_FFFF), ob_Error=>#ob_Error);
- #tempReal := NORM_X(MIN := 0, VALUE := #tempDWord, MAX := 16#FFFF_FFFF);
- #"fc_Zufall_Real_V15.0.4" := SCALE_X(MIN := #minValue, VALUE := #tempReal, MAX := #maxValue);
- END_FUNCTION
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement