老帖中发现的一个crc校验,帖子说是正确的,可我感觉在第一个for循环,ac1在怎么加一,永远都是将&vb0的数据送给它啊,是我理解错误,还是程序有错误?怎么修改才好呢?
network1//网络标题
//网络注释
ldsm0.1
movb16#1,vb0
movb16#1,vb1
movb16#0,vb2
movb16#20,vb3
movb16#0,vb4
movb16#20,vb5
network2
ldm0.1
forvw10,+1,+6
network3
ldw=vw10,+1
movw16#ffff,ac0
movd&vb0,ac1
network4
ldsm0.0
xorb*ac1,ac0
network5
ldsm0.0
forvw12,+1,+8
srwac0,1
aeno
asm1.1
xorw16#a001,ac0
network6
next
network7
ldsm0.0
incdac1
network8
next
network9
ldm0.1
swapac0
aeno
movwac0,vw6
答:程序没问题,crc本身的校验机制要清楚。请参考rtu协议给的crc校验算法。
crc开始时先把寄存器的16位全部置成“1”,然后把相邻2个8位字节的数据放入当前寄存器中,只有每个字符的8位数据用作产生crc,起始位,停止位和奇偶校验位不加到crc中。产生crc期间,每8位数据与寄存器中值进行异或运算,其结果向右移一位(向lsb方向),并用“0”填入msb,检测lsb,若lsb为“1”则与预置的固定值异或,若lsb为“0”则不作异或运算。重复上述处过程,直至移位8次,完成第8次移位后,下一个8位数据,与该寄存器的当前值异或,在所有信息处理完后,寄存器中的最终值为crc值。
产生crc的过程:
1.把16位crc寄存器置成ffffh.
2.第一个8位数据与crc寄存器低8位进行异或运算,把结果放入crc寄存器。
3.crc寄存器向右移一位,msb填零,检查lsb.
4.(若lsb为0):重复3,再右移一位。
(若lsb为1):crc寄存器与aoolh进行异或运算
5.重复3和4直至完成8次移位,完成8位字节的处理。
6.重复2至5步,处理下一个8位数据,直至全部字节处理完毕。
7.crc寄存器的最终值为crc值。
8.把crc值放入信息时,高8位和低8位应分开放置。
把crc值放入信息中,发送信息中的16位crc值时,先送低8位,后送高8位。