微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

#SOLVED - MODBUSRTU 模式CRC 计算......有什么问题?这是 DPS5020 用户手册的印刷错误吗?

如何解决#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 !!!!!!

错误的解释

  1. 在 CRC 生成期间,每个八位字符都与寄存器的内容异或。
  2. 结果向最低有效位 (LSB) 方向移动,并在最高有效位 (MSB) 的位置插入零。
  3. 提取并检查 LSB。
  4. 如果 LSB 是 1,则寄存器的异或 (XOR) 发生在一个固定的预设值。
  5. 如果 LSB 为 0,则不会发生异或 (XOR)。

合理解释

  1. 在 CRC 生成期间,每个八位字符都与寄存器的内容异或。
  2. 提取并检查 LSB(我的神奇之处)。
  3. 结果向最低有效位 (LSB) 方向移动,并在最高有效位 (MSB) 的位置插入零。
  4. 如果之前提取的 LSB(我的魔术位)是 1,则寄存器的异或 (XOR) 会以固定的预设值发生。
  5. 如果之前提取的 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 举报,一经查实,本站将立刻删除。