crc查表法实现

2012-11-23 13:22 926 0 分类: MCU/ 嵌入式 文集: 外围电路,常用IC模数,存储,时钟等

 

CRC校验 CRC程序

为保证传输过程的正确性,需要对通信过程进行差错控制。差错控制最常用的方法是自动请求重发方式(ARQ)、向前纠错方式(FEC)和混合纠错(HEC)。在传输过程误码率比较低时,用FEC方式比较理想。在传输过程误码率较高时,采用FEC容易出现“乱纠”现象。HEC方式则是ARQ和FEC的结合。在许多数字通信中,广泛采用ARQ方式,此时的差错控制只需要检错功能。实现检错功能的差错控制方法很多,传统的有:奇偶校验、校验和检测、重复码校验、恒比码校验、行列冗余码校验等,这些方法都是增加数据的冗余量,将校验码和数据一起发送到接受端。接受端对接受到的数据进行相同校验,再将得到的校验码和接受到的校验码比较,如果二者一致则认为传输正确。但这些方法都有各自的缺点,误判的概率比较高。
循环冗余校验CRC(Cyclic Redundancy Check)是由分组线性码的分支而来,其主要应用是二元码组。编码简单且误判概率很低,在通信系统中得到了广泛的应用。下面重点介绍了CRC校验的原理及其算法实现。

CRC校验可以100%地检测出所有奇数个随机错误和长度小于等于k(k为g(x)的阶数)的突发错误。所以CRC的生成多项式的阶数越高,那么误判的概率就越小。

CRC代码的一些基本概念和运算:

CRC多项式:

例:

代码:1010111 对应的多项式为:X6+X4+X2+X+1

多项式X5+X3+X2+X1+1对应的代码为101111


CRC生成多项式:

首位和最后一位必须是1。CRC生成多项式是给定的,在传输过程中不变,即发送和接收端生成码相同。

一些常用的校验码为:

CRC8=X8+X5+X4+1

CRC-CCITT=X16+X12+X5+1

CRC16=X16+X15+X5+1

CRC12=X12+X11+X3+X2+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1


CRC的运算本质是异或运算(模2除法)

例:原信息码为1011001

生成码为11001

校验码计算过程

①     将信息码左移4位(生成码长-1);得到10110010000

②     异或运算

10110010000

   11001

   01111010000(前面的数进行异或运算,后面的直接抄下来)

11001

0011110000(和生成码异或运算的必须从1开始)

11001

00111000

    11001

    001010

这样得到的结果为1010,即为所需要的校验码,添加到信息码后,得到发送的代码为:

10110011010

汇编源代码

BUFFER   EQU 40H

org 0000h
sjmp star

star: MOV R0,#BUFFER

MOV R1,#BUFFER
lcall check_sum


;enter r1 - data address数据开始的地址 R7数据长度
;out: r3,r2 crc16(hi lo)


check_sum:nop
crc_sum:mov r3,#0ffh
mov r2,#0ffh


crcloop:mov a,@r1
inc r1
xrl a,r3
push acc
mov dptr,#crc_hi
movc a,@a+dptr
xrl a,r2
mov r3,a
pop acc
mov dptr,#crc_lo
movc a,@a+dptr
mov r2,a
djnz r7,crcloop
ret


crc_hi: db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h
db 000h, 0C1h, 081h, 040h, 000h, 0C1h, 081h, 040h, 001h, 0C0h
db 080h, 041h, 001h, 0C0h, 080h, 041h, 000h, 0C1h, 081h, 040h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 000h, 0C1h
db 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h, 080h, 041h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 000h, 0C1h
db 081h, 040h, 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 000h, 0C1h, 081h, 040h
db 001h, 0C0h, 080h, 041h, 001h, 0C0h, 080h, 041h, 000h, 0C1h
db 081h, 040h, 001h, 0C0h, 080h, 041h, 000h, 0C1h, 081h, 040h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 000h, 0C1h, 081h, 040h
db 001h, 0C0h, 080h, 041h, 000h, 0C1h, 081h, 040h, 001h, 0C0h
db 080h, 041h, 001h, 0C0h, 080h, 041h, 000h, 0C1h, 081h, 040h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h
db 000h, 0C1h, 081h, 040h, 000h, 0C1h, 081h, 040h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h
db 001h, 0C0h, 080h, 041h, 000h, 0C1h, 081h, 040h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h, 000h, 0C1h, 081h, 040h
db 001h, 0C0h, 080h, 041h, 001h, 0C0h, 080h, 041h, 000h, 0C1h
db 081h, 040h, 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h
db 000h, 0C1h, 081h, 040h, 001h, 0C0h, 080h, 041h, 001h, 0C0h
db 080h, 041h, 000h, 0C1h, 081h, 040h

crc_lo: db 000h, 0C0h, 0C1h, 001h, 0C3h, 003h, 002h, 0C2h, 0C6h, 006h
db 007h, 0C7h, 005h, 0C5h, 0C4h, 004h, 0CCh, 00Ch, 00Dh, 0CDh
db 00Fh, 0CFh, 0CEh, 00Eh, 00Ah, 0CAh, 0CBh, 00Bh, 0C9h, 009h
db 008h, 0C8h, 0D8h, 018h, 019h, 0D9h, 01Bh, 0DBh, 0DAh, 01Ah
db 01Eh, 0DEh, 0DFh, 01Fh, 0DDh, 01Dh, 01Ch, 0DCh, 014h, 0D4h
db 0D5h, 015h, 0D7h, 017h, 016h, 0D6h, 0D2h, 012h, 013h, 0D3h
db 011h, 0D1h, 0D0h, 010h, 0F0h, 030h, 031h, 0F1h, 033h, 0F3h
db 0F2h, 032h, 036h, 0F6h, 0F7h, 037h, 0F5h, 035h, 034h, 0F4h
db 03Ch, 0FCh, 0FDh, 03Dh, 0FFh, 03Fh, 03Eh, 0FEh, 0FAh, 03Ah
db 03Bh, 0FBh, 039h, 0F9h, 0F8h, 038h, 028h, 0E8h, 0E9h, 029h
db 0EBh, 02Bh, 02Ah, 0EAh, 0EEh, 02Eh, 02Fh, 0EFh, 02Dh, 0EDh
db 0ECh, 02Ch, 0E4h, 024h, 025h, 0E5h, 027h, 0E7h, 0E6h, 026h
db 022h, 0E2h, 0E3h, 023h, 0E1h, 021h, 020h, 0E0h, 0A0h, 060h
db 061h, 0A1h, 063h, 0A3h, 0A2h, 062h, 066h, 0A6h, 0A7h, 067h
db 0A5h, 065h, 064h, 0A4h, 06Ch, 0ACh, 0ADh, 06Dh, 0AFh, 06Fh
db 06Eh, 0AEh, 0AAh, 06Ah, 06Bh, 0ABh, 069h, 0A9h, 0A8h, 068h
db 078h, 0B8h, 0B9h, 079h, 0BBh, 07Bh, 07Ah, 0BAh, 0BEh, 07Eh
db 07Fh, 0BFh, 07Dh, 0BDh, 0BCh, 07Ch, 0B4h, 074h, 075h, 0B5h
db 077h, 0B7h, 0B6h, 076h, 072h, 0B2h, 0B3h, 073h, 0B1h, 071h
db 070h, 0B0h, 050h, 090h, 091h, 051h, 093h, 053h, 052h, 092h
db 096h, 056h, 057h, 097h, 055h, 095h, 094h, 054h, 09Ch, 05Ch
db 05Dh, 09Dh, 05Fh, 09Fh, 09Eh, 05Eh, 05Ah, 09Ah, 09Bh, 05Bh
db 099h, 059h, 058h, 098h, 088h, 048h, 049h, 089h, 04Bh, 08Bh
db 08Ah, 04Ah, 04Eh, 08Eh, 08Fh, 04Fh, 08Dh, 04Dh, 04Ch, 08Ch
db 044h, 084h, 085h, 045h, 087h, 047h, 046h, 086h, 082h, 042h
db 043h, 083h, 041h, 081h, 080h, 040h

C语言代码

#include<reg51.h>
#define uchar unsigned char


uchar xdata OPEN[] = {
       0xb1,0x02,0x00,0x00,0x00,0x00,0x00,0x00
       }; //末尾CRC


unsigned char code 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

} ;

 

/* Table of CRC values for low–order byte */

unsigned char code 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

} ;


//example to calculate the crc of the data in message stored in memory location *puchMsg

unsigned short CRC16(unsigned char *puchMsg, unsigned char usDataLen)

{

        unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */

        unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */

        unsigned 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) ;

}
main(void)
{
unsigned int temp0;
temp0 =CRC16(OPEN,4);
do{
}while(1);
}

广告

文章评论 0条评论)

登录后参与讨论
相关推荐阅读
liang890319_284707880 2016-03-22 11:41
[博客大赛]我在搞嵌入式 我有罪
  我在搞嵌入式 我有罪 做嵌入式也有几年了 刚学习的时候书上说嵌入式的定义是以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计...
liang890319_284707880 2015-10-22 11:57
帕萨特迈腾蒙迪欧哪个好
氵灬清风灬说:太小了,没法穿了,懒得换了 junyao00022说:............................... jd272475byp说:宝贝收到啦,衣服质量非常不错,...
liang890319_284707880 2015-10-22 11:56
二手荣威550和二手起亚k2哪个好
二手荣威550和二手起亚k2哪个好   风之乞说:衣服挺好的,就是偏小,已经更换了 梦里水乡0609说:不错 很好  不了不错  赞 四灵之首说:衣服质量不错,韵达快递不行~ ...
liang890319_284707880 2015-10-22 11:55
澳大利亚深海鱼油哪个牌子好
hgjfhgj说:不错  价格便宜  款式不错  开始买中码小了一点  免费给换的  好店家 小杰c子说:非常合适。也很有气质 天佑945说:还可以,性价比高。。。。。。。。。。 Ab...
liang890319_284707880 2015-10-19 11:03
常用DDR sdram和Flash型号
  以下是代码片段: http://blog.csdn.net/myarrow/article/details/7854863   主要是三星 现代 ...
liang890319_284707880 2013-09-29 17:00
ROM FLASH RAM
EPROM、EEPROM、FLASH的总结性区别   http://xdc0363.blog.163.com/blog/static/11546200220...
我要评论
0
0
广告