繁体   English   中英

装配AVR ATMEGA128:CRC算法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM