打印

crc16的计算方法

[复制链接]
1672|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhu51231|  楼主 | 2016-5-16 10:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在搞modbus通讯,需要计算crc16(基于多项式0x8005的),网上找了很多的计算方法,验证了一下,结果都不对,我是用网上下载的crc16计算器验证的,谁有可以用的程序,发给我一下。邮箱zhu51231@126.com

相关帖子

沙发
zhu51231|  楼主 | 2016-5-16 10:53 | 只看该作者
要直接计算的程序。

使用特权

评论回复
板凳
zhu51231|  楼主 | 2016-5-16 10:55 | 只看该作者
http://www.21ic.com/app/embed/201205/122521.htm这里给的程序计算的结果也不对,谁可以解释一下

使用特权

评论回复
地板
luofeng2g| | 2016-5-16 10:55 | 只看该作者

使用特权

评论回复
5
zhu51231|  楼主 | 2016-5-17 07:55 | 只看该作者
上面两个算法,我输入数据验证了一下,结果都是不对的,可能是算法不完整,我有不知道该怎么样补充完整。求指点

使用特权

评论回复
6
hgjinwei| | 2016-5-17 08:16 | 只看该作者
给组数据及校验结果看看?

使用特权

评论回复
7
zhu51231|  楼主 | 2016-5-17 09:02 | 只看该作者
00 00 00 00 06 0d e3就这组数据用crc16的计算器计算结果是(8005)0xd143(1021)0xdbc0
用以上方法就得不到这个结果

使用特权

评论回复
8
hgjinwei| | 2016-5-20 08:19 | 只看该作者
我也算不出来,初始值为0xFFFF下,
正序计算为:0xF432
反序计算为: 0x18BE

不知道0xD143,0xDBC0是如何得到的

使用特权

评论回复
9
诺比贝尔| | 2016-5-20 23:57 | 只看该作者
CRC16_32

使用特权

评论回复
10
诺比贝尔| | 2016-5-20 23:58 | 只看该作者

#include "crc16.h"



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
// 位取反函数:
//
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
crc_16_32 reflect(crc_16_32 data, unsigned char nBits)
{
        crc_16_32 reflection = 0;
        unsigned char bit;
        for (bit = 0; bit < nBits; ++bit)// nbit=32
        {
                        if (data & 0x01)
                        {
                                reflection |= (1 << ((nBits - 1) - bit));
                        }
                        data = (data >> 1);
        }
        return(reflection);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// crc_16_32 Crc_Call() 函数
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
crc_16_32 Crc_Call(crc_16_32  *addr,crc_16_32 length)
{
       
    crc_16_32 CRC = INITIAL_REMAINDER;//初值:0XFFFF...
   
        crc_16_32 i,j;
        for(i=0;i<length;i++)//要累计CRC 的数据个数
        {
                CRC^= REFLECT_DATA (*addr++); //是否需要 对数据进行位取反,宏定义以及设置好了
                for(j=0;j<WIDTH;j++) //WIDTH 是位宽,16 或32 ;
                {                       
            if(CRC&((crc_16_32)1<<(WIDTH-1))) // 这个因为是BIT15/31 是高位
                        {
                                CRC=CRC<<1; // 数据向高位BIT15/31 移动
                                CRC^=POLYNOMIAL;//多项式
                        }
                        else CRC=CRC<<1;// 数据向高位BIT15/31 移动
                }
        }
        return(REFLECT_REMAINDER (CRC)) ;

}// END SUB

使用特权

评论回复
11
诺比贝尔| | 2016-5-20 23:59 | 只看该作者
#ifndef CRC16_H
#define CRC16_H


#ifdef __cplusplus
extern "C" {
#endif

        
#define CRC_CCITT /* 定义想要的CRC 类型 */
//#define CRC32 /* 定义想要的CRC 类型 */   

#if defined(CRC_CCITT)
typedef unsigned short crc_16_32;
#define CRC_NAME            "CRC-CCITT"
#define POLYNOMIAL          0x1021
#define INITIAL_REMAINDER   0xFFFF
#define FINAL_XOR_VALUE     0x0000
#define REFLECT_DATA        FALSE
#define REFLECT_REMAINDER   FALSE
#define CHECK_VALUE         0x29B1
#define BITWIDTH            16
#elif defined(CRC32)
typedef unsigned long crc_16_32;
#define CRC_NAME "CRC-32"
#define POLYNOMIAL                         0x04C11DB7L
#define INITIAL_REMAINDER         0xFFFFFFFF
#define FINAL_XOR_VALUE         0xFFFFFFFF
#define REFLECT_DATA                FALSE
#define REFLECT_REMAINDER         FALSE
#define CHECK_VALUE                 0xCBF43926
#define BITWIDTH            32
#else
#error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."
#endif

#define WIDTH (8 * sizeof(crc_16_32))

#define TOPBIT ((crc_16_32)1 << (WIDTH - 1))

#if (REFLECT_DATA == TRUE)
#undef REFLECT_DATA
#define REFLECT_DATA(X) ((crc_16_32)reflect((X), WIDTH))
#else
#undef REFLECT_DATA
#define REFLECT_DATA(X) (X)
#endif


#if (REFLECT_REMAINDER == TRUE)
#undef REFLECT_REMAINDER
#define REFLECT_REMAINDER(X) ((crc_16_32)reflect((X), WIDTH) )
#else
#undef REFLECT_REMAINDER
#define REFLECT_REMAINDER(X) (X)
#endif



crc_16_32 reflect(crc_16_32 data, unsigned char nBits);
crc_16_32 Crc_Call(crc_16_32 *addr,crc_16_32 length);



#ifdef __cplusplus
}
#endif /* extern "C" */

#endif  

使用特权

评论回复
12
killer2014| | 2016-5-25 14:54 | 只看该作者
感谢了, 收藏下, 下次肯定用的上。

使用特权

评论回复
13
djz1992| | 2016-5-30 15:13 | 只看该作者
https://bbs.21ic.com/icview-1591324-1-1.html
你看这个里的回复呢,算法不一样,算出的结果不一样很正常
https://bbs.21ic.com/icview-1593504-1-1.html
这里有大神分享的函数

使用特权

评论回复
14
zhu51231|  楼主 | 2016-6-4 12:45 | 只看该作者
解决了

使用特权

评论回复
15
hotpower| | 2016-6-21 15:32 | 只看该作者
http://www.21ic.com/tools/HotWC3_V1.22.html

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

117

帖子

1

粉丝