Area : Встроенные системы Date : Wed Feb 10, 14:19 From : Alexander Trush 2:5020/392.40 To : akulin@srdlan.npi.msu.su Subj : microcontroller CRC16 ──────────────────────────────────────────────────────────────────────────────── Привет akulin@srdlan.npi.msu.su! 08 Feb 99 21:49, akulin@srdlan.npi.msu.su wrote to All: a> Заметив сильный интерес к алгоритмам вычисления проверочных кодов, a> предлагаю народу посмотреть на следующий код вычисления CRC. a> Hа каждый байт массива тратится 4 строки на языке Си, или, IMHO, около a> 15 строк ассемблера. a> ;TITLE CRC "Count the CRC of the byte array" a> ;Project: a> ; MCP protocol a> ;Module: a> ; CRC.C a> ;Author: a> ; Alex Akulin, 21.05.97 a> ;History: a> ; 19.06.97 - AIA, optimized for 8-bit microcontrollers. a> ; Use the global vars to store CRC. a> ; a> */ Посмотрим на досуге ваш вариант... У меня тоже как-то возникла потребность в быстром вычислении CRC16, но вот табличный способ требовал 512 байт под таблицу, а их то как раз было жалко. Рассматривая таблицу я обнаружил что её можно привести к формальному описанию без цикла: crctab=(x=i^(i>>4), ((x<<12)^(x<<5)^x), где i - индекс, x - рабочая переменная. После этого написание функции вычисления CRC16 было дело техники. Всё это "безобразие" открылось для меня в Мае-Июне 1998. Год спустя значит от вашей реализации. Правда требовалась реализация под AVR, что и было получено после небольшой параидальной оптимизации табличного алгоритма. Hа суд общественности выставлю две подпрограммы: 1-ая используется мною для передачи данных с помощью протокола XMODEM, а вторая для проверки целостности FLASH при каждом влючении. Пользуйтесь на здоровье, не забывая меня упомянуть по возможности. Кстати ровно 15 команд и выходит... >=== Cut === ;*************************************************************************** ; (c) 1998 Alexander Trush Http://trush.da.ru 2:5020/392.40 ; ; Function UpdateCRC for computing CRC16 (poly 0x1021) .DEF HL_5 = r14 .DEF HH_5 = r16 ; High Only .DEF H_1 = r15 .DEF H_12 = r17 ; High Only UpdateCRC: lds H_12, CRC_H mov H_1, H_12 swap H_12 mov HH_5, H_12 eor H_12, H_1 andi H_12, 0xF0 andi HH_5, 0x0F eor H_1, HH_5 mov HL_5, H_12 lsl HL_5 rol HH_5 eor H_1, HL_5 eor H_12, HH_5 lds HL_5, CRC_L eor H_1, ZH eor H_12, HL_5 sts CRC_L, H_1 sts CRC_H, H_12 ret ;***************************************************************************** >=== Cut === >=== Cut === ; **************************************************************************** ; CHecking of FLASH contents by CRC16 (poly 0x1021) ; ; (c) 1998 Alexander Trush Http://trush.da.ru 2:5020/392.40 ; CRC_H: .BYTE 1 ; CRC accum CRC_L: .BYTE 1 .DEF HL_5 = r1 .DEF HH_5 = r16 ; High Only .DEF H_1 = r2 .DEF H_12 = r17 ; High Only TestFlasHContents: clr H_12 ; CRC_H, CRC_L = 0 clr R0 clr ZL ; From 0x000 address clr ZH TFC_UpdateCRC: mov H_1, H_12 swap H_12 mov HH_5, H_12 eor H_12, H_1 andi H_12, 0xF0 andi HH_5, 0x0F eor H_1, HH_5 mov HL_5, H_12 lsl HL_5 rol HH_5 eor H_1, HL_5 eor H_12, HH_5 eor H_12, R0 lpm ; Next byte... eor R0, H_1 adiw ZL, 1 cpi ZL, Low(EndOfProgram*2) brne TFC_UpdateCRC cpi ZH, HigH(EndOfProgram*2) brne TFC_UpdateCRC or R0, H_12 ret .DW 0x0 ; CRC16 of block 0x000...[EndOfProgram] EndOfProgram: .EXIT ;*************************************************************************** >=== Cut === Творческих успехов! Bye-bye. --- * Origin: trush@ropnet.ru ICQ:7865704 http://trush.da.ru (2:5020/392.40)