您当前的位置:五五电子网电子知识plc技术PLC入门CRC的原理和实现 正文
CRC的原理和实现

CRC的原理和实现

点击数:7915 次   录入时间:03-04 11:55:44   整理:http://www.55dianzi.com   PLC入门
                                            00100         PLC资料网
                                            100           <---校验码
                                           
程序可以如下实现:
    1)将Mx^r的前r位放入一个长度为r的寄存器;
    2)如果寄存器的首位为1,将寄存器左移1位(将Mx^r剩下部分的MSB移入寄存器的LSB),
      再与G的后r位异或,否则仅将寄存器左移1位(将Mx^r剩下部分的MSB移入寄存器的LSB);
    3)重复第2步,直到M全部Mx^r移入寄存器;
    4)寄存器中的值则为校验码。                                        用CRC16-CCITT的生成多项式0x1021,其C代码(本文所有代码假定系统为32位,且都在VC6上 PLC
编译通过)如下:unsigned short do_crc(unsigned char *message, unsigned int len)
{
    int i, j;
    unsigned short crc_reg;
       
    crc_reg = (message[0] << 8) + message[1];
    for (i = 0; i < len; i++)
    {
        if (i < len - 2)
            for (j = 0; j <= 7; j++)
            {
                if ((short)crc_reg < 0)
                    crc_reg = ((crc_reg << 1) + (message[i + 2] >> (7 - i))) ^ 0x1021;
                else PLC资料网
                    crc_reg = (crc_reg << 1) + (message[i + 2] >> (7 - i));     
            }
         else
            for (j = 0; j <= 7; j++)
            {
                if ((short)crc_reg < 0)
                    crc_reg = (crc_reg << 1) ^ 0x1021;
                else
                    crc_reg <<= 1;             PLC资料网
            }        
    }
    return crc_reg;
}  显然,每次内循环的行为取决于寄存器首位。由于异或运算满足交换率和结合律,以及与0异
或无影响,消息可以不移入寄存器,而在每次内循环的时候,寄存器首位再与对应的消息位
异或。改进的代码如下:unsigned short do_crc(unsigned char *message, unsigned int len)
{
    int i, j;
    unsigned short crc_reg = 0;
    unsigned short current;
       
    for (i = 0; i < len; i++)
    {
        current = message[i] << 8;
        for (j = 0; j < 8; j++)
        {

PLC


            if ((short)(crc_reg ^ current) < 0)
                crc_reg = (crc_reg << 1) ^ 0x1021;
            else
                crc_reg <<= 1;
            current <<= 1;           
        }
    }
    return crc_reg;
} 以上的讨论中,消息的每个字节都是先传输MSB,CRC16-CCITT标准却是按照先传输LSB,消息
右移进寄存器来计算的。只需将代码改成判断寄存器的LSB,将0x1021按位颠倒后(0x8408)与
寄存器异或即可,如下所示:unsigned short do_crc(unsigned char *message, unsigned int len) PLC资料网
{
    int i, j;
    unsigned short crc_reg = 0;
    unsigned short current;
       
    for (i = 0; i < len; i++)
    {
        current = message[i];
        for (j = 0; j < 8; j++)
        {
            if ((crc_reg ^ current) & 0x0001)
                crc_reg = (crc_reg >> 1) ^ 0x8408;
            else
                crc_reg >>= 1;
            current >>= 1;           

PLC资料网


        }
    }
    return crc_reg;
}    该算法使用了两层循环,对消息逐位进行处理,这样效率是很低的。为了提高时间效率,通
常的思想是以空间换时间。考虑到内循环只与当前的消息字节和crc_reg的低字节有关,对该
算法做以下等效转换:unsigned short do_crc(unsigned char *message, unsigned int len)
{
    int i, j;
    unsigned short crc_reg = 0;
    unsigned char  index;
    unsigned short to_xor;
      
    for (i = 0; i < len; i++)
    {
        index = (crc_reg ^ message[i]) & 0xff;
        to_xor = index;      
        for (j = 0; j < 8; j++)

PLC

上一页  [1] [2] [3] [4]  下一页


本文关键字:暂无联系方式PLC入门plc技术 - PLC入门