zoukankan      html  css  js  c++  java
  • 博图TIA中ModbusRTU_CRC校验程序的实现

    博图TIA中ModbusRTU_CRC校验程序的实现

    使用SCL语言,在博图TIA中编写ModbusRTU_CRC校验程序,使用两个FC块,实现两种不同的应用CRC1将计算结果直接输出,CRC2将计算的结果插入到输入数组的最后端.

    TIA中自带了modbusRTU通讯库,之所以自己实现CRC校验码的计算只是为了更深入的学习TIA SCL编程序.

    实现效果及代码截图

    代码片段

    CRC1

    FUNCTION "CRC1" : Void
    { S7_Optimized_Access := 'TRUE' }
    VERSION : 0.1
       VAR_INPUT 
          CrcData : Variant;
       END_VAR
    
       VAR_OUTPUT 
          CrcValue : Word;
          CrcErr : Word;
       END_VAR
    
       VAR_TEMP 
          Preset : Word;
          LoopLength : Int;
          ArrayPoint : Int;
          i : Int;
          ArrayLength : UDInt;
          Array1 : Array[0..999] of Byte;   // 最多1000个字节
          Err : Int;
       END_VAR
    
    
    BEGIN
    	#ArrayLength:= CountOfElements(#CrcData);
    	
    	IF #ArrayLength <= 1000 THEN //这里的1000如果需要调大,对应的数组临时变量Array1也要调大
    	    #Err := MOVE_BLK_VARIANT(SRC := #CrcData, COUNT := #ArrayLength, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Array1);
    	    #Preset := 16#FFFF;
    	    #LoopLength := 0;
    	    #ArrayPoint := 0;
    	    
    	    //计算CRC校验码
    	    WHILE #LoopLength < #ArrayLength DO    //数据长度
    	        #Preset := #Preset XOR #Array1[#ArrayPoint];
    	        #ArrayPoint := #ArrayPoint + 1;
    	        FOR #i := 0 TO 7 DO
    	            IF (#Preset AND 16#01) = 16#01 THEN
    	                #Preset := SHR(IN := #Preset, N := 1);
    	                #Preset := #Preset XOR 16#A001;
    	            ELSE
    	                #Preset := SHR(IN := #Preset, N := 1);
    	            END_IF;
    	        END_FOR;
    	        #LoopLength := #LoopLength + 1;
    	    END_WHILE;
    	    
    	    //#CrcValue := #Preset;
    	    #CrcValue := SHR_WORD(IN := #Preset, N := 8) + SHL_WORD(IN := #Preset, N := 8);
    	    #CrcErr := 16#0000;
    	ELSE
    	    #CrcErr := 16#8000;
    	END_IF;
    	
    END_FUNCTION
    

    SEND1

    DATA_BLOCK "SEND1"
    { S7_Optimized_Access := 'FALSE' }
    VERSION : 0.1
    NON_RETAIN
       STRUCT 
          CrcData : Array[0..5] of Byte;   // 该数组不大于1000字节
          CrcValue : Word;
          CrcError : Word;
       END_STRUCT;
    
    
    BEGIN
       CrcData[0] := 16#01;
       CrcData[1] := 16#03;
       CrcData[2] := 16#00;
       CrcData[3] := 16#00;
       CrcData[4] := 16#00;
       CrcData[5] := 16#01;
    
    END_DATA_BLOCK
    

    CRC2

    FUNCTION "CRC2" : Void
    { S7_Optimized_Access := 'TRUE' }
    VERSION : 0.1
       VAR_INPUT 
          Command : Variant;
          dataLen : Int;
       END_VAR
    
       VAR_TEMP 
          buffer : Array[0..#MaxLen] of Byte;
          i : Int;
          j : Int;
          CrcReg : Word;
          Len : Int;
       END_VAR
    
       VAR CONSTANT 
          MaxLen : Int := 255;
       END_VAR
    
    
    BEGIN
    	IF #dataLen = 0 OR #dataLen > CountOfElements(IN := #Command) - 2 THEN
    	    RETURN;
    	ELSE
    	    #Len := #dataLen;
    	END_IF;
    	
    	#CrcReg := 16#FFFF;
    	
    	//将数据转到缓冲区
    	VariantGet(SRC:=#Command,
    	           DST=>#buffer);
    	
    	//计算CRC校验码
    	FOR #i := 0 TO (#Len - 1) DO
    	    #CrcReg := #CrcReg XOR #buffer[#i];
    	    FOR #j := 0 TO 7 DO
    	        IF (#CrcReg AND 16#1) = 1 THEN
    	            #CrcReg := SHR_WORD(IN := #CrcReg, N := 1);
    	            #CrcReg := #CrcReg XOR 16#A001;
    	        ELSE
    	            #CrcReg := SHR_WORD(IN := #CrcReg, N := 1);
    	        END_IF;
    	    END_FOR;
    	END_FOR;
    	
    	#buffer[#Len + 1] := SHR_WORD(IN := #CrcReg, N := 8);
    	#buffer[#Len] := #CrcReg AND 16#FF;
    	
    	//将缓冲区数据再写入到指针所指向的区域
    	VariantPut(SRC := #buffer,
    	           DST := #Command);
    	
    	
    END_FUNCTION
    

    SEND2

    DATA_BLOCK "SEND2"
    { S7_Optimized_Access := 'FALSE' }
    VERSION : 0.1
    NON_RETAIN
       STRUCT 
          CrcData : Array[0..7] of Byte;   // 该数组不大于1000字节
       END_STRUCT;
    
    
    BEGIN
       CrcData[0] := 16#01;
       CrcData[1] := 16#03;
       CrcData[2] := 16#00;
       CrcData[3] := 16#00;
       CrcData[4] := 16#00;
       CrcData[5] := 16#01;
    
    END_DATA_BLOCK
    
  • 相关阅读:
    Android UI法宝的设计资源的开发
    Ural 1309 Dispute (递归)
    ZOJ3827 ACM-ICPC 2014 亚洲区域赛的比赛现场牡丹江I称号 Information Entropy 水的问题
    myeclipse如何恢复已删除的文件和代码
    在C#主线程和子线程将数据传递给对方如何实现
    SSh框架结构(Struts2.1+Hibernate4.0+Spring3.1)
    基于大数据分析的安全管理平台技术研究及应用【摘录】
    ulimit -t 引起的kill血案
    Oracle RAC 环境下的连接管理
    SMTP协议--在cmd下利用命令行发送邮件
  • 原文地址:https://www.cnblogs.com/guyk/p/15170228.html
Copyright © 2011-2022 走看看