[英]Assembly AVR ATMEGA128: CRC Algorithm
我必须对以下内容执行简单的CRC检查:从端口获取8位输入,获取其CRC校验和值并将其输出。 到目前为止,我可以接受输入并读取算法,因此将n-1个零附加到我的输入中,有效地使其大到足以成为16位。 我也能正常工作,我知道我需要一个XOR,因为我们在除法的同时做模2。 但是,我对算法一无所知,甚至不知道从哪里开始。
.MACRO INITSTACK
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16
.ENDMACRO
.MACRO LOADIO
LDI R20, @1
OUT @0, R20
.ENDMACRO
.include "m128def.inc"
.EQU ones = 0xFF ; output
.EQU zeros = 0x00 ; input
.EQU CRC_CODE = 0x13 ; our CRC polynomial in binary (10011)
.DEF INPUTREG = R16 ; input register
.DEF CRC_RES = R17 ; Holds the CRC result (4 bits)
.DEF OPREG1 = R18 ; temp operation register 1
.DEF OPREG2 = R19 ; temp operation register 2
.DEF OPREG3 = R20 ; temp operation register 3
.DEF OPREG4 = R21 ; temp operation register 4
.DEF OPREG5 = R22 ; temp operation register 5
.ORG 0x0000
main:
INITSTACK
; Modifies the INPUTREG
RCALL TakeInput
RCALL CreateCRC
LOADIO DDRA, ones
LOADIO DDRB, ones
OUT PORTA, CRC_RES
Stop:
NOP
JMP Stop
TakeInput:
LOADIO DDRA, zeros
IN INPUTREG, PORTA
CLR XH
MOV XL, INPUTREG
LSL XL ; do a shift 4 times, for the 4 (5 - 1) zeros
ROL XH
LSL XL ; do a shift 4 times, for the 4 (5 - 1) zeros
ROL XH
LSL XL ; do a shift 4 times, for the 4 (5 - 1) zeros
ROL XH
LSL XL ; do a shift 4 times, for the 4 (5 - 1) zeros
ROL XH
RET
CreateCRC:
LDI OPREG1, 0x08 ; do shift 8 times
LDI OPREG2, CRC_CODE ; load the polynom
LSL OPREG2 ; no need for 5th bit, we only do operation with lower 4 bits (CLC does XOR for the high bit we skipped)
SWAP OPREG2 ; Swap nibbles, so the number has the bits we want at higher 4 bits
CLZ
crc_loop:
CLC
ROL INPUTREG
DEC OPREG1
BREQ crc_end ; if we did this 8 times, stop
BRCC crc_loop ; no carry, then keep shifting, if its set we go to XOR
crc_do_xor:
EOR INPUTREG, OPREG2
JMP crc_loop
crc_end:
SWAP INPUTREG ; Swap the higher 4 bits to lower 4 bits
MOV CRC_RES, INPUTREG
RET
编辑:现在我得到错误的消息1100 1111与代码10011的结果。输出应为1100,但我得到1101。在哪里可能出错?
您的代码似乎还没有什么用。 您需要考虑算法的工作原理,并确定使用所需字节的好方法。
由于您的输入仅是一个字节而不是流,因此我建议您使用该字节并执行8次移位。 我建议您使用ROL,通过进位向左旋转,并使用CLC,清除进位,以及XOR指令。
这个想法是清除进位标志,然后向左旋转一个位置。 如果进位位已设置,则需要对00110000进行XOR指令。这是多项式,其中前1个不移到左侧。
1) 11001111 CLC and ROL
2) 10011110 with C=1, so do an XOR
10101110 CLC and ROL
3) 01011100 with C=1, so do an XOR
01101100 CLC and ROL
4) 11011000 with C=0, so don't XOR.
CLC and ROL
5) 10110000 with C=1, so do an XOR
01000000 CLC and ROL
6) 10000000 with C=0, so don't XOR.
CLC and ROL
7) 00000000 with C=1, so do an XOR
00110000 CLC and ROL
8) 01100000 with C=0, so don't XOR.
CLC and ROL
9) 11000000 The first four bits are the result. SWAP to get it to the right.
编写一个执行此算法的循环,测试C位的分支。 注意,多项式的高位不需要直接使用。 这意味着,如果设置了进位,则只能对低位进行XOR。 CLC对进位位本身执行“ XOR”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.