博客
关于我
CRC16循环冗余校验 RTU-MODBUS标准 Linux C
阅读量:205 次
发布时间:2019-02-28

本文共 2580 字,大约阅读时间需要 8 分钟。

1、概述

CRC16循环冗余校验是一种常用的数据完整性校验方法,尤其在MODBUS协议中应用广泛。CRC16校验值为16位无符号整数,通常以两个字节表示,低检验字节在前,高检验字节在后。例如,若校验值为0x1788,则MODBUS报文中校验顺序为...0x88 0x17。

2、C程序实现

以下是实现CRC16校验的Linux C代码示例:

```c/****************************************************************************** * 文件名称: main.c * 描述: 提供CRC16校验的Linux实现 * 作者: jackwang * 日期: 2018-07-15 ******************************************************************************/#include
#include
#include

static unsigned char Char2Int(char chr, bool *isOK);static unsigned char HexStr2Int(char *str, bool *isOK);static unsigned short GenerateCRC16(unsigned char *arr_buff, unsigned short len);

int main(int argc, char *argv) {int ret = 0;int numByte = argc;unsigned char bccVal = 0x00;char inputBuff[10];unsigned char dataBuff[1000];unsigned short buffSize = 0;unsigned short crcVal;bool isOK;int Nibb;

if (argc == 1) {    printf("[note] 无输入参数,请输入要校验的字节数据,按空格分隔。\r\n");} else {    printf("[note] 输入 %d 个字节的数据:", numByte - 1);    for (int i = 1; i < numByte; ++i) {        printf("%s ", argv[i]);    }    printf("\r\n");    for (int i = 1; i < numByte; ++i) {        memcpy(inputBuff, argv[i], 2);        Nibb = HexStr2Int(inputBuff, &isOK);        if (isOK) {            dataBuff[i - 1] = Nibb;            buffSize++;        }    }    crcVal = GenerateCRC16(dataBuff, buffSize);    printf("[note] CRC16校验值为:0x%04X\r\n", crcVal);}return 0;

}

static unsigned char Char2Int(char chr, bool *isOK) {unsigned char nibb1;if (chr >= '0' && chr <= '9') {nibb1 = chr - '0';*isOK = true;} else if (chr >= 'a' && chr <= 'f') {nibb1 = chr - 'a' + 10;*isOK = true;} else if (chr >= 'A' && chr <= 'F') {nibb1 = chr - 'A' + 10;*isOK = true;} else {printf("[error] 无效的Hex字符输入:%c\r\n", chr);*isOK = false;}return nibb1;}

static unsigned char HexStr2Int(char *str, bool *isOK) {unsigned char nibb1, nibb2;bool isOK1, isOK2;nibb1 = Char2Int(str, &isOK1);nibb2 = Char2Int((str + 1), &isOK2);

if (isOK1 && isOK2) {    *isOK = true;    return nibb1 * 16 + nibb2;} else {    *isOK = false;    return 0;}

}

static unsigned short GenerateCRC16(unsigned char *arrBuff, unsigned short len) {unsigned short crc = 0xFFFF;unsigned char i, j;

for (j = 0; j < len; ++j) {    crc = crc ^ *arrBuff++;    for (i = 0; i < 8; ++i) {        if ((crc & 0x0001) > 0) {            crc = crc >> 1;            crc = crc ^ 0xA001;        } else {            crc = crc >> 1;        }    }}return crc;

}

3、编译

可以使用以下命令编译程序:

```bashgcc main.c -o getcrc16```

4、使用示例

运行程序时,按照以下格式输入Hex字节数据:

```bash./getcrc16 01 03 00 04 00 04```

输出结果为:

```bash[note] 输入 6 字节的数据:01 03 00 04 00 04[note] CRC16校验值为:0xC805```

转载地址:http://qbwp.baihongyu.com/

你可能感兴趣的文章
Oracle10g下载地址--多平台下的32位和64位
查看>>
Oracle10g安装了11g的ODAC后,PL/SQL连接提示TNS:无法解析指定的连接标识符
查看>>
oracle11g dataguard物理备库搭建(关闭主库cp数据文件到备库)
查看>>
Oracle11G基本操作
查看>>
Oracle11g服务详细介绍及哪些服务是必须开启的?
查看>>
Oracle11g静默安装dbca,netca报错处理--直接跟换操作系统
查看>>
oracle12安装软件后安装数据库,然后需要自己配置监听
查看>>
Oracle——08PL/SQL简介,基本程序结构和语句
查看>>
Oracle——distinct的用法
查看>>
Oracle、MySQL、SQL Server架构大对比
查看>>
oracle下的OVER(PARTITION BY)函数介绍
查看>>
Oracle中DATE数据相减问题
查看>>
Oracle中merge into的使用
查看>>
oracle中sql查询上月、本月、上周、本周、昨天、今天的数据!
查看>>
oracle中sql的case语句运用--根据不同条件去排序!
查看>>
Oracle中Transate函数的使用
查看>>
oracle中关于日期问题的汇总!
查看>>
Oracle中常用的语句
查看>>
Oracle中序列的操作以及使用前对序列的初始化
查看>>
oracle中新建用户和赋予权限
查看>>