文档库 最新最全的文档下载
当前位置:文档库 › C51的CRC校验程序(Keil C51)

C51的CRC校验程序(Keil C51)

/*************************************************

CRC校验程序 Keil-C51
=====================
CPU : AT89C51
crystal : 11.0592MHz/12MHz /24MHz
date : 2013.03.06
design : Shi Jian Min
version : 1.0.0

Modify : 2013.03.06 V1.0.0

Modifier : Shi Jian Min

输入:字节数组
输出:CRC校验
校验多项式:0xA001
**************************************************/

#include

#define SendDataBuf DBYTE[214] //数据缓冲区地址(使用高128byteRAM段)

/************************************
CRC计算
输入:1个字节(8bit)赋给16bit的 Data
输出:CRC结果,word(int)(16bit) CrcData

*********************************/
unsigned int CrcCal(unsigned int Data, unsigned int CrcData)
{
unsigned char data i;

Data *= 2;
for(i = 8;i > 0;i--) //1个字节移位运算8次
{
Data = Data / 2;
if((Data ^ CrcData) & 1)
{
CrcData = (CrcData / 2) ^ 0xa001; //多项式代码:0xa001
}
else CrcData /= 2; //等同:CrcData >>= 1 ; //右移1位
}
return (CrcData); //返回CRC计算结果
} // CrcCal(unsigned int Data, unsigned int CrcData)

/*********************************
CRC测试
计算缓冲区中数据的CRC值,
通过模拟调试(单步跟踪)可以查看CRC的结果

**********************************/
void Test_CRC(void)
{
unsigned int CRC;
unsigned char i;

char Buf[]={1,3,0,0,0,1}; //6个字节的CRC = 0x0a84
char Buf1[]={1,3,0,0,0,1,0x84,0x0a}; //8个字节的CRC = 0x0000

CRC = 0xffff;
for(i = 0;i < 6;i++) //Buf做6次循环计算
{
CRC = CrcCal(Buf[i],CRC); //改过的调用方式,将0xa001固定在子程序中
}

//计算Buf1中的8个字节CRC=0x0000,想想看Buf与Buf1的数据,为什么?
CRC = 0xffff;
for(i = 0;i < 8;i++) //Buf1做8次循环计算
{
CRC = CrcCal(Buf1[i],CRC); //改过的调用方式,将0xa001固定在子程序中
}
} //Test_CRC(void)

/*************************************************
(准备数据)
数据放在缓冲区中,计算缓冲区中所有数据的CRC结果,
并将结果放在缓冲区后面。
(计算好数据后就可以通过串口等将数据发送出去)
***************************************************/
void ReadyRTU_Data(void)
{
unsigned int CRC;
unsigned char data *p;
unsigned char data i;

p = &SendDataBuf; //准备数据:1,2,3,4,5,6,7
*p++ = 0x01;
*p++ = 0x02;
*p++ = 0x03;
*p++ = 0x04;
*p++ = 0x05;
*p++ = 0x06;
*p++ = 0x07;
p = &SendDataBuf; //开始计算CRC
CRC = 0xffff;
for(i = 0;i < 7; i++)
{
CRC = CrcCal((*p),CRC);
p++;
}
*p++ = CRC; //CrcL 将结果放到缓冲区中低字节在前,高字节在后。
*p = CRC / 256; // CrcH
}//准备RTU数据


main (void) // main program
{
Test_CRC(); //测试CRC计算
ReadyRTU_Data(); //准备通

信数据
while (1) ;
} // main()


相关文档