Как вычислять контрольную сумму - CRC8 CRC16 ?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
avr123.nm.ru
Вечно гонимый
Сообщения: 331
Зарегистрирован: Пн сен 04, 2006 20:25:28
Откуда: самоучитель по микроконтроллерам
Контактная информация:

Как вычислять контрольную сумму - CRC8 CRC16 ?

Сообщение avr123.nm.ru »

подскажите как вычислять контрольную сумму - CRC8 и CRC16 ?
Реклама
Аватара пользователя
xelos
Потрогал лапой паяльник
Сообщения: 336
Зарегистрирован: Пн мар 20, 2006 13:05:08
Контактная информация:

Сообщение xelos »

тебе полиномы или алгоритм?
Я просто верю в то, что рушить догмы - лучший способ не стареть.
Реклама
Аватара пользователя
avr123.nm.ru
Вечно гонимый
Сообщения: 331
Зарегистрирован: Пн сен 04, 2006 20:25:28
Откуда: самоучитель по микроконтроллерам
Контактная информация:

Сообщение avr123.nm.ru »

Лучшебы ближе к готовому на Си примеру.
Аватара пользователя
xelos
Потрогал лапой паяльник
Сообщения: 336
Зарегистрирован: Пн мар 20, 2006 13:05:08
Контактная информация:

Сообщение xelos »

на С# - я писал расчет СRС16 - переложить на С, проблем не должно составить.
полином не помню откуда я взял.
Вложения
crc.c
(4.02 КБ) 1893 скачивания
Я просто верю в то, что рушить догмы - лучший способ не стареть.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
avr123.nm.ru
Вечно гонимый
Сообщения: 331
Зарегистрирован: Пн сен 04, 2006 20:25:28
Откуда: самоучитель по микроконтроллерам
Контактная информация:

Сообщение avr123.nm.ru »

Спасибо.
Реклама
Аватара пользователя
avr123.nm.ru
Вечно гонимый
Сообщения: 331
Зарегистрирован: Пн сен 04, 2006 20:25:28
Откуда: самоучитель по микроконтроллерам
Контактная информация:

Сообщение avr123.nm.ru »

Вот написал CRC на Си в CVAVR и симуляция в VMLAB. Таблично и быстро.
Вложения
CRC_Tabl_Fast.rar
(23.36 КБ) 1785 скачиваний
Реклама
Аватара пользователя
romeuz
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пт июл 28, 2006 13:28:14
Откуда: Москва
Контактная информация:

Сообщение romeuz »

а кто нибудь в курсе как CRC16 делается таблично для полинома 0х8005?
Аватара пользователя
tych
Э...
Сообщения: 2792
Зарегистрирован: Ср апр 04, 2007 08:39:14
Откуда: Москва
Контактная информация:

Сообщение tych »

Вот посмотри - там и время выполнения я указал.
Вложения
CRC16 табличный atmega64.rar
(2.4 КБ) 1021 скачивание
Думайте сами, решайте сами ... а вот он-лайн перевод на корявый русский http://translate.ru
Аватара пользователя
romeuz
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пт июл 28, 2006 13:28:14
Откуда: Москва
Контактная информация:

Сообщение romeuz »

Ну вот, собственно, то что было нужно... Может кому пригодится...
Вложения
crc16_8005_ffff.asm
CRC16, табличный метод
(8.57 КБ) 907 скачиваний
Аватара пользователя
Lonleystranger
Потрогал лапой паяльник
Сообщения: 361
Зарегистрирован: Ср янв 21, 2009 00:45:33

CRC-8 tiny2313

Сообщение Lonleystranger »

Прочитав тему http://www.radiokot.ru/articles/13/ -спасибо автору
!написал интерфейсик, все работает кроме CRC...В статье указан код на MCS-51:
DO_CRC:
PUSH ACC ; сохраняем аккумулятор
PUSH B ; сохраняем регистр В
PUSH ACC ; сохраняем байт данных
MOV B, #8 ; кол-во битов (счетчик циклов)
CRC_LOOP:
XRL A, CRC ; XOR с предыдущим значением контрольной суммы
RRC A ; сдвиг вправо через флаг переноса
MOV A, CRC ; берем последнее значение CRC
JNC ZERO ; переход, если не было переноса
XRL A, #18H ; обновляем значение CRC путем XOR с константой
ZERO:
RRC A ; снова сдвигаем CRC
MOV CRC, A ; сохраняем новое значение CRC
POP ACC ; восстанавливаем байт данных
RR A ; циклически сдвигаем вправо
PUSH ACC ; снова сохраняем значение
DJNZ B, CRC_LOOP ; повторяем цикл 8 раз (для каждого бита)
POP ACC ; очищаем стек
POP B ; восстанавливаем прежние значения регистров из стека
POP ACC
RET ; завершение процедуры

Я переделал его на AVR ASM
DO_CRC:
PUSH DURATION ; сохраняем аккумулятор
PUSH TEMP2 ; сохраняем регистр В
PUSH DURATION ; сохраняем байт данных
ldi TEMP2, 8 ; кол-во битов (счетчик циклов)
CRC_LOOP:
eor TEMP, CRC ; XOR с предыдущим значением контрольной суммы
ROR TEMP ; сдвиг вправо через флаг переноса
MOV TEMP, CRC ; берем последнее значение CRC
BRCC ZERO ; переход, если не было переноса
ldi exper,0x18
eor TEMP, exper ; обновляем значение CRC путем XOR с константой
ZERO:
ROR TEMP ; снова сдвигаем CRC
MOV CRC, TEMP ; сохраняем новое значение CRC
POP DURATION ; восстанавливаем байт данных
LSR TEMP ; циклически сдвигаем вправо
PUSH DURATION ; снова сохраняем значение
dec TEMP2
brne CRC_LOOP ; повторяем цикл 8 раз (для каждого бита)
POP DURATION ; очищаем стек
POP TEMP2 ; всстанавливаем прежние значения регистров из стека
POP DURATION
RET ; завершение процедуры

Но где-то ошибка...Ввожу номер 1990 iButton'a 8-ми байтовый (с CRC включительно), а 0 не получаю...
Помогите пожалуйста-где я ошибся?
Аватара пользователя
nictrace
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вс янв 11, 2009 09:29:08
Откуда: Ярославль
Контактная информация:

Обзор нетабличных методов для CRC8

Сообщение nictrace »

Хе-хе... Кого-то энта тема интересовала и до меня ;)
Вот пример реализации CRC8 на Си из AppNotes:

Код: Выделить всё

unsigned char OWI_ComputeCRC8(unsigned char inData, unsigned char seed)
{
    unsigned char bitsLeft;
    unsigned char temp;

    for (bitsLeft = 8; bitsLeft > 0; bitsLeft--)
    {
        temp = ((seed ^ inData) & 0x01);
        if (temp == 0)
        {
            seed >>= 1;
        }
        else
        {
            seed ^= 0x18;
            seed >>= 1;
            seed |= 0x80;
        }
        inData >>= 1;
    }
    return seed;   
}

Так скажем - неплохо, но можно лучше!
А что же на ассемблере?
Вот отсюда - http://avr-asm.tripod.com/dallas1.html я извлек следующий алгоритм:

Код: Выделить всё

CRCGEN:
      PUSH   R1   
      LDI   R20,8   
      LDI   R18,0x18
      PUSH   R1   
                               
CRC_L:   lds   R3,CRC   
      EOR   R1,R3
      ROR   R1
      MOV   R1,R3
      BRCC   ZERO
      EOR   R1,R18
ZERO:   ROR   R1
      sts   CRC,R1   
      POP   R1   
      SEC      
      SBRS   R1,0   
      CLC
      ROR   R1   
      PUSH   R1     
      DEC   R20
      BRNE   CRC_L
      POP   R1   
      POP   R1   
      RET

Буэээ... Мерзость!
Самое смешное, что этот код, к тому же не без ошибок, был раскопирован во множество проектов!
На Коте вот что нашел:

Код: Выделить всё

_w1_dow_crc8:
   clr  r30
   ld   r24,y
   tst  r24
   breq __w1_dow_crc83
   ldi  r22,0x18
   ldd  r26,y+1
   clr  r27
__w1_dow_crc80:
   ldi  r25,8
   ld   r31,x+
__w1_dow_crc81:
   mov  r23,r31
   eor  r23,r30
   ror  r23
   brcc __w1_dow_crc82
   eor  r30,r22
__w1_dow_crc82:
   ror  r30
   lsr  r31
   dec  r25
   brne __w1_dow_crc81
   dec  r24
   brne __w1_dow_crc80
__w1_dow_crc83:
   adiw r28,2
   ret


Вроде, ничего, но уж больно код плохо читается! Короче, подумал и придумал собственный алгоритм:

Код: Выделить всё

crc_go2:
      ldi   mask,0x8C      ; полином
      clr   crc         ; вначале был 0

loc1:         lpm            ; data - в r0
      adiw   ZL,1         ; может быть на границе блока
      ldi   bits,8
      eor   crc,r0
loc2:         lsr   crc         ; left shift
      brcc  loc3
      eor   crc,mask
loc3:    dec   bits
      brne  loc2

      dec   buflen
      brne  loc1         ; do next byte
      ret


Как это ни странно, программа выдает те же результаты, что и предыдущие ;)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

в комплекте WinAVR имеется библиотечный модуль util/crc16.h, в котором реализованы несколько функций для подсчета CRC16 по нескольким широкораспространенным алгоритмам и полиномам, а так жже CRC8 по алгоритму/полиному
1-wire
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Сообщение asteroid7 »

Хорошие примеры на C для CRC8, 16, 32
http://ru.wikipedia.org/wiki/CRC16
Аватара пользователя
Lonleystranger
Потрогал лапой паяльник
Сообщения: 361
Зарегистрирован: Ср янв 21, 2009 00:45:33

Сообщение Lonleystranger »

Совершенно ничего не понимаю! Взял оригинальный код из crc16.h
#include <util>

// Dallas iButton test vector.
uint8_t serno[] = { 0x02, 0x1c, 0xb8, 0x01, 0, 0, 0, 0xa2 };

int
checkcrc(void)
{
uint8_t crc = 0, i;

for (i = 0; i < sizeof serno / sizeof serno[0]; i++)
crc = _crc_ibutton_update(crc, serno[i]);

return crc; // must be 0
}
main (void)
{

checkcrc();

return (0);
}

откомпилировал, залез в отладчик,
E6E0 LDI R30,0x60 Load immediate
+00000042: E0F0 LDI R31,0x00 Load immediate
+00000043: E090 LDI R25,0x00 Load immediate
+00000044: 9181 LD R24,Z+ Load indirect and postincrement
+00000045: 2798 EOR R25,R24 Exclusive OR
+00000046: E028 LDI R18,0x08 Load immediate
+00000047: E88C LDI R24,0x8C Load immediate
+00000048: FB90 BST R25,0 Bit store from register to T
+00000049: 9596 LSR R25 Logical shift right
+0000004A: F40E BRTC PC+0x02 Branch if T flag cleared
+0000004B: 2798 EOR R25,R24 Exclusive OR
+0000004C: 952A DEC R18 Decrement
+0000004D: F7D1 BRNE PC-0x05 Branch if not equal
+0000004E: E080 LDI R24,0x00 Load immediate
+0000004F: 36E8 CPI R30,0x68 Compare with immediate
+00000050: 07F8 CPC R31,R24 Compare with carry
+00000051: F791 BRNE PC-0x0D
начал отладку, да, тот код,что указан дает в регистре R25 ноль, вставляю свой в ОЗУ- не работает!
Я просто в диком архишоке!
Единственное различие - идентификатор устройства в примере 02, а у меня DS1990 т.е 01.....

код из статьи http://ru.wikipedia.org/wiki/CRC16
unsigned char Crc8(unsigned char *pcBlock, unsigned char len)
{
unsigned char crc = 0xFF;
unsigned char i;

while (len--)
{
crc ^= *pcBlock++;

for (i = 0; i < 8; i++)
crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
}

return crc;
}
Вообще выдает непонятно что...
Аватара пользователя
mr.Kirill
Мучитель микросхем
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

Lonleystranger писал(а):Совершенно ничего не понимаю!...
...
Вообще выдает непонятно что...


Прежде всего - научитесь правильно оформлять код программы, который вставляете в пост!

Чем не понравился результат кода crc8 по ссылке?
http://ru.wikipedia.org/wiki/CRC16

Сам его не раз применял, все работает как положено. В чем у Вас проблема?
Аватара пользователя
nictrace
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вс янв 11, 2009 09:29:08
Откуда: Ярославль
Контактная информация:

Сообщение nictrace »

2Lonleystranger
Во первых, вы не привели код _crc_ibutton_update()
Во вторых,компилятор посчитал вызов процедуры излишним и вставил ее в единый ряд инструкций.
8С - это полином, а 8 - разрядность байта...
Аватара пользователя
nictrace
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вс янв 11, 2009 09:29:08
Откуда: Ярославль
Контактная информация:

Re: CRC-8 tiny2313

Сообщение nictrace »

Lonleystranger писал(а):
ROR TEMP ; сдвиг вправо через флаг переноса
MOV TEMP, CRC ; берем последнее значение CRC
BRCC ZERO ; переход, если не было переноса

Но где-то ошибка...Ввожу номер 1990 iButton'a 8-ми байтовый (с CRC включительно), а 0 не получаю...
Помогите пожалуйста-где я ошибся?


А ошибка в выделенном куске. Нельзя тупо копировать код, вы же с чужого языка не дословно предложение переводите? :)))
Команда МОV обнуляет флаг С!
Возьмите мой код - чуть выше по ветке. Он значительно короче и работает! ;)
Аватара пользователя
Lonleystranger
Потрогал лапой паяльник
Сообщения: 361
Зарегистрирован: Ср янв 21, 2009 00:45:33

Сообщение Lonleystranger »

Спасибо всем за понимание и советы, в результате все-таки взял CRC16.H (спасибо ARV), откомпилировал, взял из бугера код, вставил как ASM, подредактировал немного (спасибо nictrace за дельные советы и код), вот что получилось:

Код: Выделить всё

Do_Crc:
EOR     CRC,temp          ;Exclusive OR
LDI     R18,0x08         ;Load immediate
LDI     temp,0x8C         ;Load immediate
BST     CRC,0            ;Bit store from register to T
LSR     CRC              ;Logical shift right
BRTC    PC+0x02          ;Branch if T flag cleared
EOR     CRC,temp          ;Exclusive OR
DEC     R18              ;Decrement
BRNE    PC-0x05          ;Branch if not equal
LDI     temp,0x00         ;Load immediate
ret

Все работает, УРА!А раньше скорее всего просто не учел переносов из WinASM в AVRStudio...
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Re: CRC-8 tiny2313

Сообщение smac »

nictrace писал(а):...
Команда МОV обнуляет флаг С!
...

А вот этого не надо, команда mov не воздействует на флаги результата.
Аватара пользователя
nictrace
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вс янв 11, 2009 09:29:08
Откуда: Ярославль
Контактная информация:

Сообщение nictrace »

2smac: Виноват. Не меняет... :)
А ошибка Lonleystranger была в том, что он назначил имена DURATION и TEMP разным регистрам, а нужно было - одному!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»