ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
457510 Топик полностью
Adept (27.10.2013 08:26 - 08.11.2013 23:53, просмотров: 479) ответил Adept на Поправьте, если что. Правильно ли интерпретирую сей СИ-код ???
Всё, сделал, ну как же всё, блин через жопу (в общем описании теории расчёта CRC не ни слова об особенностях реализации CCITT-варианта) ещё немного пооптимизировал :) ;CRC16 - CCITT (XMODEM) ;27/X.13 ;(C) Vladimir Kovalev ;St.Petersburg, Russia ;------------------------ ;Время исполнения менее 67 тактов (включая call/ret) ;время обсчёта тестовой ASCII строки "123456789" с побайтовой загрузкой данных в TMP-регистр - 623 такта ; ;подсчёт CRC16_CCITT отличается от теории по расчёту CRC. ; Исходные данные предварительно XORятся со старшим байтом CRC-регистра, а затем уже производятся ; операции сдвига и XOR с полиномом (деление на полином по правилам CRC-арифметики). ; В теории же (в обще описании CRC-алгоритма), данные должны просто побитно вдвигаться в CRC-регистр справа. ;Стартовое значение CRC-регистра д.б. 0xFFFF ;Операции финализации, требуемые по теории (дополнение исходного вектора данных нулями в размере полинома, ;и XOR на финальной стадии с финализирующей константой (0xFFFF) - не производятся ; ;Правила использования: ; CRC16_INIT 0xFFFF,0x1021 ;начальная инициализация CRC-регистра (запись в него 0xFFFF) ; ;и значение полинома (0x1021). ; ldi TMP,DATAbyte1 ; call CRC16_CCITT_update ; ldi TMP,DATAbyte2 ; call CRC16_CCITT_update ; . ; . ; . ; ldi TMP,DATAbyteN ; call CRC16_CCITT_update ; ;Результат забирать в регистре "Y" ;--------------------------- ;Test vector: '123456789' (0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039) ;Result: 0x29b1 ; ;'1' - c782 ;'2' - 3dba ;'3' - 5bce ;'4' - 5349 ;'5' - 4560 ;'6' - 2ef4 ;'7' - 7718 ;'8' - a12b ;'9' - 29b1 ; ;Если сообщение (например Test Vector) дополнить его CRC контрольной суммой, то посчитав CRC для всего вектора данных вместе ;со значением CRC должны получить ноль. ; т.е. CRC16_CCITT (0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39)=0x29B1 ; соответственно: CRC16_CCITT (0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x29,0xB1)=0x0000 ; ;Используемые регистры: ;TMP, TMP2, Y, X ; ;!! ВНИМАНИЕ !! ;во время всей процедурв подсчёта CRC16_CCITT регистр "Y" (регистр контрольной суммы) ;и регистр "X" (значение полинома) - не портить!! ; ;TMP - исходные данные (подсчитываемый байт данных) ;X- значение полинома ;Y - CRC-регистр - текущее и финальное значения контрольной суммы CRC16_CCITT ;----------------- .macro LDX ldi XL,low(@0) ldi XH,high(@0) .endmacro ;----------------- .macro LDY ldi YL,low(@0) ldi YH,high(@0) .endmacro ;----------------- .macro CRC16_INIT LDY @0 ;начальная инициализация CRC-регистра LDX @1 ;значение полинома .endmacro ;---------------------------------------- CRC16_CCITT_update: eor YH,TMP ;помещаем байт данных в CRC регистр (XOR байта данных со старшим байтом CRC-регистра) ldi TMP2,7 ;В TMP2 организуем счётчик бит для операций сдвига байта исходных данных ;В TMP на данный момент лежат исходные данные (подсчитываемый байт данных) CRC_Count: lsl YL ;Сдвигаем побитно данные влево в CRC-регистре (Y). rol YH brcc CRC_CheckByteEnd ;Если "выдвинутый" из CRC-регистра бит - нулевой, то проверяем, не закончился ли байт входных данных eor YL,XL ; иначе считаем, что выдвинулась "1", сл-но нужно поXORить CRC регистр с полиномом eor YH,XH ; (!! важный момент, - так как выдвинутая "1" "потерялась", но у полинома старший (17-й) бит = "1" ; то это совершенно неважно. т.к. XOR выдвинутой "1" и старшего бита полинома даст "0") CRC_CheckByteEnd: subi TMP2,1 ;Проверяем счётчик бит (сдвигов) для исходного байта данных brcc CRC_Count ; продолжаем цикл подсчёта CRC, если не все разряды исходного байта просмотрены. ; ret ;Если просмотрели все разряды исходного байта, то выходим (результат в регистре Y) ;----------------------------------------------------------------------------
...делать нужно так, как нужно. А как ненужно - делать не нужно (С) Винни-Пух :)