使用了modbus协议的PLC。上位机发送了一组数据,这组数据遵循modbus协议的格式,那么数据里边是有CRC校验的对吧。而下位机PLC需要对这组除了CRC校验码的那些数据,进行再次校验此时得到的校验码与接收来的CRC检验相比较。若相同则正确,若不同说明出现了数据遗失,则不让PLC产生响应。请问PLC处的CRC校验该怎么做呢?我modbus协议部分写好了。
最佳答案
方法1:计算法
主程序:OB1
Network 1
LD M0.0
EU
CALL SBR0, AC0 /
INCB VB0
INCB VB0
XMT 发送接收缓冲区, 0
Network 2
LD M0.1
EU
CALL SBR0, AC0
AW<> AC0, +0
MOVB 1, AC0
SBR_0:SBR0
VAR_OUTPUT
crc:INT;
END_VAR
VAR
count:INT;
ptr:DWORD;
END_VAR
BEGIN
Network 1
// MOVW AC0, *#ptr 用于发送,直接将CRC写入发送缓冲区,然后mmodbusBufr加2。
//
LD SM0.0
MOVW 16#FFFF, AC0
BTI VB0, LW2
MOVD &VB0, LD4
INCD LD4
FOR AC2, +1, LW2
XORB *LD4, AC0
FOR AC1, +1, +8
SRW AC0, 1
LD SM1.1
XORW 16#A001, AC0
NEXT
LD SM0.0
INCD LD4
NEXT
Network 2
// MOVW AC0, #crc 用于接收
// 如果程序无须接收,则可删除这一行,删除crc这个OUT参数。
//
//
//
// MOVW AC0, *#ptr 用于发送
// 直接将CRC写入发送缓冲区,然后mmodbusBufr加2。
// 如果程序无须发送,则可删除这一行。
LD SM0.0
SWAP AC0
MOVW AC0, LW0
MOVW AC0, *LD4
Network 3 // 网络标题
// 网络注释
END_SUBROUTINE_BLOCK
INTERRUPT_BLOCK INT_0:INT0
TITLE=中断程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
END_INTERRUPT_BLOCK
方法2:查表法
ORGANIZATION_BLOCK 主程序:OB1
TITLE=和方法1不同的是多了个初始化,简化了CRC计算过程,缩短了时间。
// 调用方法和方法1一样
BEGIN
Network 1 // 网络标题
// 初始化CRC表,需要512个字节。VB2256---------VB2767
LD SM0.1
CALL SBR0
Network 2 // 网络标题
// 发送
LD M0.0
EU
CALL SBR1, AC0 //AC0在此无用
INCB VB2000
INCB VB2000
XMT 发送接收缓冲区, 0
Network 3
// 接收完成后检查接收的数据对错,如果计算结果为0,则说明传输正确。
LD M0.1
EU
CALL SBR1, AC0
AW<> AC0, +0
MOVB 1, AC0
END_ORGANIZATION_BLOCK
SUBROUTINE_BLOCK SBR_0:SBR0
TITLE=子程序注释
VAR
index1:INT;
index2:INT;
END_VAR
BEGIN
Network 1
LD SM0.0
MOVD &VB2256, AC3
MOVD +0, AC2
FOR LW0, +1, +256
MOVW AC2, AC0
FOR LW2, +1, +8
SRW AC0, 1
Network 2
LD SM1.1
XORW 16#A001, AC0
Network 3
NEXT
Network 4
LD SM0.0
MOVW AC0, *AC3
INCW AC2
+I +2, AC3
Network 5
NEXT
Network 6 // 网络标题
// 网络注释
END_SUBROUTINE_BLOCK
SUBROUTINE_BLOCK SBR_1:SBR1
TITLE=子程序注释
VAR_OUTPUT
crc:INT;
END_VAR
VAR
count:INT;
ptr:DWORD;
END_VAR
BEGIN
Network 1
LD SM0.0
BTI VB2000, LW2
MOVD &VB2000, LD4
INCD LD4
XORD AC0, AC0
MOVD 16#FFFF, AC2
FOR AC1, +1, LW2
MOVB *LD4, AC0
XORW AC2, AC0
ANDW 16#FF, AC0
SLW AC0, 1
MOVD &VB2256, AC3
+I AC0, AC3
SWAP AC2
ANDW 16#FF, AC2
XORW *AC3, AC2
INCD LD4
Network 2
NEXT
Network 3
LD SM0.0
SWAP AC2
MOVW AC2, LW0
MOVW AC2, *LD4
Network 4 // 网络标题
// 网络注释
END_SUBROUTINE_BLOCK
INTERRUPT_BLOCK INT_0:INT0
TITLE=中断程序注释
BEGIN
Network 1 // 网络标题
// 网络注释
END_INTERRUPT_BLOCK
提问者对于答案的评价:
多谢了,好久不见了。可是程序没明白,有点乱。请问您有写在PLC软件上的程序吗?发给我吧。我的邮箱是jinzihan1984@sina.com
原创文章,作者:ximenziask,如若转载,请注明出处:https://www.zhaoplc.com/plc350577.html