OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2208|回复: 1

被modbus文档坑了一下

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2018-3-20
在线时间
2 小时
发表于 2018-5-4 16:08:22 | 显示全部楼层 |阅读模式
最近在研究modbus协议,通讯协议流程搞明白后开始写程序~文档上面有现成的CRC查表法实现代码,但是就想自己试着写一个计算的代码,按照文档上的流程写出来测试怎么都不对。上网查查看别人的代码,发现了问题,第3步“将 CRC 寄存器右移 1 位 (向 LSB 方向), MSB 充零. 提取并检测 LSB.”检测的应该是移出的那一位,而不是检测移出后CRC寄存器的最低位。
生成 CRC 的过程为:
1. 将一个 16 位寄存器装入十六进制 FFFF (全 1). 将之称作 CRC 寄存器.
2. 将报文的第一个 8 位字节与 16 位 CRC 寄存器的低字节异或,结果置于 CRC 寄存器.
3. 将 CRC 寄存器右移 1 位 (向 LSB 方向), MSB 充零. 提取并检测 LSB.
4. (如果 LSB 为 0): 重复步骤 3 (另一次移位).
(如果 LSB 为 1): 对 CRC 寄存器异或多项式值 0xA001 (1010 0000 0000 0001).
5. 重复步骤 3 和 4,直到完成 8 次移位。当做完此操作后,将完成对 8 位字节的完整操作。
6. 对报文中的下一个字节重复步骤 2 到 5,继续此操作直至所有报文被处理完毕。
7. CRC 寄存器中的最终内容为 CRC 值.
8. 当放置 CRC 值于报文时,如下面描述的那样,高低字节必须交换。
我写的代码

[mw_shl_code=c,true]unsigned short my_crc16(unsigned char *buffer, unsigned short buffer_length)
{
    uint16_t crc = 0xFFFF;
    while (buffer_length--) {
        crc ^= *buffer++;
        for (int i = 0; i < 8; i++) {
            crc >>= 1;
            if (crc & 0x01)
                crc ^= 0xA001;
        }
    }
    crc = ((crc & 0xff) << 8) + (crc >> 8);
    return crc;
}[/mw_shl_code]
修改后的代码
[mw_shl_code=applescript,true]unsigned short cal_crc16(unsigned char *buffer, unsigned short buffer_length)
{
    uint16_t crc = 0xFFFF;
    while (buffer_length--) {
        crc ^= *buffer++;
        for (int i = 0; i < 8; i++) {
            if (crc & 0x01)
                crc = crc >> 1 ^ 0xA001;
            else
                crc >>= 1;
        }
    }
    crc = ((crc & 0xff) << 8) + (crc >> 8);
    return crc;
}[/mw_shl_code]
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2018-3-20
在线时间
2 小时
 楼主| 发表于 2018-5-4 16:12:22 | 显示全部楼层
1, Load a 16–bit register with FFFF hex (all 1’s). Call this the CRC register.
2. Exclusive OR the first 8–bit byte of the message with the low–order byte
of the 16–bit CRC register, putting the result in the CRC register.
3. Shift the CRC register one bit to the right (toward the LSB), zero–filling the
MSB. Extract and examine the LSB.
4. (If the LSB was 0): Repeat Step 3 (another shift).
(If the LSB was 1): Exclusive OR the CRC register with the polynomial
value A001 hex (1010 0000 0000 0001).
5. Repeat Steps 3 and 4 until 8 shifts have been performed. When this is
done, a complete 8–bit byte will have been processed.

英文版文档
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 13:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表