svin (02.04.2011 13:55, просмотров: 4389)
необходим алгоритм для подсчета crc16 для пакета длиной более 256 байт. Сам считаю табличным методом, алгоритм следующий:
; +--------------------------------------------------------------------------------+
; | подпрограмма проверки контрольной суммы CRC16 |
; | |
; |temp1,temp10 - кол-во байт для подсчета, temp8,temp6 - начальный адрес 1го байта|
; | выход: temp3 - младший байт CRC16, temp2 - старший байт CRC16 |
; +--------------------------------------------------------------------------------+
checkCRC16:
ldi temp2,0xFF ;загружаем начальное значение CRCLo
ldi temp3,0xFF ;загружаем начальное значение CRCLh
ldi temp4,0x00 ;загружаем начальное значение CRCindex
add temp6,temp1 ;прибавляем к нач.адресу кол-во байт
adc temp8,temp10
mov temp5,temp6 ;копируем результат в temp5,temp9
mov temp9,temp8
loopXORbyte:
mov temp6,temp5 ;копируем результат в temp6,temp8
mov temp8,temp9
sub temp6,temp1 ;в temp6,temp8 остается адрес текущего байта принятого фрэйма
sbc temp8,temp10
mov ZH,temp8
mov ZL,temp6
ld temp6,Z ;в temp6 остается значение байта
eor temp2,temp6 ;ксорим значение байта со значением CRCLo
mov temp4,temp2 ;получаем новое значение CRCIndex
ldi ZH,0x02 ;выбираем старший массив таблицы
mov ZL,temp4 ;выбираем элемент старшего массива таблицы по новому CRCIndex
lpm temp6,Z ;в temp6 получаем значение элемента старшего массива таблицы
eor temp3,temp6 ;ксорим значение из таблицы с CRCLh
mov temp2,temp3 ;получаем новое значение CRCLo
ldi ZH,0x01 ;выбираем младший массив таблицы
mov ZL,temp4 ;выбираем элемент младшего массива таблицы(по CRCIndex)
lpm temp3,Z ;в temp3 получаем значение элемента младшего массива (что и есть новое CRCHi)
subi temp1,1 ;уменьшаем счетчик байт
sbci temp10,0
cpi temp1,0
brne loopXORbyte
cpi temp10,0
brne loopXORbyte
ret
к сожалению ничего не могу найти в сети по моему вопросу... может опыта не хватает.. поэтому могу ток с бубном прыгать пока, и это кое что дает, но я не понял пока о чем это говорит, попробую объяснить, к примеру есть массив данных:
3E 01 01 01 0B 00 00 48 01 00 50 FF FF 02 00 65 FF FF 03 00 61 FF FF 04 00 77 FF FF 05 00 57 FF FF 06 00 6E FF FF 07 00 84 FF FF 08 00 87 FF FF 09 00 66 FF FF 0A 00 7A FF FF 0B 00 73 FF FF 0C 00 84 FF FF 0D 00 65 FF FF 0E 00 71 FF FF 0F 00 76 FF FF 10 00 84 FF FF 11 00 56 FF FF 12 00 68 FF FF 13 00 61 FF FF 14 00 6B FF FF 15 00 5D FF FF 16 00 6C FF FF 17 00 65 FF FF 18 00 78 FF FF 19 00 49 FF FF 1A 00 57 FF FF 1B 00 53 FF FF 1C 00 64 FF FF 1D 00 4F FF FF 1E 00 5C FF FF 1F 00 55 FF FF 20 00 65 FF FF 21 00 46 FF FF 22 00 45 FF FF 23 00 49 FF FF 24 00 56 FF FF 25 00 5A FF FF 26 00 50 FF FF 27 00 4D FF FF 28 00 47 FF FF 29 00 40 FF FF 2A 00 3C FF FF 2B 00 2B FF FF 2C 00 32 FF FF 2D 00 39 FF FF 2E 00 40 FF FF 2F 00 36 FF FF 30 00 40 FF FF 31 00 27 FF FF 32 00 34 FF FF 33 00 2A FF FF 34 00 3A FF FF 35 00 2A FF FF 36 00 32 FF FF 37 00 1D FF FF 38 00 1D FF FF 39 00 15 FF FF 3A 00 20 FF FF 3B 00 1B FF FF 3C 00 20 FF FF 3D 00 37 FF FF 3E 00 2D FF FF 3F 00 2D FF FF 40 00 20 FF FF 41 00 28 FF FF 42 00 1E FF FF 43 00 3C FF FF 44 00 41 FF FF 45 00 41 FF FF 46 00 34 FF FF 47 00 39 FF FF 48 00 2A FF FF
мой модуль по приведенному выше алгоритму (на асме) считает для него crc16 = F4 17. Программка для работы с портами (IODump называется) считает для этого же массива crc16 = 84 8D. Это разные результаты, НО... Если взять этот массив и в конце добавить к нему F4 17 и прогнать через программку IODump в надежде получить 00 00, то я получу результат crc16 = 63 5B. Также если взять этот массив и в конце добавить к нему 84 8D и прогнать через программку IODump в надежде получить 00 00, то я опять же получаю результат crc16 = 63 5B. И это не совпадение, можно и еще несколько разных пакетов аналогично проверить и значения будут одинаковыми. Я немного в замешательстве, мож все таки у кого нить есть правильный алгоритм вычисления, для эталона, чтоб понять как дальше жить то..)