ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
19 апреля
457413
Adept (26.10.2013 17:49 - 27.10.2013 05:42, просмотров: 24261)
чего-то никак не въеду в CRC, вроде всё понятно, но правильного значения не получается. Где ошибаюсь? CRC16 CCITT (полином 0x1021) инициализирующее значение 0xFFFF, финализирующее - нулевое тестовый ряд - стандартный 1 2 3 4 5 6 7 8 9 (т.е. 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39) должно быть значение CRC 0x29B1, получается 0xE5CC (немного переосмыслил теорию, но всё равно, один фиг - не считает правильно) Алгоритм примерно такой: Стартовое значение CRC-0xFFFF установим счётчик бит в 7 A: побайтно(на самом деле побитно) вдвигаем справа в CRC-регистр вектор данных (старшими битами вперёд) (lsl DATA; rol CRC0; rol CRC1) если выдвинутый в "carry" бит = 1, то XOR CRC регистра и полинома, если =0, ничего не делаем счётчик бит -- если счётчик бит <0 (carry), то уходим (EXIT), иначе повтопяем итерации (jmp A) EXIT: финализируем CRC регистр (дополняем вектор данных ещё двумя нулевыми байтами, считаем CRC) Ассемблерный код примерно такой: call CRC_INIT ldi TMP,'1' call CRC16_update ldi TMP,'2' call CRC16_update ldi TMP,'3' call CRC16_update ldi TMP,'4' call CRC16_update ldi TMP,'5' call CRC16_update ldi TMP,'6' call CRC16_update ldi TMP,'7' call CRC16_update ldi TMP,'8' call CRC16_update ldi TMP,'9' call CRC16_update ; call CRC16_FINALIZE ;---------------------------------------------------------------------- CRC_INIT: #define CRC16_INIT_Const 0xFFFF ldi TMP,BYTE1(CRC16_INIT_Const) sts S_CRC_byte0,TMP ldi TMP,BYTE2(CRC16_INIT_Const) sts S_CRC_byte1,TMP ret ;----------------------------------------- CRC16_FINALIZE: #define CRC16_FINALIZE_Const 0x0000 clr TMP ;дополняем обсчитываемое сообщение "нулями" в длину полинома (16 бит) call CRC16_update clr TMP call CRC16_update ; ldi TMP2,low(CRC16_FINALIZE_Const) ;XORим результат с финализируещей константой lds TMP,S_CRC_byte0 eor TMP,TMP2 sts S_CRC_byte0,TMP ldi TMP2,high(CRC16_FINALIZE_Const) lds TMP,S_CRC_byte1 eor TMP,TMP2 sts S_CRC_byte1,TMP ret ;----------------------------------------- #define CRC_polynom 0x1021 ;CRC16 - CCITT (XMODEM) ; ;Test string: '123456789' (0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039) ;Result: 0x29b1 ; ; ;TMP, TMP2, Y ;В TMP лежат исходные данные (подсчитываемый байт данных) CRC16_update: LDX CRC_polynom ;Полином для операции XOR-SHIFT lds YL,S_CRC_byte0 ;Загрузим в "Y" текущее значение байт результата CRC lds YH,S_CRC_byte1 ; ldi TMP2,7 ;В TMP2 организуем счётчик бит для операций сдвига байта исходных данных ;В TMP на данный момент лежат исходные данные (подсчитываемый байт данных) CRC_Count: lsl TMP ;Задвигаем побитно данные в CRC-регистр (Y). rol YL 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, если не все разряды исходного байта просмотрены. ; sts S_CRC_byte0,YL ;Если просмотрели все разряды исходного байта, то сохраняем результат sts S_CRC_byte1,YH ret где собака зарыта ??
...делать нужно так, как нужно. А как ненужно - делать не нужно (С) Винни-Пух :)