技术论坛

 回复:CRC效验SCL程序

返回主题列表
作者 主题
v_wind
侠圣

经验值:2552
发帖数:287
精华帖:3
楼主    2017-09-29 09:14:52
主题:CRC效验SCL程序 精编帖 

CRC效验SCL程序对BYTE数组进行校验,放在数组最后两字节,正常情况是通过串口的MODBUS RTU下进行验证,1200已经支持这样的效验。我一般用在TCP或UDP自由通信时效验数组。




v_wind
侠圣

经验值:2552
发帖数:287
精华帖:3
2楼    2017-09-29 13:45:12
精编帖  主题:回复:CRC效验SCL程序

这里使用了Variant类型,可以方便效验长度不相同的数组了(最大数组长度可以更改)。

Zane
版主

经验值:85179
发帖数:21055
精华帖:399
3楼    2017-10-01 01:22:05
精编帖  主题:回复:CRC效验SCL程序

似乎没有必要开200字节的静态缓存

Zane 注册自动化系统工程师 Always save before download
v_wind
侠圣

经验值:2552
发帖数:287
精华帖:3
4楼    2017-10-01 13:13:26
精编帖  主题:回复:CRC效验SCL程序
我也希望能够像C指针一样不开辟这样缓存区,但是没找到好的办法,如果谁有别的方法请指教。或者用的时候,需要用多少改多少,哎很是麻烦呀!
yming
至圣

经验值:138382
发帖数:23141
精华帖:880
5楼    2017-10-02 14:06:48
精编帖  主题:回复:CRC效验SCL程序

你是用TIA V13吧?

如果是用 TIA V14 SP1,你可以使用 Array [*] of Type (你这里 Type=Byte)放在 InOut FC 接口。

用 CountOfElements 获得 元素个数(UDint)。

最后的计算结果填在被处理的 InOut 的未知元素个数的数组尾端。

这样用个FC,而不用FB来处理。

你说呢?


学而时习之,不亦说乎?温故而知新,不亦乐乎?
v_wind
侠圣

经验值:2552
发帖数:287
精华帖:3
6楼    2017-10-02 14:59:13
精编帖  主题:回复:CRC效验SCL程序
yming版主看了您的回帖也包括其它的帖子,真是受益匪浅,回去对这个方法研究一下,测试完了,把程序发上来。
v_wind
侠圣

经验值:2552
发帖数:287
精华帖:3
8楼    2017-10-07 20:30:15
精华帖  精编帖  主题:回复:CRC效验SCL程序

FUNCTION "CRC_CHK" : Void

{ S7_Optimized_Access := 'TRUE' }

VERSION : 0.1

   VAR_IN_OUT 

      ArrayBuf : Array[*] of Byte;

   END_VAR


   VAR_TEMP 

      ArrayBuf_LEN : UDInt;

      VariantBuf : Variant;

      CRC_INDEX : Int;

      VariantBuf_LEN : DInt;

      CRC_BIT : Int;

      temp : Word;

      temp_1 : Byte;

   END_VAR



BEGIN

VariantPut(SRC:=#ArrayBuf,

          DST:=#VariantBuf);

#ArrayBuf_LEN :=CountOfElements(#VariantBuf);

//CRC校验,将从数据块的第0个字节开始,一直到发送的最后一个字节

#ArrayBuf[#VariantBuf_LEN - 1] := 16#FF;      //CRC寄存器的初始化

#ArrayBuf[#VariantBuf_LEN - 2] := 16#FF;      //CRC寄存器的初始化

#temp.%B0 := #ArrayBuf[#VariantBuf_LEN - 1];

#temp.%B1 := #ArrayBuf[#VariantBuf_LEN - 2];

FOR #CRC_INDEX := 0 TO #VariantBuf_LEN - 3 BY 1 DO

   //信息字节与当前CRC最低有效字节异或

   #temp_1 := #ArrayBuf[#CRC_INDEX] AND 16#FF;

   #temp := #temp_1 XOR #temp;

   FOR #CRC_BIT := 0 TO 7 BY 1 DO

       IF (#temp AND 16#01) = 16#01 THEN    //CRC最低有效位为真

           #temp := SHR(IN := #temp, N := 1);   //右移1位

           #temp := #temp XOR 16#A001;   //与多项式异或

       ELSE

           #temp := SHR(IN := #temp, N := 1);   //右移1位

       END_IF;

   END_FOR;

END_FOR;

//将CRC校验传到缓冲区

#ArrayBuf[#VariantBuf_LEN - 1] := #temp.%B1;

#ArrayBuf[#VariantBuf_LEN - 2] := #temp.%B0;

END_FUNCTION

以上是修改过的程序,用Array[*] of Byte确实不用开辟新的空间,但读取长度还需要 Variant类型的,这个程序仅仅是编译通过,没有测试的。

程序是块生成源,保存SCL格式的,再用笔记本打开复制出来的。

yuanqijun88
侠圣

经验值:3465
发帖数:161
精华帖:0
9楼    2017-10-25 21:04:41
精编帖  主题:回复:CRC效验SCL程序

楼主: CountOfElements这个变量在哪儿创建,时什么样的类型?谢谢!楼主们告诉?

“技术论坛”发言及“找答案”的个人信息中
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。