博图TIA中ModbusRTU_CRC校验程序的实现
2021/8/21 20:06:20
本文主要是介绍博图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
这篇关于博图TIA中ModbusRTU_CRC校验程序的实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享