2016-04-12 10 views
0

次のような単純なCRCチェックが必要です。ポートから8ビットの入力を受け取り、CRCチェックサム値を取得して出力します。今のところ、私は入力を取ることができ、アルゴリズムを読んでいるので、入力にn - 1の零点を追加して、効果的に16ビットにすることができます。私はそれもうまく働いています。分けている間にモジュロ2をするときに私はここでXORが必要であることを知っています。しかし、私はアルゴリズムでそれ以上行くことはできません、どこから始めるべきかわかりません。アセンブリAVR ATMEGA128:CRCアルゴリズム

.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 

編集:今、私は、コード10011の出力とメッセージ1100 1111のための誤った結果を得るには、1100年でなければなりませんが、私はそれが間違っている可能性1101を取得しますか?

答えて

1

あなたのコードはまだ役に立たないようです。アルゴリズムの仕組みについて考える必要があり、必要なバイトを使う良い方法を決める必要があります。

あなたの入力はストリームではなく1バイトだけなので、そのバイトで作業してシフトを8回実行することをお勧めします。私はあなたがROLを使用することをお勧めします左キャリーを介して回転し、CLC、クリアキャリービットだけでなく、XOR命令。

アイデアは、キャリーフラグをクリアし、左に1回転させることです。キャリービットがセットされている場合は、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"を行います。

+0

私はこのアルゴリズムを実装しましたが、私はあなたが持っているのと同じ出力(1100)で到着することはできません。何らかの理由で1101になる。なぜそれができますか? (自分のコードでOPを更新しました) – SenselessCoder

+0

手順5でエラーが発生したようです。ご使用のバージョンが正しい可能性があります。いくつかの例でそれを実行してみてください(そして私がやったよりも手作業で確実にやってください!) – UncleO