CRC16循环冗余校验 RTU-MODBUS标准 Linux C

1、概述

CRC16循环冗余校验常用在MODBUS协议中,用于校验报文的完整性。CRC16校验值为uint16_t 无符号整形2字节,在MODBUS协议中,低检验字节在前,高校验字节在后,比如校验结果crc16=0x1788,则MODBUS中的校验顺序为 ...0x88 0x17。

以下为自己写的linux C 代码,可以直接用。

2、C程序

/*******************************************************************************
_____ ___ ____  ___   _____    _             _   _             
| ____|_ _|  _ \|_ _| |_   _|__(_)_ __   __ _| | | |_   _  __ _ 
|  _|  | || |_) || |    | |/ __| | '_ \ / _` | |_| | | | |/ _` |
| |___ | ||  _ < | |    | |\__ \ | | | | (_| |  _  | |_| | (_| |
|_____|___|_| \_\___|   |_||___/_|_| |_|\__, |_| |_|\__,_|\__,_|
  * File Name          : main.c
  * Description        : This file provides code for crc16 caculation in linuxc.
  * Author             : jackwang by jiawang16@foxmail.com
  * Date               : 2018-07-15
*******************************************************************************/
/*! -------------------------------------------------------------------------- */
/*! Include headers */
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

/*! -------------------------------------------------------------------------- */
/*! Private function declarations */
static unsigned char Char2Int(char chr,bool *isOK);/*! convert char to int type*/
static unsigned char HexStr2Int(char *str, bool *isOK);/*!convert hexstr to int*/
/*! caculate crc16 of buff-input:arr_buff and length: len */
static unsigned short GenerateCRC16(unsigned char *arr_buff, unsigned short len);

/*! -------------------------------------------------------------------------- */
/*! main function defination */
int main(int argc, char* argv[])
{
  /*! variable define */
  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]  no params to caculate, please input hex string,
                                            splite by space!\r\n");
  }
  else{
    printf("[note]  input %d byte: ",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 value: 0x%04X\r\n",crcVal);
  }
  return 0;
}

/*! -------------------------------------------------------------------------- */
/*! Private function definations */
/*! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
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]  invalid hex str input: %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 *arr_buff, unsigned short len)
{
    unsigned short crc=0xFFFF;
    unsigned char i, j;
    for ( j=0; j < len;j++){
        crc=crc ^*arr_buff++;
        for ( i=0; i<8; i++) {
            if( ( crc&0x0001) >0){
                crc=crc>>1;
                crc=crc^ 0xa001;
            }
            else{ crc=crc>>1;}
        }
    }
    return crc;
}

3、编译

~$ gcc main.c -o getcrc16

4、使用

 
~$ ./getcrc16 01 03 00 04 00 04
~$ [note]  input 6 byte: 01 03 00 04 00 04
~$ [note]  crc16 value: 0xC805


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值