<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0079)http://www.guangdongdz.com/special_column/techarticle/TECHDATA/dpj/200209/8.htm -->
<HTML><HEAD><TITLE>循环冗余校验码的单片机及CPLD实现 -- www.guangdongdz.com精心打造</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.3700.6699" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<STYLE type=text/css>.main {
FONT-SIZE: 12px
}
.main1 {
FONT-SIZE: 14px
}
.main2 {
FONT-SIZE: 16px
}
.main3 {
FONT-SIZE: 7px
}
.main4 {
FONT-SIZE: 10px
}
A:link {
COLOR: #0000ff; TEXT-DECORATION: none
}
A:visited {
TEXT-DECORATION: none
}
color:active:unknown {
COLOR: #ff0000; TEXT-DECORATION: none
}
A:hover {
COLOR: #aa0000; TEXT-DECORATION: underline
}
.downbor {
BORDER-BOTTOM-COLOR: #ffd0a2; BORDER-BOTTOM-STYLE: solid; BORDER-LEFT-COLOR: black; BORDER-LEFT-STYLE: solid; BORDER-RIGHT: black 0px solid; BORDER-TOP: black 0px solid
}
border-bottom-width.downbor1:unknown {
BORDER-BOTTOM: #ffffff 2px solid; BORDER-LEFT: black 0px solid; BORDER-RIGHT: black 0px solid; BORDER-TOP: black 0px solid
}
.mar {
MARGIN-TOP: 10px
}
.mar2 {
MARGIN-BOTTOM: 0px
}
</STYLE>
</HEAD>
<BODY bgColor=#ffffff leftMargin=17 oncontextmenu=self.event.returnValue=false
onkeydown="if(event.keyCode==78&&event.ctrlKey)return false;"
onselectstart="return false" topMargin=8><SPAN class=main1>
<DIV align=center>
<CENTER></CENTER></DIV>
<P align=left> </P>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=82 width=794>
<TBODY>
<TR>
<TD align=middle bgColor=#fdfef1 height=64 vAlign=top width=116>
<P align=left><FONT color=#800000><BR></FONT><SPAN
class=main1><BR><BR></SPAN><FONT color=#800000>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD><SPAN class=main1>作者:空军工程大学 来卫国 空军后勤学院 徐
冉 来源:《单片机与嵌入式系统应用》</SPAN></SPAN> </TD></TR>
<TR>
<TD>
<P align=center><SPAN class=main1><BR><B><FONT color=#0000a0 face=宋体
lang=ZH-CN><SPAN class=main1
style="FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Times New Roman; mso-hansi-font-family: Times New Roman; mso-bidi-font-family: Times New Roman; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">循环冗余校验码的单片机及CPLD实现</SPAN></FONT></B></SPAN></P><SPAN
class=main1>
<HR align=center SIZE=1 width=520>
<P class=MsoNormal><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
<B>摘要:</B></SPAN>循环冗余码校验(CRC)是一种可靠性很高的串行数据校验方法。介质循环冗余码校验的基本原理,并分别用单片机和CPLD作了循环冗余码验的软件实现和硬件实现。包括汇编语言和VHDL语言源程序。</P>
<P class=MsoNormal><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
<B>关键词:</B></SPAN>差错校验 查表法 CPLD</P>
<P style="TEXT-INDENT: 0px"><B>1 基本原理</B></P>
<P
style="TEXT-INDENT: 30px">串行数据的差错检验是保证数据正确的必要手段,通常采用奇遇校验法和循环冗余校验法。这两种方法都是通过冗余数据来提供必要信息。奇偶校验法适用于以字节为单位数据传输。例如用偶校验传送1个ASCII字符时,要附加1个校验位,从而使全部9位中“1”的个数为偶数。奇偶校验简单易行,但当数据崩溃或出现多位错误时,往往不能检验出来,因而可靠性不高。</P>
<P
style="TEXT-INDENT: 30px">循环冗余码校验法利用了循环和反馈机制,校验码由输入数据与历史数据经过较为复杂的运算而得到。因此,冗余码包含了更为丰富的数据间的信息,可靠性更高。校好的循环冗余码可校验出以下错误:①全部数据位任意奇数个位出错;②全部数据位中任意连续2位出错;③处于一个8位时间窗内的任1~8位数据出错。</P>
<P
style="TEXT-INDENT: 30px">使用循环冗余码校验方法通信时,发送方先计算待发数据的校验码,然后将数据与校验码起发出;接收方接收数据的同时进行循环冗余码的计算,并将计算结果与来自发送方的校验码相比较,如不相同表示传输过程中出现了错误,接收方必须通知发送方再次发送该组数据。</P>
<P
style="TEXT-INDENT: 30px">假设要传输64位数据(最后8位是校验码),并使用多项式x8+x5+x4+1来产生8位循环冗余校验码(以下简称CRC码)。其逻辑结构可用异或门和移位寄存器表示,如图1所示。寄存器的值即为输入数据的CRC码。首先来输入数据与最低位的异或值,如为“0”,只需将当前CRC码逻辑右移1位(首位补零),即可得到新CRC码;如为“1”,则将当前CRC码与18H异或,再循环右移1位即可。该校验码有以下特点:①当输入的8位数据(低位在前)与当前CRC码相同时,输出的CRC码将是零。因此,当包含8位CRC码的全部64位数据输入后,输出的CRC码应为零。②只要有非零位即可判决传输错误,而必复杂的校验技术。<B><BR><IMG
border=0 height=120 hspace=10
src="循环冗余校验码的单片机及CPLD实现 -- www_guangdongdz_com精心打造.files/8a.gif"
vspace=10 width=550><BR>2 用汇编语言产生循环冗长余校验码</B></P>
<P
style="TEXT-INDENT: 30px">在8051单片机上,由以下代码可得8位CRC码(存于变量CRC中),8位输入数据暂存于ACC中。</P>
<P style="TEXT-INDENT: 30px">DO_CRC:PUSH ACC ;保存输入数据</P>
<P style="TEXT-INDENT: 30px">PUSH B ;保存B寄存器</P>
<P style="TEXT-INDENT: 30px">PUSH ACC ;再次保存</P>
<P style="TEXT-INDENT: 30px">MOV B,#8 ;共有8位数据</P>
<P style="TEXT-INDENT: 30px">CRC_LOOP:XRL A,CRC</P>
<P style="TEXT-INDENT: 30px">RRC A ;将最低位与输入数据的异或值放入进位标志中</P>
<P style="TEXT-INDENT: 30px">MOV A,CRC</P>
<P style="TEXT-INDENT: 30px">JNC ZERO</P>
<P style="TEXT-INDENT: 30px">XRL A,#18H;当前CRC码与18H异或</P>
<P style="TEXT-INDENT: 30px">ZERO: RRC A ;右移1位</P>
<P style="TEXT-INDENT: 30px">MOV CRC,A ;保存新CRC码</P>
<P style="TEXT-INDENT: 30px">POP ACC</P>
<P style="TEXT-INDENT: 30px">RR A ;取出输入数据的第2位</P>
<P style="TEXT-INDENT: 30px">PUSH ACC</P>
<P style="TEXT-INDENT: 30px">DJNZ B,CRC_LOOP ;循环</P>
<P style="TEXT-INDENT: 30px">POP ACC</P>
<P style="TEXT-INDENT: 30px">POP B</P>
<P style="TEXT-INDENT: 30px">POP ACC ;恢复各寄存器</P>
<P style="TEXT-INDENT: 30px">RET</P>
<P
style="TEXT-INDENT: 30px">上述程序对每一位输入数据都要执行一系列操作,运算量很大,但内存占用少,适合于内存紧张的情况。当内存充裕时,可以使用效率更高的查表法。</P>
<P style="TEXT-INDENT: 0px"><B>3 用查表法求CRC码</B></P>
<P
style="TEXT-INDENT: 30px">将输入数据按字节分开,每字节值在0~255之间。令当前CRC码为00H,当分别输入0~255时,得到256个CRC码。将它们顺序排列就构成了循环冗余校验码表。用当前CRC码与输入字节异或后的值作为下标,查表即可求出新CRC码。下例中,crc存放CRC码,ACC存放输入字节,crc_table为循环冗余校验表的入口地址。代码如下:</P>
<P style="TEXT-INDENT: 30px">XRL A,crc ;当前CRC码与输入数据异或</P>
<P style="TEXT-INDENT: 30px">PUSH DPH</P>
<P style="TEXT-INDENT: 30px">PUSH DPL ;保存数据指针</P>
<P style="TEXT-INDENT: 30px">MOV DPTR #crc_table</P>
<P style="TEXT-INDENT: 30px">MOVC A,@A+DPTR;查表</P>
<P style="TEXT-INDENT: 30px">MOV crc,A</P>
<P style="TEXT-INDENT: 30px">POP DPL</P>
<P style="TEXT-INDENT: 30px">POP DPH ;恢复数据指针</P>
<P style="TEXT-INDENT: 30px">RET</P>
<P style="TEXT-INDENT: 30px">crc_table:</P>
<P style="TEXT-INDENT: 30px">DB 00H,5EH,BCH,E2H,61H,3FH,DDH,83H</P>
CRC.rar_crc_vhdl crc_单片机 循环码
版权申诉
125 浏览量
2022-09-22
17:36:02
上传
评论
收藏 14KB RAR 举报
局外狗
- 粉丝: 64
- 资源: 1万+