typedef unsigned char    uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t; #define CRC_POLY_16 0xA001
#define CRC_START_MODBUS 0xFFFF static uint16_t crc_tab16[];
static bool crc_tab16_init = false; static void init_crc16_tab(void)
{
uint16_t i;
uint16_t j;
uint16_t crc;
uint16_t c; for (i = ; i<; i++)
{
crc = ;
c = i; for (j = ; j<; j++)
{
if ((crc ^ c) & 0x0001)
{
crc = (crc >> ) ^ CRC_POLY_16;
}
else
{
crc = crc >> ;
}
c = c >> ;
}
crc_tab16[i] = crc;
}
crc_tab16_init = true;
} uint16_t crc_modbus(const unsigned char *input_str, size_t num_bytes)
{
uint16_t crc;
uint16_t tmp;
uint16_t short_c;
const unsigned char *ptr;
size_t a; if (!crc_tab16_init) init_crc16_tab(); crc = CRC_START_MODBUS;
ptr = input_str; if (ptr != NULL) for (a = ; a < num_bytes; a++)
{
short_c = 0x00ff & (uint16_t)*ptr;
tmp = crc ^ short_c;
crc = (crc >> ) ^ crc_tab16[tmp & 0xff];
ptr++;
}
return crc;
}

或者

typedef unsigned char    uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t; #define CRC_POLY_16 0xA001
#define CRC_START_MODBUS 0xFFFF static const uint16_t crc_tab16[] =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
}; uint16_t crc_modbus(const unsigned char *input_str, size_t num_bytes)
{
uint16_t crc;
uint16_t tmp;
uint16_t short_c;
const unsigned char *ptr;
size_t a; crc = CRC_START_MODBUS;
ptr = input_str; if (ptr != NULL) for (a = ; a < num_bytes; a++)
{
short_c = 0x00ff & (uint16_t)*ptr;
tmp = crc ^ short_c;
crc = (crc >> ) ^ crc_tab16[tmp & 0xff];
ptr++;
}
return crc;
}

参考资料: On-line CRC calculation and free library

CRC-16 (Modbus)的更多相关文章

  1. Modbus CRC 16 (C#)

    算法 1.预置一个值为 0xFFFF 的 16 位寄存器,此寄存器为 CRC 寄存器. 2.把第 1 个 8 位二进制数据(即通信消息帧的第 1 个字节)与 16 位的 CRC 寄存器相异或,异或的结 ...

  2. C# CRC - 16

    using System; static class Program { static void Main() { string input = "8000"; var bytes ...

  3. CRC(16位)多项式为 X16+X15+X2+1

    其对应校验二进制位列为1 1000 0000 0000 0101,可这有17位啊,我怎么和16位信息进行异或啊?是不是不要最高位的1 你没有弄明白crc的意思.这17位后面再添上16个零,然后开始抑或 ...

  4. HJ212 CRC 16 (C#)

    算法 CRC16 校验寄存器赋值为 0xFFFF: 取被校验串的第一个字节赋值给临时寄存器: 临时寄存器与 CRC16 校验寄存器的高位字节进行"异或"运算,赋值给 CRC16 校 ...

  5. modbus协议讲义

        Modbus 一个工业上常用的通讯协议.一种通讯约定.Modbus协议包括RTU.ASCII.TCP.其中MODBUS-RTU最常用,比较简单,在单片机上很容易实现.虽然RTU比较简单,但是看 ...

  6. 对单片机的modbus RTU的详细解释(转载)

    Modbus 一个工业上常用的通讯协议.一种通讯约定.Modbus协议包括RTU.ASCII.TCP.其中MODBUS-RTU最常用,比较简单,在单片机上很容易实现.虽然RTU比较简单,但是看协议资料 ...

  7. C#CRC16 Modbus 效验算法

    CRC校验(循环冗余校验)小知识 CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗 ...

  8. stm32——modbus例程网址收藏

    https://blog.csdn.net/baidu_31437863/article/details/82178708 STM32(五) Modbus https://blog.csdn.net/ ...

  9. Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 3

    Modbus-RTU 一.数据分析       两个设备(单片机)通讯,用的是Modbus协议.      在单片机中拿出一部分内存(RAM)进行两个设备通讯,例如: 说明: OX[20]   代表是 ...

  10. CRC循环冗余校验码总结(转)

    转自 http://blog.csdn.net/u012993936/article/details/45337069 一.CRC简介 先在此说明下什么是CRC:循环冗余码校验 英文名称为Cyclic ...

随机推荐

  1. 搞懂Xamarin.Forms布局,看这篇应该就够了吧

    Xamarin.Forms 布局介绍 什么是布局?可以简单的理解为,我们通过将布局元素有效的组织起来,让屏幕变成我们想要的样子! 我们通过画图的方式来描述一下Xamarin.Forms的布局. 小节锚 ...

  2. JHipster技术栈理解 - UAA原理分析

    本文简要分析了UAA的认证机制和部分源码功能. UAA全称User Account and Authentication. 相关源码都是通过Jhipster生成,包括UAA,Gateway,Ident ...

  3. Android 官方DEMO BasicNetworking

    本示例演示如何使用Android API检查网络连接. Demo下载地址:https://github.com/googlesamples/android-BasicNetworking/#readm ...

  4. Linux 防火墙

    目录 iptables配置 1. iptables 控制类型 2. 链表规则 3. iptables表 CentOS和RedHat 6.x CentOS和RedHat 7.x ufw ubuntu u ...

  5. RMAN命令DELETE操作总结

    本篇总结一下RMAN命令中的DELETE操作,DELETE命令用于删除RMAN备份记录以及相应的物理文件. To delete physical backups and copies as well ...

  6. mysql练习----Self join

    stops(id, name) route(num,company,pos, stop)   stops route id num name company   pos   stop    

  7. CharacterController平滑移动到某点

    通常使用CharacterController控制玩家移动时,我们都会写以下代码: void Update() { var move = (moveTarget - transform.Positio ...

  8. oracle USING 用法

    提问 using(xx)中可以接多个列吗? using(xx)中的列可以接表名或别名吗? 在使用using的语句中,select * 可以使用吗? 如果表有别名t,select t.* from ta ...

  9. MacOS远程Windows提示:远程桌面连接无法验证您希望连接的计算机的身份

    解决方法: 1.在Windows端,运行输入 “gpedit.msc”,打开本地组策略编辑器 2.依次打开[计算机配置]→[管理模板]→[windows组件]→[远程桌面服务]→[远程桌面会话主机]→ ...

  10. 【PS技巧】如何拼图

    1.材料准备 根据对图片的内容表达,粗略的“计划”,每张图片摆放位置及尺寸.C与D等高,C/D与B叠高后与A等高.C与D叠宽后与B等宽. 2.记录每张图片原始大小 (1)双击工作区,打开待拼接图片 ( ...