Короче переделал я алгоритм расчета crc из табличного в стандартный с тем же полиномом A001 ; +-------------------------------------------------------------------------+
; | подпрограмма проверки контрольной суммы CRC16 |
; | |
; |temp1,temp10 - кол-во байт для подсчета, temp8,temp6 - начальный адрес 1го байта|
; | выход: temp3 - младший байт CRC16, temp2 - старший байт CRC16 |
; +-------------------------------------------------------------------------+
checkCRC16:
ldi temp2,0xFF ;загружаем начальное значение CRC (МБ)
ldi temp3,0xFF ;загружаем начальное значение CRC (СБ)
ldi temp4,0x01 ;загружаем значение полинома
ldi temp5,0xA0
add temp6,temp1 ;прибавляем к нач.адресу кол-во байт
adc temp8,temp10
mov temp7,temp6 ;копируем результат в temp7,temp9
mov temp9,temp8
loopCalcCRC16:
mov temp6,temp7 ;копируем результат в 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 ;ксорим значение байта со значением CRC (МБ)
ldi temp6,8
loopXORbyte:
sbrc temp2,0 ;проверяем младший бит CRC (МБ)
jmp MB_CRCL_1
jmp MB_CRCL_0
MB_CRCL_1:
clc ;сдвигаем вправо весь CRC
ror temp3
ror temp2
eor temp2,temp4 ;ксорим значение CRC с полиномом
eor temp3,temp5
jmp skip_MB_CRCL_0
MB_CRCL_0:
clc ;сдвигаем вправо весь CRC
ror temp3
ror temp2
skip_MB_CRCL_0:
dec temp6
brne loopXORbyte
subi temp1,1 ;уменьшаем счетчик байт
sbci temp10,0
cpi temp1,0
brne loopCalcCRC16
cpi temp10,0
brne loopCalcCRC16 ;и проверяем достиг ли он 0
ret
Этот код полностью повторяет С# код пользователя Linore с форума http://programmers …ead.php?t=82812&page=2
Правильность посчитанной суммы проверял программкой СRC Find (Подбор полинома) неизвестного автора, там можно ввести hex-пакет длиной больше 256 и получившуюся контрольную сумму, затем эта программка просчитывает все полиномы от 0x0000 до 0xFFFF, так вот для пакета:
3E0101010B00004801005AFFFF02005FFFFF030062FFFF04004DFFFF050062FFFF06007CFFFF07006BFFFF08008AFFFF090062FFFF0A0079FFFF0B007BFFFF0C007FFFFF0D0056FFFF0E006AFFFF0F007DFFFF10007EFFFF110045FFFF120065FFFF130073FFFF14005FFFFF15005AFFFF160068FFFF170076FFFF180076FFFF190057FFFF1A006BFFFF1B0061FFFF1C0069FFFF1D0039FFFF1E0072FFFF1F0058FFFF200044FFFF210039FFFF220033FFFF230060FFFF240032FFFF25005FFFFF260048FFFF27005CFFFF280057FFFF290047FFFF2A0040FFFF2B003BFFFF2C0049FFFF2D0034FFFF2E0052FFFF2F0035FFFF300035FFFF310033FFFF320041FFFF33004EFFFF340033FFFF350025FFFF36002DFFFF370007FFFF38002FFFFF390026FFFF3A0024FFFF3B0006FFFF3C0032FFFF3D0034FFFF3E0029FFFF3F0032FFFF40003DFFFF41004CFFFF42000BFFFF43005CFFFF440036FFFF450055FFFF46002CFFFF470058FFFF480019FFFF
мой модуль выдал crc16 = 0x403F, программка CRC Find при вычислении полинома выдала что совпал полином 0xA001
Программка для работы с портами IODump, которой я пользуюсь похоже считает crc16 корректно только для пакетов длиной не больше 256 и считает она тоже с полиномом 0xA001, например для этого же пакета она считает crc16 = 0x1604 и при проверке через прогу CRC Find ни с одним полиномом не совпадает. Вот такие дела собственно.