tag 标签: crc16

相关博文
  • 热度 21
    2015-8-5 12:59
    1748 次阅读|
    0 个评论
      ;modbus CRC16 TEST_CRC16:  ;R0,R3,R4,DPH,DPL,A,PSW.   R0为起始单元   R4为数据长度,结果在DPH,DPL中   ;① 装入一个16位寄存器,所有数位均为1。        MOV DPH,#0FFH              MOV DPL,#0FFH CRCJ1:       MOV R3,#8              MOV A,@R1              XRL A,DPL        ;② 该16位寄存器的低位字节与开始8位字节进行"异或"运算。运算结果放入这个16 位寄存器。        MOV DPL,A  CRCJ2:       MOV A,DPH       CLR C       RRC A       MOV DPH,A       MOV A,DPL       RRC A       MOV DPL,A ;③ 把这个16寄存器向右移一位。        JNC  CRCJ3 ;④ 若向右(标记位)移出的数位是1,则用多项式1010000000000001 和这个寄存器进行"异或"运算;若向右移出的数位是0,则返回③。   ;--------------       MOV A,#01H       XRL A,DPL       MOV DPL,A       MOV A,#0A0H       XRL A,DPH       MOV DPH,A CRCJ3: ;⑤ 重复③和④,直至移出8位。        DJNZ R3,CRCJ2 ;⑥ 另外8位与该十六位寄存器进行"异或"运算。        INC R1 ;⑦ 重复③~⑥,直至该报文所有字节均与16位寄存器进行"异或"运算,并移位8次。        DJNZ R4,CRCJ1 CRC_END: ;⑧ 这个16位寄存器的内容即2字节CRC错误校验,被加到报文的最高有效位。  ;MOV 70H,DPL   ;发送与返回的CRC16代码,低字节在前,高字节在后 ;MOV 71H,DPH RET  
  • 热度 15
    2014-9-20 18:10
    1822 次阅读|
    1 个评论
    在看别人使用FPGA写CRC16校验码的程序时,看不懂。于是根据百度提供的校验生成方法,自己编写了这个CRC16校验码生成的C程序。 测试了几组数据,生成的校验码都正确。
  • 热度 31
    2013-11-17 20:37
    3397 次阅读|
    0 个评论
            生成CRC码的基本原理:       任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。       CRC码集选择的原则:若设码字长度为N,信息字段为K位,校验字段为R位(N=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式。   //  本程序使用的多项式是   x^12 + x^5 + x^0 // C00  = ........X...X... X...X... // C01  = .........X...X.. .X...X.. // C02  = ..........X...X. ..X...X. // C03  = ...........X...X ...X...X // C04  = ............X... ....X... // C05  = ........X...XX.. X...XX.. // C06  = .........X...XX. .X...XX. // C07  = ..........X...XX ..X...XX // C08  = X..........X...X ...X...X // C09  = .X..........X... ....X... // C10  = ..X..........X.. .....X.. // C11  = ...X..........X. ......X. // C12  = ....X...X...X..X X...X..X // C13  = .....X...X...X.. .X...X.. // C14  = ......X...X...X. ..X...X. // C15  = .......X...X...X ...X...X // module crc16_dat8 (crc_in,dat_in,crc_out); input crc_in; input dat_in; output crc_out; wire crc_out; generate     crc16_dat8_flat cc (.crc_in(crc_in),.dat_in(dat_in),.crc_out(crc_out)); endgenerate endmodule     module crc16_dat8_flat (crc_in,dat_in,crc_out); input crc_in; input dat_in; output crc_out; wire crc_out; wire x7, x6, x5, x4, x3, x2, x1,         x0, x15, x14, x13, x12, x11, x10, x9,         x8; assign crc_out = {x15,x14,x13,x12,x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1,         x0}; wire d0,d1,d2,d3,d4,d5,d6,d7; assign { d7,d6,d5,d4,d3,d2,d1,d0} = dat_in ; wire c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,     c15; assign { c15,c14,c13,c12,c11,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,         c0} = crc_in ;     xor6 x7i (.out(x7),.a(c10),.b(d6),.c(c14),.d(d2),.e(c15),.f(d7));  // 6 ins 1 outs     xor6 x6i (.out(x6),.a(c9),.b(d5),.c(c13),.d(d1),.e(c14),.f(d6));  // 6 ins 1 outs     xor6 x5i (.out(x5),.a(c8),.b(d4),.c(c12),.d(d0),.e(c13),.f(d5));  // 6 ins 1 outs     xor6 x4i (.out(x4),.a(c12),.b(d4),.c(1'b0),.d(1'b0),.e(1'b0),.f(1'b0));  // 2 ins 1 outs     xor6 x3i (.out(x3),.a(c11),.b(d7),.c(c15),.d(d3),.e(1'b0),.f(1'b0));  // 4 ins 1 outs     xor6 x2i (.out(x2),.a(c10),.b(d6),.c(c14),.d(d2),.e(1'b0),.f(1'b0));  // 4 ins 1 outs     xor6 x1i (.out(x1),.a(c9),.b(d5),.c(c13),.d(d1),.e(1'b0),.f(1'b0));  // 4 ins 1 outs     xor6 x0i (.out(x0),.a(c8),.b(d4),.c(c12),.d(d0),.e(1'b0),.f(1'b0));  // 4 ins 1 outs     xor6 x15i (.out(x15),.a(c11),.b(d7),.c(c15),.d(d3),.e(c7),.f(1'b0));  // 5 ins 1 outs     xor6 x14i (.out(x14),.a(c10),.b(d6),.c(c14),.d(d2),.e(c6),.f(1'b0));  // 5 ins 1 outs     xor6 x13i (.out(x13),.a(c9),.b(d5),.c(c13),.d(d1),.e(c5),.f(1'b0));  // 5 ins 1 outs     assign x12 = c8 ^ d4 ^ c12 ^ d0 ^ c15 ^ d7 ^ c4;  // 7 ins 1 outs     xor6 x11i (.out(x11),.a(c14),.b(d6),.c(c3),.d(1'b0),.e(1'b0),.f(1'b0));  // 3 ins 1 outs     xor6 x10i (.out(x10),.a(c13),.b(d5),.c(c2),.d(1'b0),.e(1'b0),.f(1'b0));  // 3 ins 1 outs     xor6 x9i (.out(x9),.a(c12),.b(d4),.c(c1),.d(1'b0),.e(1'b0),.f(1'b0));  // 3 ins 1 outs     xor6 x8i (.out(x8),.a(c11),.b(d7),.c(c15),.d(d3),.e(c0),.f(1'b0));  // 5 ins 1 outs endmodule      
  • 热度 18
    2010-8-6 08:27
    3675 次阅读|
    3 个评论
    3.2 字节查表法 unsigned char code crc_ta = {   #else    const unsigned short crc_ta = {                    /* CRC余式表 */   #endif        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,       0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,       0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,       0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,       0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,       0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,       0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,       0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,       0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,       0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,       0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,       0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,       0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,       0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,       0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,       0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,       0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,       0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,       0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,       0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,       0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,       0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,       0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,       0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,       0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,       0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,       0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,       0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,       0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,       0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,       0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,       0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0       };   unsigned short CalCRC16Quick(unsigned char *ptr,  unsigned char len)    {       unsigned short crc;       unsigned char da;          crc=0;       while(len--!=0) {       da=(unsigned char) (crc/256);                       /* 以8位二进制数的形式暂存CRC的高8位 */       crc=8;                                          /* 左移8位,相当于CRC的低8位乘以  */       crc^=crc_ta ;                               /* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */       ptr++;       }       return(crc);   }   #endif   注: 未经我们验证. 3.3 半字节查表法 从网络资料中我们理解到这样的结论: 该方法速度强于基本运算法, 对code空间的要求, 低于字节查表法(512bytes array). unsigned short CalCRC16(unsigned char *ptr,  unsigned char len)   {       unsigned short crc;       unsigned char da;       unsigned short crc_ta ={   0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef       };     crc = 0;       while(len--!=0)        {           da = ((unsigned char)(crc/256))/16;                  crc=4;                                             crc^=crc_ta ;                           da = ((unsigned char)(crc/256))/16;                  crc=4;                                             crc^=crc_ta ;                         ptr++;       }       return(crc);   }  注: 该函数, 经过了我们对1字节(0x00, 0x01, 0x0f)的CRC结果的验证, 它们的结果分别是: 0x0000, 0x1021, 0xf1ef. 4. 结论: 当我们不得不引入 CRC 计算时, 半字节查表法在微处理器有限的资源下, 看起来是最适合的算法模式. 同时我们也对文中 16 bit 的 0x1021 CRC 码的半字节查表法的例程, 做了1字节的简单结果验证. Allen 通宵工作于 2010.8.5 深圳 使用半字节查表法之CRC16的code sample(一) 使用半字节查表法之CRC16的code sample(二)  
  • 热度 24
    2010-8-6 08:26
    5236 次阅读|
    6 个评论
    在进行通讯的过程中, 我们需要和CRC打交道. Allen觉得, 尽管在很多时候, CRC并不是那么重要. 但是出于通讯协议兼容, 我们往往被迫使用CRC计算. 在通宵的工作过程中, Allen 对网络资源进行了一番整理, 并自行加入理解, 便于同行们, 在相应工作时, 节省大量查阅资料的时间. 前提: 1. 运算法则的可靠性: 在反复检索资料后, Allen 意识到, 弄清运算法则需要至少1个工作日, 用大量实例和思考, 并配合相当的实例进行思考. 在极大的项目时间压力下, 我们放弃这个know-why 的行为. 我们接受现有算法, 作为"定理"的引用, 而非作为一个严谨算数逻辑推导的结果. CRC要素: 1. 多项式除法 在进行 CRC 计算之前, 我们不得不重温多项式除法. 检索:   http://certmaths.ilongman.com/chi/ppt/ch03/lecture03_02c.ppt 的 ppt 文档. 大致我们知道: 多项式除以单项式时, 我们可以使用分配率. 而多项式除以多项式时, 我们必须使用长除法. 2. CRC原理 简单描述: 把待传送的数据 M 的二进制码序列看成多项式 M, 事先选定一个 r+1 bit 的二进制数看成多项式 P, 把多项式 M 除以 P, 得到商Q 和余数 R(r bit), 把余数 R 附加在信息码 M 一起发送. 在接收端, 使用同样的 M/P 获取余数 R', 与 R 比较验证 M 是否正确. 引用讨论: http://topic.csdn.net/u/20090625/09/d3121402-443c-4d6d-be2d-6746f9434c72.html 举例说明: 信息位: 1011001 CRC码: 4位 r = 4 校验多项式(生成码): 11001 (x4+x3+1) 运算步骤: 1011001 - 左移4位 - 10110010000 - 除以 11001 - 遵守运算法则: 不借位除法, 即异或运算, 得到结果(余数) 1010, 即为 CRC 码. 3. 例程实现: CRC的算法包括: 基本算法, 字节查表法, 半字节查表法 我们主要讨论 16 bit 的 CRC 实现, 使用 CRC16-CCITT, 也即是 X16+X12+X5+1, 生成码为 0x1021. 本来实际值应该是 0x010121, 这里又引入了一个运算法则: "最高位一定为1故抛弃", 因此是 0x1021. 3.1 基本算法: http://read.pudn.com/downloads90/sourcecode/embed/341559/crc.c__.htm /****************************************************************   *函数性质:公共   *入口:要进行CRC校验的数据缓冲unsigned char *ptr,要进行CRC校验的数据长度   *出口:CRC计算结果   *功能:CRC16计算(计算速度慢,程序空间小)   *调用方式:unsigned short CalCRC16Slow(unsigned char *ptr, unsigned char len)  *****************************************************************/   #if CRC16 == CRC16SLOW    unsigned short CalCRC16Slow(unsigned char *ptr, unsigned char len)   {       unsigned char i;       unsigned short crc = 0;       while(len--!=0)        {           for(i = 0x80; i != 0; i/=2)            {               if((crc0x8000)!=0)                {                   crc*=2;                    crc^=0x1021;               }                                           /* 余式CRC乘以2再求CRC  */               else crc*=2;               if((*ptri)!=0) crc^=0x1021;                /* 再加上本位的CRC */           }           ptr++;       }       return(crc);   }   #endif    注: 我们未验证该例程. 并注意到这里又引入了一个运算法则: 使用模2的方式, 进行异或运算(应该指不借位除法). 使用半字节查表法之CRC16的code sample(一) 使用半字节查表法之CRC16的code sample(二)  
相关资源