打印

PIC 单片机CRC校验程序(转)

[复制链接]
4849|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
paul1983|  楼主 | 2008-12-17 22:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <P16CE625.INC>

;-------------------------------
    cblock    0x20
datBuff:8            ;assign 8 byte data buffer
bit_cnt                ;bit counting 
CRC_COUNT            ;number of bytes for CRC
CRC_RESULT            ;CRC resulr
crc_temp            ;temporary data buffer during CRC
    endc

;-------------------------------
#define    skp0    btfsc
#define    skp1    btfss


;===============================
    org    0x000

    movlw    .7
    movwf    CRC_COUNT
    movlw    datBuff
    movwf    FSR        ;FSR point to data buffer
    call    CRC_CHECK
    movwf    datBuff+7
    goto    $

;===============================
;CHECK THE CRC FOR ? BYTES DATA
;For the polynomial of X^8 + X^5 + X^4 + 1
;Derived from Dallas's iButton standard
;Before calling, FSR       = data buffer
;                CRC_COUNT = number of bytes for CRC
CRC_CHECK    ;~~~~~~~~~~~~~~~
    clrf    CRC_RESULT    ;initialize the CRC buffer
_crc_00
    movlw    .8        ;number of bits for one byte
    movwf    bit_cnt        ;set bit counter
    movf    INDF,w        ;get one data byte
    movwf    crc_temp    ;copy to temporary location
_crc_01
    rrf    crc_temp,f    ;get LSB in C
    skpc            ;is this LSB=1?
    goto    _crc_02        ;go if LSB=0
    movlw    0x01        ;do if LSB=1
    xorwf    CRC_RESULT,f
_crc_02
    rrf    CRC_RESULT,w    ;get LSB of CRC
    skpc            ;test LSB
    goto    _crc_03        ;go if LSB=0
    movlw    0x18        ;do if LSB=1
    xorwf    CRC_RESULT,f    ;polynomial implementation
_crc_03
    rrf    CRC_RESULT,w    ;whole byte right rotate
    rrf    CRC_RESULT,f
    decfsz    bit_cnt,f    ;bit counting
    goto    _crc_01        ;go on until aa 8 bits done
    incf    FSR,f        ;pointer update to next byte
    decfsz    CRC_COUNT,f    ;byte counting
    goto    _crc_00        ;go on until all byte done
    movf    CRC_RESULT,w    ;get CRC, Z set if CRC=0
    return            ;return with CRC in W

    END
沙发
paul1983|  楼主 | 2008-12-17 22:59 | 只看该作者

循环冗余校验码

循环冗余校验码(Cylclic Redundancy Check Code),简称CRC码。常用的CRC数有8,16,32,CRC位数越大,数据越不易受干扰,但运算时间加长。一般关于通信的书籍都有介绍。简单原理是将要传输的数据视为一堆连续位组成的一整个数值,并将此数值除一个特定的除数,通常以二进制表示,此除数称为衍生多项式(Generation Polynomial).
一般数据量不大时,使用Checksume验错方式就行了;数据量大时,就用CRC了;据理论统计,用CRC16时,超过17个连续位的错误侦测率为99。9969,小于此的为100。

使用特权

评论回复
板凳
paul1983|  楼主 | 2008-12-17 23:00 | 只看该作者

CRC-12 的生成多项式为

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

使用特权

评论回复
地板
paul1983|  楼主 | 2008-12-17 23:00 | 只看该作者

CRC 源码

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

使用特权

评论回复
5
paul1983|  楼主 | 2008-12-17 23:01 | 只看该作者

查表法


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

#include <stdio.h>
#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 ];
}

使用特权

评论回复
6
paul1983|  楼主 | 2008-12-17 23:02 | 只看该作者

CRC 源码

_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

使用特权

评论回复
7
paul1983|  楼主 | 2008-12-17 23:02 | 只看该作者

CRC 源码

uint crc(uchar * byte,uchar nbyte) //CRC校验
{
uint data itemp=0;
uchar data i,j;
bit flag;
for(i=0;i<nbyte;i )
{
itemp^=(byte<<8);
for (j=0;j<8;j )
{
flag=itemp&0x8000;
itemp<<=1;
if(flag)
{
itemp^=0x1021;
}
}
}
return itemp;
}

使用特权

评论回复
8
paul1983|  楼主 | 2008-12-17 23:03 | 只看该作者

CRC 源码

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

使用特权

评论回复
9
paul1983|  楼主 | 2008-12-17 23:04 | 只看该作者

CRC 源码

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

使用特权

评论回复
10
paul1983|  楼主 | 2008-12-17 23:04 | 只看该作者

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

使用特权

评论回复
11
paul1983|  楼主 | 2008-12-17 23:05 | 只看该作者

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<len;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) ;
}

使用特权

评论回复
12
paul1983|  楼主 | 2008-12-17 23:05 | 只看该作者

crc 16


#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;
car ^= crc[0];
crc[0] = crc[1] ^ TABLE2[car];
crc[1] = TABLE1[car];
}
return (*(WORD*)(&crc[0]));
}

使用特权

评论回复
13
paul1983|  楼主 | 2008-12-17 23:06 | 只看该作者

crc16 keil c51


#pragma small
#include <reg52.h>
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

使用特权

评论回复
14
paul1983|  楼主 | 2008-12-17 23:07 | 只看该作者

查表算法

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

使用特权

评论回复
15
hotpower| | 2008-12-17 23:31 | 只看该作者

网上群魔乱舞CRC/PEC在线验算器

使用特权

评论回复
16
洪七公| | 2008-12-20 21:34 | 只看该作者

PIC CRC8

;-------8位右移循环冗余码校验------------------
;
;例如:
;       CLRF    CRCOUT
;       CALL    CRCFRB
CALL_CRCFRB     MACRO CRCOUT,COUNT,VALUE,TEMP
CRCFRB
        MACRO_CRCFRB CRCOUT,COUNT,VALUE,TEMP
        RETLW   0
        ENDM
;----------------------------------------------
MACRO_CRCFRB    MACRO CRCOUT,COUNT,VALUE,TEMP
        LOCAL   CRCFRBLOOP,CRCFRBNEXT
        MOVWF   VALUE
        MOVLFB .8,COUNT
CRCFRBLOOP
        MOVF    VALUE,W
        XORWF   CRCOUT,W;异或CRC
        MOVWF   TEMP;暂存
        RRF     TEMP,W;CY
        MOVF    VALUE,W
        BTFSS   STATUS,C
        GOTO    CRCFRBNEXT
        MOVLW   18H;异或x5+x2
        XORWF   CRCOUT,F
CRCFRBNEXT
        RRF     CRCOUT,F
        BCF     STATUS,C
        BTFSC   VALUE,0
        BSF     STATUS,C
        RRF     VALUE,F
        DECFSZ  COUNT,F
        GOTO    CRCFRBLOOP
        ENDM

使用特权

评论回复
17
hotpower| | 2018-12-30 00:57 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

29

帖子

0

粉丝