CRC源码大全
2012-06-18
标签: CRC

循环冗余校验码(Cylclic Redundancy Check Code),简称CRC码。常用的CRC数有8,16,32,CRC位数越大,数据越不易受干扰,但运算时间加长。一般关于通信的书籍都有介绍。简单原理是将要传输的数据视为一堆连续位组成的一整个数值,并将此数值除一个特定的除数,通常以二进制表示,此除数称为衍生多项式(Generation Polynomial).

一般数据量不大时,使用Checksume验错方式就行了;数据量大时,就用CRC了;据理论统计,用CRC16时,超过17个连续位的错误侦测率为99。9969,小于此的为100。

1、CRC-12 的生成多项式为:P(x)=X^12 X^11 X^3 X^2 1

2、

CRC MOV DPH, #table ; 指向余式表下半区

MOV DPL, R0 ; 指向对应单元

CLR A ;

MOVC A, @A DPTR ; 读余式的高字节

XRL A, R1 ; 计算余式的高字节

MOV R0, A ; 存入R0

INC DPH ; 指向余式表上半区

CLR A ;

MOVC A, @A DPTR ; 读余式的低字节

XRL A, R2 ; 计算余式的低字节

MOV R1, A ; 存入R1

RET

这个是对于三字节的东东,你自己还要造张余式表

3、很简单的查表法

unsigned int UpdateCRC(unsigned char byte,unsigned int crc);

#include

#include "crc16.h"

static code unsigned int Crc16Table[256] =

{

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 int UpdateCrc16(unsigned char Octet,unsigned int CRC)

{

return Crc16Table[ (CRC >> 8) & 255] ^ (CRC << 8) ^ Octet;

}

unsigned int UpdateCRC(unsigned char Octet,unsigned int CRC)

{

return (CRC << 8) ^ Crc16Table[ (CRC >> 8) ^ Octet ];

}

4、

_CRC:

MOV A,R7 ;CRC INPUT POINTER

MOV R1,A

MOV B,R5

MOV DPH,R6;#SRCADR ;CRC INPUT PAGE ADDRESS

MOV DPL,R1

MOV RCRC2L,#0

MOV RCRC1H,#0

MOV RCRC1L,#0

CRCA:

MOVX A,@DPTR

XRL A,RCRC1H

XRL A,RCRC2L

MOV RXTEMP,A

MOV RCRC2L,RCRC1L

MOV DPTR,#CRCTAB1

MOVC A,@A DPTR

MOV RCRC1H,A

MOV A,RXTEMP

INC DPH

MOVC A,@A DPTR

MOV RCRC1L,A

MOV DPH,R6;#SRCADR ;CRC INPUT PAGE ADDRESS

INC R1

MOV DPL,R1

MOV A,R1

CJNE A,B,CRCA

MOV A,RCRC1H

XRL A,RCRC2L

CPL A

MOV RCRC1H,A

MOV A,RCRC1L

CPL A

MOV RCRC1L,A

MOV R6,RCRC1H

MOV R7,RCRC1L

RET

;-------------------------------------------

CRCTAB1:

DB 000H,089H,012H,09BH,024H,0ADH,036H,0BFH

DB 048H,0C1H,05AH,0D3H,06CH,0E5H,07EH,0F7H

DB 081H,008H,093H,01AH,0A5H,02CH,0B7H,03EH

DB 0C9H,040H,0DBH,052H,0EDH,064H,0FFH,076H

DB 002H,08BH,010H,099H,026H,0AFH,034H,0BDH

DB 04AH,0C3H,058H,0D1H,06EH,0E7H,07CH,0F5H

DB 083H,00AH,091H,018H,0A7H,02EH,0B5H,03CH

DB 0CBH,042H,0D9H,050H,0EFH,066H,0FDH,074H

DB 004H,08DH,016H,09FH,020H,0A9H,032H,0BBH

DB 04CH,0C5H,05EH,0D7H,068H,0E1H,07AH,0F3H

DB 085H,00CH,097H,01EH,0A1H,028H,0B3H,03AH

DB 0CDH,044H,0DFH,056H,0E9H,060H,0FBH,072H

DB 006H,08FH,014H,09DH,022H,0ABH,030H,0B9H

DB 04EH,0C7H,05CH,0D5H,06AH,0E3H,078H,0F1H

DB 087H,00EH,095H,01CH,0A3H,02AH,0B1H,038H

DB 0CFH,046H,0DDH,054H,0EBH,062H,0F9H,070H

DB 008H,081H,01AH,093H,02CH,0A5H,03EH,0B7H

DB 040H,0C9H,052H,0DBH,064H,0EDH,076H,0FFH

DB 089H,000H,09BH,012H,0ADH,024H,0BFH,036H

DB 0C1H,048H,0D3H,05AH,0E5H,06CH,0F7H,07EH

DB 00AH,083H,018H,091H,02EH,0A7H,03CH,0B5H

DB 042H,0CBH,050H,0D9H,066H,0EFH,074H,0FDH

DB 08BH,002H,099H,010H,0AFH,026H,0BDH,034H

DB 0C3H,04AH,0D1H,058H,0E7H,06EH,0F5H,07CH

DB 00CH,085H,01EH,097H,028H,0A1H,03AH,0B3H

DB 044H,0CDH,056H,0DFH,060H,0E9H,072H,0FBH

DB 08DH,004H,09FH,016H,0A9H,020H,0BBH,032H

DB 0C5H,04CH,0D7H,05EH,0E1H,068H,0F3H,07AH

DB 00EH,087H,01CH,095H,02AH,0A3H,038H,0B1H

DB 046H,0CFH,054H,0DDH,062H,0EBH,070H,0F9H

DB 08FH,006H,09DH,014H,0ABH,022H,0B9H,030H

DB 0C7H,04EH,0D5H,05CH,0E3H,06AH,0F1H,078H

CRCTAB2:

DB 000H,011H,023H,032H,046H,057H,065H,074H

DB 08CH,09DH,0AFH,0BEH,0CAH,0DBH,0E9H,0F8H

DB 010H,001H,033H,022H,056H,047H,075H,064H

DB 09CH,08DH,0BFH,0AEH,0DAH,0CBH,0F9H,0E8H

DB 021H,030H,002H,013H,067H,076H,044H,055H

DB 0ADH,0BCH,08EH,09FH,0EBH,0FAH,0C8H,0D9H

DB 031H,020H,012H,003H,077H,066H,054H,045H

DB 0BDH,0ACH,09EH,08FH,0FBH,0EAH,0D8H,0C9H

DB 042H,053H,061H,070H,004H,015H,027H,036H

DB 0CEH,0DFH,0EDH,0FCH,088H,099H,0ABH,0BAH

DB 052H,043H,071H,060H,014H,005H,037H,026H

DB 0DEH,0CFH,0FDH,0ECH,098H,089H,0BBH,0AAH

DB 063H,072H,040H,051H,025H,034H,006H,017H

DB 0EFH,0FEH,0CCH,0DDH,0A9H,0B8H,08AH,09BH

DB 073H,062H,050H,041H,035H,024H,016H,007H

DB 0FFH,0EEH,0DCH,0CDH,0B9H,0A8H,09AH,08BH

DB 084H,095H,0A7H,0B6H,0C2H,0D3H,0E1H,0F0H

DB 008H,019H,02BH,03AH,04EH,05FH,06DH,07CH

DB 094H,085H,0B7H,0A6H,0D2H,0C3H,0F1H,0E0H

DB 018H,009H,03BH,02AH,05EH,04FH,07DH,06CH

DB 0A5H,0B4H,086H,097H,0E3H,0F2H,0C0H,0D1H

DB 029H,038H,00AH,01BH,06FH,07EH,04CH,05DH

DB 0B5H,0A4H,096H,087H,0F3H,0E2H,0D0H,0C1H

DB 039H,028H,01AH,00BH,07FH,06EH,05CH,04DH

DB 0C6H,0D7H,0E5H,0F4H,080H,091H,0A3H,0B2H

DB 04AH,05BH,069H,078H,00CH,01DH,02FH,03EH

DB 0D6H,0C7H,0F5H,0E4H,090H,081H,0B3H,0A2H

DB 05AH,04BH,079H,068H,01CH,00DH,03FH,02EH

DB 0E7H,0F6H,0C4H,0D5H,0A1H,0B0H,082H,093H

DB 06BH,07AH,048H,059H,02DH,03CH,00EH,01FH

DB 0F7H,0E6H,0D4H,0C5H,0B1H,0A0H,092H,083H

DB 07BH,06AH,058H,049H,03DH,02CH,01EH,00FH

end

5、

uint crc(uchar * byte,uchar nbyte) //CRC校验

{

uint data itemp=0;

uchar data i,j;

bit flag;

for(i=0;i

{

itemp^=(byte[i]<<8);

for (j=0;j<8;j )

{

flag=itemp&0x8000;

itemp<<=1;

if(flag)

{

itemp^=0x1021;

}

}

}

return itemp;

}

6、

CREATCRC: ; ----- CRC-16 -----

MOV R2,#00H

MOV R3,#00H

CRCATER2: MOV A,@R0

XRL A,R3

LCALL CRCCRT1

XRL A,R2

MOV R3,A

MOV R2,B

INC R0

DJNZ R5,CRCATER2

MOV @R0,B

INC R0

MOV @R0,A

RET

CRCCRT1:

MOV R7,#08H

MOV B,#00H

CRT1LOP1: CLR C

PUSH ACC

MOV A,B

RLC A

MOV B,A

POP ACC

RLC A

JNC CRT1LOP2

PUSH ACC

MOV A,B

XRL A,#CRCGENL

MOV B,A

POP ACC

XRL A,#CRCGENH

CRT1LOP2: DJNZ R7,CRT1LOP1

RET

RECEIVE:

SETB F0

LCALL CREATCRC

MOV A,CCRC1

XRL A,@R0

JNZ ERRORCRC

INC R0

MOV A,CCRC2

XRL A,@R0

JNZ ERRORCRC

LJMP EEND

ERRORCRC: CLR F0

EEND: RET

7、

1) 求CRC码的运算采用模2运算, 所谓模2运算就是不带进位和借位, 因此加法和减法等价,实际上就是逻辑上的异或运算, 除法可以用多次模2减法实现.

2) 所谓CRC码, 就是把数据块左移16位, 然后除以0x11021所得到的余数(由CCITT推荐).

3) 据此写出以下的CRC的C程序. *ptr指向发送数据块的首地址, len是数据块以字节为单位的长度.

uint cal_crc(uchar *ptr, uchar len) {

uint crc;

uchar i;

crc=0;

while(len--!=0) {

for(i=0x80; i!=0; i/=2) {

if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;}

else crc*=2;

if((*ptr&i)!=0) crc^=0x1021;

}

ptr ;

}

return(crc);

}

8、CRC校验算法

START EQU 2000H ;数据区首址(任意设置128字节数据)。

ERR BIT 00H ;出错标志。

ORG 100H

LCALL CRCOUT ;模拟发方生成CRC校验。

LCALL CHECK ;模拟收方进行CRC校验,应该没有差错。

MOV DPTR,#START 20H ;模拟两个字节被破坏。

CLR A

MOVX @DPTR,A

INC DPTR

MOVX @DPTR,A

LCALL CHECK ;再次模拟收方进行CRC校验,应该发现差错。

STOP: LJMP STOP

NOP

NOP

NOP

CRCOUT: MOV DPTR,#START 80H ;将CRC存放单元初始化为零。

CLR A

MOVX @DPTR,A

INC DPTR

MOVX @DPTR,A

LCALL CRC ;计算CRC。

MOV DPTR,#START 80H ;将计算结果存放到数据块之后。

MOV A,R2

MOVX @DPTR,A

INC DPTR

MOV A,R3

MOVX @DPTR,A

RET

NOP

NOP

CRC: MOV DPTR,#START ;(CRC计算模块)先取两字节数据,作为

MOVX A,@DPTR ;最初的被除数。

MOV R2,A

INC DPTR

MOVX A,@DPTR

MOV R3,A

MOV R7,#80H ;以后的128字节依次作为被除数的补充。

CRC1: INC DPTR

MOVX A,@DPTR ;取一字节数据,作为被除数的补充。

MOV R4,A

MOV R5,#8 ;每字节要进行8次模2除法。

CRC2: MOV A,R4 ;三字节被除数的当前余数左移一位。

RLC A

MOV R4,A

MOV A,R3

RLC A

MOV R3,A

MOV A,R2

RLC A

MOV R2,A

JNC CRC3 ;移出的最高位是0,不用处理。

XRL A,#10H ;移出的最高位是1,进行模2处理。

MOV R2,A

MOV A,R3

XRL A,#21H

MOV R3,A

CRC3: DJNZ R5,CRC2 ;处理完一个字节。

DJNZ R7,CRC1 ;处理完全部数据。

RET ;CRC校验码在R2R3之中。

NOP

NOP

CHECK: CLR ERR ;出错标志初始化。

LCALL CRC ;计算CRC。

MOV A,R2 ;结果为零否?

ORL A,R3

JZ CHKE

SETB ERR ;结果不为零,设立出错标志。

CHKE: RET

END

9、crc16 keil

#include "verity.h"

static 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

} ;

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

static 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 nLRC(unsigned char *str,unsigned int len)

{

unsigned int tmp;

for(tmp=0;tmp

str[tmp]=str[tmp]-0x30;

return(LRC(str,len));

}

unsigned char LRC(unsigned char *uchMsg, unsigned int usDataLen)

{

unsigned char uchLRC = 0 ; /* LRC char initialized */

while (usDataLen--) /* pass through message */

uchLRC =*uchMsg ; /* buffer add buffer byte*/

/* without carry */

return((unsigned char)(-(char)(uchLRC)));

/* return twos complemen */

}

unsigned int nCRC16(unsigned char *puchMsg, unsigned int usDataLen)

{

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

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

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

}

10、crc16

#define POLY_CRC16 0xA001

static BYTE TABLE1[256]; /* crc16 values */

static BYTE TABLE2[256]; /* crc16 values */

/*

crc_init: prepare crc16 preset tables

must be called once at init

(before any crc calculation)

*/

void crc_init (void)

{

WORD mask, bit, crc, mem;

for( mask = 0; mask < 0x100; mask ) {

crc = mask;

for( bit = 0; bit < 8; bit ) {

mem = crc & 0x0001 ;

crc /= 2;

if ( mem != 0 ) crc ^= POLY_CRC16 ;

}

TABLE2[mask] = crc & 0xff;

TABLE1[mask] = crc >> 8;

}

}

/*

crc_make: calculates a crc16

size: size of the frame (including header)

buff: pointer to the first byte of the frame

(slave number)

return: CRC16 in MOTOROLA format (high byte / low byte)

*/

WORD crc_make (WORD size, BYTE *buff)

{

BYTE car, i;

BYTE crc[2];

crc[0] = 0xff;

crc[1] = 0xff;

for ( i = 0; i < size; i ) {

car = buff[i];

car ^= crc[0];

crc[0] = crc[1] ^ TABLE2[car];

crc[1] = TABLE1[car];

}

return (*(WORD*)(&crc[0]));

}

11、crc16 keil c51(铁匠)

#pragma small

#include

unsigned int CRC_16(unsigned int c,unsigned char d);

unsigned int crc16=0;

void main(void)

{

// unsigned char crcbuff[] = {31,3,0,1,0,7};

unsigned char crcbuff[] = "123456789";

unsigned char *p;

// unsigned int crc16 = 0xffff;

p=crcbuff;

while(*p !='\0')

{

crc16 = CRC_16(crc16,*p );

}

p=crcbuff;

}

unsigned int CRC_16(unsigned int c,unsigned char d)

{

unsigned int data e;

unsigned char data f;

e = c^(unsigned int)d;

for(f=0;f<8;f )

{

if(e&1)

{

e >>= 1;

e ^= 0xa001;

}

else e >>= 1;

}

return e;

}

// 使用字符串"123456789"测试,crc16初始值为0时

// 结果为0xbb3d 符合crc caculator

12、/

//网站上的算法大都是查512字节表的,对单片机来讲,太浪费空间了。

//据老古网上资料,修改并测试通过以下算法:

unsigned int crc_ta[16]={

0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,

0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,

};

unsigned int Crc16(unsigned char *ptr, unsigned char len)

{

unsigned int crc;

unsigned char da;

crc=0;

while(len--!=0)

{

da=crc>>12;

crc<<=4;

crc^=crc_ta[da^(*ptr/16)];

da=crc>>12;

crc<<=4;

crc^=crc_ta[da^(*ptr&0x0f)];

ptr++;

}

return(crc);

}

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号