//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收
//和查询发送,另外我觉得发送没有必要用中断,因为程序的开销是一样的
#include
<reg51.h>
#include
<string.h>
#define
INBUF_LEN
4
//数据长度
unsigned
char
inbuf1[INBUF_LEN];
unsigned
char
checksum,count3;
bit read_flag=
0
;
void
init_serialcomm(
void
)
{
SCON =
0x50
;
//SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |=
0x20
;
//TMOD: timer 1, mode 2, 8-bit reload
PCON |=
0x80
;
//SMOD=1;
TH1 =
0xF4
;
//Baud:4800 fosc=11.0592MHz
IE |=
0x90
;
//Enable Serial Interrupt
TR1 =
1
;
// timer 1 run
// TI=1;
}
//向串口发送一个字符
void
send_char_com(
unsigned
char
ch)
{
SBUF=ch;
while
(TI==
0
);
TI=
0
;
}
//向串口发送一个字符串,strlen为该字符串长度
void
send_string_com(
unsigned
char
*str,
unsigned
int
strlen)
{
unsigned
int
k=
0
;
do
{
send_char_com(*(str + k));
k++;
}
while
(k < strlen);
}
//串口接收中断函数
void
serial () interrupt
4
using
3
{
if
(RI)
{
unsigned
char
ch;
RI =
0
;
ch=SBUF;
if
(ch>
127
)
{
count3=
0
;
inbuf1[count3]=ch;
checksum= ch-
128
;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if
( (count3==(INBUF_LEN-
1
)) && (!checksum) )
{
read_flag=
1
;
//如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}
main()
{
init_serialcomm();
//初始化串口
while
(
1
)
{
if
(read_flag)
//如果取数标志已置位,就将读到的数从串口发出
{
read_flag=
0
;
//取数标志清0
send_string_com(inbuf1,INBUF_LEN);
}
}
}
//-------------------------------------------------------------------
//crc:校验子程序
//开始地址指针ADRS,需校验字节数量SUM
//校验结果:高位CRCH,低位CRCL
//-------------------------------------------------------------------
void CCRC(unsigned char *ADRS,unsigned char SUM)
{
unsigned int data CRC; //校验码
unsigned char data i;
unsigned char data j;
CRC=0xFFFF;
for (i=0;i<SUM;i++)
{
CRC^=*ADRS;
for (j=0;j<8;j++)
{
if ((CRC & 1)==1)
{
CRC>>=1;
CRC^=0xA001;
}
else
{
CRC>>=1;
}
}
ADRS++;
}
CRCH=CRC&0xFF;
CRCL=CRC>>8;
}
//-------------------------------------------------------------------
//其他程序调用例子
//校验数组前6位
//-------------------------------------------------------------------
//。。。
unsigned char data RBuf[9]; //数据区
CCRC(&RBuf,6);
//。。。
CRC差错检验法在PC 机与8031单片机串行通讯中的应用
摘 要 通过对不同校验方法的分析,介绍了一种适合PC机与8031单片 机通讯差错校验的CRC方法并给出了其实现的软件流程图。
关键词 数据传输差错校验CRC
随着数据采集系统的功能日益强大,以及微型计算机的普及,在现代工业中,利用微机进行数据通讯的工业控制应用得也越来越广泛。特别是在大规模高精度数据采集系统中,对数据进行分析和计算将占用很大一部分单片机的资源,可以将采集到的数据通过串行通讯方式传送给PC机,由PC机来完成数据的处理工作。但是由于传输距离、现场状况等诸多可能出现的因素的影响,计算机与受控设备之间的通讯数据常会发生无法预测的错误。为了防止错误所带来的影响,在数据的接收端必须进行差错校验。虽然差错校验也可以完全由硬件来承担,但由于单片机和PC都具有很强的软件编程能力,这就为实施软件的差错校验提供了前提条件,而软件的差错校验有经济实用并且不增加硬件开销的优点。本文就是基于多功能应变测试系统而编写的主机和单片机之间的RS-485通讯系统,介绍了一种软件差错校验方案循环冗余差错校验法。
1 CRC法的原理
传统的差错检验法有:奇偶校验法,校验和法,行列冗余校验法等。这些方法都是在数据后面加一定数量的冗余位同时发送出去,例如在单片机的通讯方式2和3中,TB8就可以作为奇偶校验位同数据一起发送出去,在数据的接收端通过对数据信息进行比较、判别或简单的求和运算,然后将所得和接收到的冗余位进行比较,若相等就认为数据接收正确,否则就认为数据传送过程中出现错误。但是冗余位只能反映数据行或列的奇偶情况,所以这 类检验方法对数据行或列的偶数个错误不敏感,漏判的概率很高。因此,此种方法的可靠性 就差。
循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC。它是利用除法及余数 的原理来作错误侦测(Error Detecting)的。实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CR C值不同,则说明数据通讯出现错误。由于这种方法取得校验码的方式具有很强的信息覆盖能力,所以它是一种效率极高的错误校验法。错误的概率几乎为零。在很多的仪器设备中都 采用这种冗余校验的通讯规约。
根据应用环境与习惯的不同,CRC又可分为以下几种标准:
① CRC-12码;② CRC-16码;
③ CRC-CCITT码;④ CRC-32码。
CRC-12码通常用来传送6-bit字符串。CRC-16及CRC-CCITT码则是用来传送8-b it字符,其中CRC-16为美国采用,而CRC-CCITT为欧洲国家所采用。CRC-32码大都被采用在一种称为Point-to-Point的同步传输中。
2 CRC校验码的生成过程
我们以最常用的CRC-16码作为例子进行说明。
冗余循环码包括2个字节,即16位二进制数。先预置16位寄存器全部为1,再逐 步把每8位的数据信息进行处理。在进行CRC计算时只用8位数据位,起始位和停止位,如有 奇 偶校验位的话也包括奇偶校验位,都不参与CRC计算。
在计算CRC码时,8位数据与寄存器的数据相异或,得到的数据向低位移一位,用 0填补最高位,再检查最低位。如果最低位为1,把寄存器的内容与预置数相异或;若最低位 为0,则不进行异或计算。
这个过程一直重复8次,第8次移位后,下一个8位数据再与现在寄存器中的内容 相异或,这个过程和以上一样重复8次。当所有的信息处理完后,最后寄存器中的内容即为C RC码。这个CRC码将由发送设备跟在数据的最后一起发送。
计算CRC的步骤为:
(1)预置16位寄存器位十六进制数FFFF(即全为1)。称此寄存器位CRC寄存器。
(2)把第一个8位数据与16位寄存器的低位相异或,将结果放于CRC寄存器中;
(3)把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位;
(4)如果最低位为0,重复第三步(再次移位);
如果最低位为1,CRC寄存器与多项式码进行异或;
(5)重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
(6)重复步骤2到5,进行下一个8位数据的处理;
(7)最后得到的CRC寄存器即为CRC码。
3 CRC法在收发双方的软件实现
根据前面给出的CRC码的生成过程,我们可以编制CRC校验程序,根据通讯协议通 过RS232-RS485电平转换接口和MAX485,PC机的串口与单片机的串行口进行串行异步通讯, 需要发送的数据信息位8位,选取异或多项式为A001(Hex)。
8031单片机CRC算法的程序流程图如图1所示。同时给出汇编语言的源程序。
CRC源代码:
CRCH,CRCL,CRCD分别代表CRC校验码的高8位,低8位和要处理的数据。
PC机的CRC程序思路与单片机完全相同,信息的处理、发送和接收可以用任何一种高级设计 语言来实现。
本文主要讨论了用CRC法进行差错校验的问题,接收方如果发现接收错误,则返回信息,要求主机重发数据;如果没有发现错误,则不反馈信息。由此可以提高收发效率。实践证明CRC法在PC机与8031单片机异步通讯的差错检验中应用是十分有效的,可以在实际中得到广泛应用。