如何解决#SOLVED - MODBUSRTU 模式CRC 计算......有什么问题?这是 DPS5020 用户手册的印刷错误吗?
我是意大利人,很抱歉我的英语不好。 我正在分析DPS5020电源模块使用的MODBUS协议(rs232 com口),无法理解RTU模式下的CRC计算方法(第3页)https://cloud.kyme32.ro/ftp_backup/DPS5020%20PC%20Software(2017.11.04)/DPS5020%20CNC%20Communication%20%20Protocol%20V1.2.pdf。 在第 4 页上发送字节 1、3、0、2、0、2 的第一个示例中,指示值 CRC = 65CB(十六进制)(交换了 2 个字节)。 我也在网上尝试了几个 CRC 计算器,但找不到正确的值。 我也做了一个计算和位正确旋转的分步图,但值不返回给我。 是否需要使用帧(6)的所有字节进行计算还是仅使用数据值(4)?我两个都试过都没有成功... 能否请您放一张关于如何完成计算和返回值的小图(16位xor与A001值,向右旋转是/否......等)? 我知道最后你必须在它们之间交换 2 个字节,但无论如何单个值都不会返回给我。 或者它只是手册的印刷错误? 我真的很沮丧。非常感谢。
#解决 DPS5020 文档(通信协议)中的错误解释:该文档指出应该在位右移之后而不是 BEFORE 之后检查 LSB !!!!!!
错误的解释
- 在 CRC 生成期间,每个八位字符都与寄存器的内容异或。
- 结果向最低有效位 (LSB) 方向移动,并在最高有效位 (MSB) 的位置插入零。
- 提取并检查 LSB。
- 如果 LSB 是 1,则寄存器的异或 (XOR) 发生在一个固定的预设值。
- 如果 LSB 为 0,则不会发生异或 (XOR)。
合理解释
- 在 CRC 生成期间,每个八位字符都与寄存器的内容异或。
- 提取并检查 LSB(我的神奇之处)。
- 结果向最低有效位 (LSB) 方向移动,并在最高有效位 (MSB) 的位置插入零。
- 如果之前提取的 LSB(我的魔术位)是 1,则寄存器的异或 (XOR) 会以固定的预设值发生。
- 如果之前提取的 LSB(我的魔术位)是 0,则不会发生异或 (XOR)。
非常感谢 Mark Adler 的支持。
解决方法
帧中的所有字节都用于 CRC 计算。
这是 CRC 的 C 实现,它应该可以回答您关于究竟要移位什么和异或何时移位的问题:
#include <stddef.h>
#include <stdint.h>
uint16_t crc16modbus_bit(uint16_t crc,void const *mem,size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0xffff;
for (size_t i = 0; i < len; i++) {
crc ^= data[i];
for (unsigned k = 0; k < 8; k++) {
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
}
}
return crc;
}
(当调用 mem
等于 NULL
时返回初始 CRC 值。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。