在线情况
楼主
  • 头像
  • 级别
  • 门派
  • 职务总版主
  • 声望+9
  • 财富5
  • 积分3065
  • 经验390701
  • 文章6744
  • 注册2006-03-07
CRC算法及C语言实现
   附件中是“CRC算法及C语言实现.pdf”
   [img]../images/fileType/pdf.gif[/img]此主题相关文件 [url=../../upload/2006/05/06/184437.pdf]184437.pdf[/url]
[ 此帖最后由DC在2012-11-8 0:20:00从 电子通识 转移过来 ]
[COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
在线情况
2
  • 头像
  • 级别
    • 积分27
    • 经验1424
    • 文章33
    • 注册2006-05-06
    生成多项式为G(x),这个G(x)是怎么来得,好像发送序列和接受序列都用到了G(x),谁能告诉我
    微控网感谢您的参与
    在线情况
    3
    • 头像
    • 级别
      • 积分27
      • 经验1424
      • 文章33
      • 注册2006-05-06
      呵呵,明白了,在这个表里,是根据数据序列的位数不同而有不同的G(x)
       
       CRC-4
        x4+x+1

       
       CRC-12
        x12+x11+x3+x+1
         
         
       CRC-16
        x16+x12+x2+1

       
       CRC-ITU**
        x16+x12+x5+1
       
       CRC-32
        x32+x26+x23+...+x2+x+1
       
       CRC-32c
        x32+x28+x27+...+x8+x6+1
      微控网感谢您的参与
      在线情况
      4
      • 头像
      • 级别
        • 积分27
        • 经验1424
        • 文章33
        • 注册2006-05-06
        看了一下CRC的算法,当有所领悟的时候,简单总结了一下,澄清一下文档中难以理解的地方。用它的例子重新表述一下:
        比如要发送4位数据串:1100,所以k=4;P(x)=x3+x2
        而r就是多项式最高次幂,即r=3。
        将P(x)左移r(=3)位 + R(x) 就是要发送的带校验码的数据串。
        R(x)怎么得出呢,首先需要知道G(x):CRC-4 多项式为G(x)= x4+x+1 ,即:1011;
        发送方编码方法:将P(x)乘以2r(即对应的二进制码序列左移r位),再除以G(x),所得余式即为R(x)。所以1100 000 /1011 = 1110余010,所以R(x)=010,占r(=3)位。
        所以最后发送的字符串就是1100 000 + 010 = 1100 010
                      1110
                    -------  
              1011 /1100000    
                    1011
                    ----
                     1110
                     1011
                     -----
                      1010
                      1011
                      -----
                       0010
                       0000
                       ----
                        010

        收到这串数据后,如果传输无误,则该串数据/G(x)没有余数,也就是1100 010 / 1011可以除尽。否则就认为有误码。

        以上数据串所用的除法是:模2减运算法则,既是不带进位和借位的按位减法,举例来看,1100-1011 = 0111,可以发现,这种运算其实是一种按位异或运算。所以编程就相对容易一些了。
        微控网感谢您的参与
        在线情况
        5
        • 头像
        • 级别
          • 积分27
          • 经验1424
          • 文章33
          • 注册2006-05-06
          利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的 r位监督码(CRC码) ,附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
          微控网感谢您的参与
          在线情况
          6
          • 头像
          • 级别
            • 积分27
            • 经验1424
            • 文章33
            • 注册2006-05-06
            为什么对CRC校验这么关心呢,因为在RS-485通讯中要用Modbus协议,这个协议如果使用RTU模式时要对每帧数据进行CRC校验,所以要想看懂人家的代码,就对对他的原理十分了解了。
            使用RTU模式,消息包括了一基于CRC方法的错误检测域。CRC域检测了整个消息的内容。
            CRC域是两个字节,包含一16位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。
            CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。
            CRC产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重复8次。在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。
            CRC添加到消息中时,低字节先加入,然后高字节。
            微控网感谢您的参与
            在线情况
            7
            • 头像
            • 级别
              • 积分27
              • 经验1424
              • 文章33
              • 注册2006-05-06
              所以想通过实验看他是怎么回事,就编个简单的单片机程序仿真一下:

              #include  <msp430x14x.h>

              const unsigned char auchCRCHi[] = {
              0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
              0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
              0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
              0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
              0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
              0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
              0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
              0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
              0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
              0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
              0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
              0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
              0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
              0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
              0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
              0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
              0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
              0x40
              } ;

              const unsigned  char auchCRCLo[] = {
              0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
              0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
              0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
              0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
              0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
              0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
              0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
              0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
              0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
              0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
              0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
              0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
              0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
              0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
              0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
              0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
              0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
              0x40
              };

                  unsigned char rx_buffer[4]={0x12,0x34,0x56,0x78};
                  unsigned int crc_reasult=0;
              unsigned int crc(unsigned char *puchMsg , unsigned short usDataLen)
              {
                  unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
                  unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
                  unsigned char uIndex ;  /* will index into CRC lookup table */
                 
                  while (usDataLen--) /* pass through message buffer */
                  {
                      uIndex = uchCRCHi ^ *puchMsg++ ; /* calculate the CRC */
                      uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
                      uchCRCLo = auchCRCLo[uIndex] ;
                  }
                  return (uchCRCHi << 8 | uchCRCLo) ;
              }


              void main(void){

                 
                  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
                  crc_reasult = crc(rx_buffer,1);
                  crc_reasult =  crc_reasult ;
              }
              仿真结果:crc_reasult = 0x3F4D, 这就是要跟在数据串后面的CRC校验码,大家可以不必理解算法的实现,直接用就能大大降低误码率。但要注意:往数据序列里加CRC码的时候,要先加低字节,再加高字节,即0x4D,0x3F。
              微控网感谢您的参与
              在线情况
              8
              • 头像
              • 级别
                • 积分27
                • 经验1424
                • 文章33
                • 注册2006-05-06
                生成CRC-16校验字节的步骤如下:
                ①装如一个16位寄存器,所有数位均为1。
                ②该16位寄存器的高位字节与开始8位字节进行“异或”运算。运算结果放入这个16位寄存器。
                ③把这个16寄存器向右移一位。
                ④若向右(标记位)移出的数位是1,则生成多项式1010000000000001和这个寄存器进行“异或”运算;若向右移出的数位是0,则返回③。
                ⑤重复③和④,直至移出8位。
                ⑥另外8位与该十六位寄存器进行“异或”运算。
                ⑦重复③~⑥,直至该报文所有字节均与16位寄存器进行“异或”运算,并移位8次。
                ⑧这个16位寄存器的内容即2字节CRC错误校验,被加到报文的最高有效位。
                微控网感谢您的参与
                在线情况
                9
                • 头像
                • 级别
                  • 积分27
                  • 经验1424
                  • 文章33
                  • 注册2006-05-06
                  改了一下程序,用串口调试助手发送16进制字符串:12 34 0C C7 ,其中0x1234是要校验的数据,0x0cc7是由0x1234生成的16位CRC校验码,msp430单片机收到后将校验码分离装入crc_temp,并对前两字节数据0x1234重新依据规则生成校验码,装入crc_reasult.如果两者相等,则说明该串数据有效,返回给上位机'Y',如果在传输过程中产生误码,则返回'N'。程序共享如下:

                  #include  <msp430x14x.h>


                  const unsigned char auchCRCHi[] = {
                  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
                  0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
                  0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
                  0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
                  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
                  0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
                  0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
                  0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
                  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
                  0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
                  0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
                  0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
                  0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
                  0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
                  0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
                  0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
                  0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
                  0x40
                  } ;

                  const unsigned  char auchCRCLo[] = {
                  0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
                  0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
                  0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
                  0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
                  0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
                  0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
                  0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
                  0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
                  0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
                  0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
                  0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
                  0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
                  0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
                  0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
                  0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
                  0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
                  0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
                  0x40
                  };

                  unsigned char rx_buffer[4];
                  static char index=0;

                  unsigned int crc(unsigned char *puchMsg , unsigned short usDataLen)
                  {
                      unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
                      unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
                      unsigned char uIndex ;  /* will index into CRC lookup table */
                     
                      while (usDataLen--) /* pass through message buffer */
                      {
                          uIndex = uchCRCHi ^ *puchMsg++ ; /* calculate the CRC */
                          uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
                          uchCRCLo = auchCRCLo[uIndex] ;
                      }
                      return (uchCRCHi << 8 | uchCRCLo) ;
                  }
                  unsigned char rtu_crc_anlys(unsigned char *source_p){
                      unsigned char tmp1, tmp2;
                      unsigned int crc_reasult=0;
                      unsigned int crc_temp=0;
                      tmp1 = *(source_p+2);
                      tmp2 = *(source_p+3);
                      crc_temp = (((unsigned int)tmp1)<<8) + (unsigned int)tmp2;
                      crc_reasult = crc(source_p,2);
                      if(crc_temp == crc_reasult){
                          return 1;
                      }else return 0;
                  }
                  void main(void)
                  {
                    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
                    P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD
                    ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
                    UCTL0 |= CHAR;                            // 8-bit character
                    UTCTL0 |= SSEL0;                          // UCLK = ACLK
                    UBR00 = 0x03;                             // 32k/9600 - 3.41
                    UBR10 = 0x00;                             //
                    UMCTL0 = 0x4A;                            // Modulation
                    UCTL0 &= ~SWRST;                          // Initialize USART state machine
                    IE1 |= URXIE0;                            // Enable USART0 RX interrupt
                      while(1){
                           _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupt
                          if(rtu_crc_anlys(rx_buffer)==1){
                              while (!(IFG1 & UTXIFG0));                // USART0 TX buffer ready?
                              TXBUF0 = 'Y';
                          }else {
                              while (!(IFG1 & UTXIFG0));                // USART0 TX buffer ready?
                              TXBUF0 = 'N';
                           }
                      }
                  }

                  #pragma vector=UART0RX_VECTOR
                  __interrupt void usart0_rx (void)
                  {
                    rx_buffer[index++] = RXBUF0;
                    if(index==4) LPM3_EXIT;
                    index%=4;  
                  }

                  微控网感谢您的参与
                  在线情况
                  10
                  • 头像
                  • 级别
                    • 积分8
                    • 经验678
                    • 文章13
                    • 注册2007-08-31
                    谢谢 hoohoo 分享,很有价值啊!!!
                    微控网感谢您的参与
                    在线情况
                    11
                    • 头像
                    • 级别
                      • 积分10
                      • 经验1840
                      • 文章55
                      • 注册2007-03-27
                      请问谁有CRC12的表呢?想对照一下
                      微控网感谢您的参与
                      在线情况
                      12
                      • 头像
                      • 级别
                        • 积分8
                        • 经验4358
                        • 文章48
                        • 注册2008-04-21
                        真的值得学习
                        微控网感谢您的参与
                        Powered by LeadBBS 9.2 .
                        Page created in 0.2812 seconds with 8 queries.