wangzs728 发表于 2021-9-7 10:03:13

使用CF块写的CRC-16/MODBUS校验例程

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
其中计算原理为初始化校验码寄存器(0xffff),将要发送值逐帧(一个字节)获取,并先进行一次与校验码寄存器的异或,之后再使用移位指令对寄存器内的值逐位依次进行比较,为1则移位后异或一次,为0则移位后比较下一位,直到8位均比较完成后再获取下一帧数据重复进行,直到全部比较完成。
大致程序如下:

运算结果以及网络工具运算结果:


变量列表:

↓↓↓↓↓↓↓↓↓ 源代码 ↓↓↓↓↓↓↓↓↓
      /***************************************************************
      **使用两个for循环对数据内容进行逐一对比,
      **第一个for循环将数据从首地址—>末地址拆分成多个字节;
      **第二个for循环对每个字节进行8次异或、移位,
      **如果异或后最低位(LSB)不为0则将CRC码异或上多项式值(0xA001);
      **多项式值可为通讯双方约定好数值/标准多项式;
      **全部计算完成后分开为高八位低八位分别输出,方便使用
      ****************************************************************/
#include "math.h"
#include "stdio.h"
#include "plc300.h"
U16 CRCw;                //存放计算结果
U8 t1, t2, data_n, CRCL, CRCH;                //中间变量

void CRC( void* S_Add, U16 Len, U8 *L_CRC, U8 *H_CRC)
{
      //变量说明:
      //S_Add:数据首地址
      //Len:数据长度
      //L_CRC:校验码低八位
      //H_CRC:校验码高八位
      CRCw = 0xffff ;                //初始化CRC寄存器

      for(t1=0; t1<Len; t1++)                //在首地址到首地址+*Len 地址之间逐个进行异或运算
      {
                data_n = getU8(S_Add+t1);
                CRCw ^= data_n;                        //将数据异或到CRCw
                for(t2=0; t2<8; t2++)                //对每次运算的8bit二进制进行异或比较
                {
                        if((CRCw & 0x0001) != 0)                //比较最低位,为1则进行CRC异或,为0则继续下一位比较
                        {
                              CRCw >>=1 ;
                              CRCw ^= 0xA001 ;
                        }
                        else
                        {
                              CRCw >>=1 ;
                        }
                }
      }

      CRCL = CRCw&0x00ff ;                //获取低8位CRC校验码
      CRCH = CRCw>>8 ;                        //获取高8位CRC校验码
      setU8(L_CRC,CRCL) ;                //输出低8位CRC校验码
      setU8(H_CRC,CRCH);                //输出高8位CRC校验码
}      





页: [1]
查看完整版本: 使用CF块写的CRC-16/MODBUS校验例程