zackwu 发表于 2025-4-24 09:16:12

CRC校验问题

你好版主,
目前我用的MODBUSCRC校验如下
u16        MODBUS_CRC16(u8 *p, u16 n)
{
        u16        i;
        u16        crc16;
        crc16 = 0xffff;        //预置16位CRC寄存器为0xffff(即全为1)
        do
        {
                crc16 ^= (u16)*p;                //把8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器
                for(i=0; i<8; i++)                //8位数据
                {
                        if(crc16 & 1)        crc16 = (crc16 >> 1) ^ 0xA001;        //如果最低位为0,把CRC寄存器的内容右移一位(朝低位),用0填补最高位,
                                                                                                                        //再异或多项式0xA001
                        else        crc16 >>= 1;                                                        //如果最低位为0,把CRC寄存器的内容右移一位(朝低位),用0填补最高位
                }
                p++;
        }while(--n != 0);
        return        (crc16);
}       

这个校验应该没问题,出来的数据和工具里面提供CRC校验数据是一致的,如下

可是用MODBUS POLL去读取的时候出现了检验失败的情况,能否指点下思路



国芯人工智能 发表于 2025-4-24 09:18:00

您好,针对您提到的MODBUS CRC校验问题,以下是一些可能的原因和解决思路:

1. CRC校验算法实现问题
您的CRC校验算法实现看起来是正确的,但仍有以下几点需要注意:
初始值:MODBUS CRC校验的初始值应为0xFFFF,您的代码中已经正确设置。
多项式:MODBUS CRC校验使用的多项式是0xA001,您的代码中也已正确使用。
数据顺序:确保在计算CRC时,数据的顺序是正确的。MODBUS协议通常使用大端序(Big-Endian),即高位字节在前,低位字节在后。

2. 数据帧格式问题
MODBUS POLL工具在读取数据时,可能会对数据帧的格式有特定要求。请检查以下几点:
数据帧长度:确保发送的数据帧长度符合MODBUS协议的规定。
CRC校验字节顺序:MODBUS协议中,CRC校验结果的两个字节需要按照低字节在前、高字节在后的顺序附加到数据帧末尾。如果顺序错误,MODBUS POLL会认为CRC校验失败。

3. 通信参数设置问题
MODBUS POLL工具在读取数据时,需要与设备的通信参数一致。请检查以下几点:
波特率:确保MODBUS POLL的波特率与设备设置的波特率一致。
数据位、停止位、校验位:确保这些参数与设备设置一致。
从机地址:确保MODBUS POLL中设置的从机地址与设备地址一致。

4. 工具配置问题
MODBUS POLL工具本身可能有一些配置选项需要调整。请检查以下几点:
CRC校验选项:确保MODBUS POLL中启用了CRC校验功能。
数据帧解析方式:确保MODBUS POLL的数据帧解析方式与设备发送的数据帧格式一致。

5. 调试建议
为了进一步排查问题,您可以采取以下调试步骤:
打印数据帧:在发送数据帧之前,打印出完整的数据帧(包括CRC校验字节),确保数据帧的格式和内容正确。
使用其他工具验证:使用其他MODBUS调试工具(如MODSCAN)进行验证,看看是否同样出现CRC校验失败的情况。
对比CRC校验结果:手动计算CRC校验结果,并与MODBUS POLL工具中的CRC校验结果进行对比,确保两者一致。

6. 代码优化建议
您的代码可以进一步优化,以提高可读性和效率。以下是优化后的代码示例:
c
u16 MODBUSCRC16(u8 p, u16 n) {
    u16 crc16 = 0xFFFF;// 预置16位CRC寄存器为0xFFFF
    while (n--) {
      crc16 ^= p++;// 把8位数据与16位CRC寄存器的低位相异或
      for (u16 i = 0; i < 8; i++) {
            if (crc16 & 0x0001) {
                crc16 = (crc16 >> 1) ^ 0xA001;// 如果最低位为1,右移一位并异或多项式0xA001
            } else {
                crc16 >>= 1;// 如果最低位为0,右移一位
            }
      }
    }
    return crc16;
}

7. 总结
通过以上步骤,您应该能够找到CRC校验失败的原因。如果问题仍然存在,建议进一步检查硬件连接、设备配置以及MODBUS POLL工具的设置。希望这些建议对您有所帮助,祝您顺利解决问题!

如有其他问题,欢迎继续交流。

[本文内容由国芯人工智能辅助生成,仅供参考]

_奶咖君_ 发表于 2025-4-24 09:23:11

串口的奇偶校验配置的对么?

ercircle 发表于 2025-4-24 09:44:25

看下CRC高低位是不是填反了






DebugLab 发表于 2025-4-24 10:04:38

神农鼎 发表于 2025-4-24 10:38:25



CRC计算工具@AIapp-ISP V6.95M - 串行口,DMA支持的4组串口,RS232,RS485,Modbus, CRC16 国芯技术交流网站 - AI32位8051交流社区

zackwu 发表于 2025-4-24 16:22:58

_奶咖君_ 发表于 2025-4-24 09:23
串口的奇偶校验配置的对么?

无校验
页: [1]
查看完整版本: CRC校验问题