Easyelectronics.ru

Электроника для всех
Текущее время: 23 янв 2021, 00:19

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 21 ] 
Автор Сообщение
 Заголовок сообщения: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 13:53 
Только пришел

Зарегистрирован: 24 сен 2010, 18:47
Сообщения: 23
Откуда: Россия, Московская обл.
Доброго времени суток всем!
Делаю небольшой проект с использованием протокола Modbus RTU, используя контроллер ATmega16 и AVR Studio. В данный момент разбираюсь с процедурой подсчета 16 битной контрольной суммы.
В результате углубленного копания в интернетах нашел следующий код на Си:

Show код Си


Кое-как разобравшись в дебрях Сишного кода, попытался переложить данный код на ассемблерный лад.
Вот что получилось
Show код асм


Однако, данный код работает неверно. Если загрузить последовательно 0x05, 0x02, 0x12, 0x10 контрольная сумма - 0x06D9, тогда как он-лайн калькуляторhttp://www.lammertbies.nl/comm/info/crc-calculation.html выдает 0x6388
Подскажите, где ошибка в ассемблерном варианте?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 15:04 
Старожил
Аватара пользователя

Зарегистрирован: 29 май 2010, 18:46
Сообщения: 4189
Откуда: Киев
S_B писал(а):
Кое-как разобравшись в дебрях Сишного кода, попытался переложить данный код на ассемблерный лад

Тебе Си никак не подходит? Я тоже сделал девайс на Атмеге168 с таким протоколом. Заимствовал библиотеку на Си. Слегка ее подпилил - и нормально работает. Правда, когда начну на MSP430 лепить, подумываю о кардинальной переделке этой библиотеки, ибо он наворочена сильно мудрено. Хорошо, что берешь ее AS IS, но приспособить к новому процессору - боюсь, будет больше геморра, чем пользы.

А по сути вопроса - увы! Ничего не скажу. Ассемблером не пользуюсь. Да простят меня старожилы форума и лично ДХ! Ну, и пусть подсказывают ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 15:16 
Только пришел

Зарегистрирован: 24 сен 2010, 18:47
Сообщения: 23
Откуда: Россия, Московская обл.
К сожалению, я крайне плохо знаю Си. Возможно в будущем конкретно займусь изучением.
Мне хотябы понять принцип подсчета: допустим есть ячейка для старшего байта CRC - HI_CRC, для младшего - LO_CRC
Есть переменная Index - указатель на таблицу, есть Temp - Туда мы загружаем байт. Что с чем XOR и т.д., ну словом на пальцах хотябы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 16:08 
Старожил

Зарегистрирован: 22 мар 2010, 22:54
Сообщения: 3995
а гуглить вы не пробовали? http://ru.wikipedia.org/wiki/%D0%A6%D0% ... 0%BE%D0%B4

вот здесь все описано, как и что. и есть примеры кода. и там же можно заметить, что есть 2 разных стандарта црц16, один - который у вас, и второй - который в modbus;) поменяйте таблицу и все будет ок.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 17:14 
Только пришел

Зарегистрирован: 24 сен 2010, 18:47
Сообщения: 23
Откуда: Россия, Московская обл.
Простите, несовсем вас понял. Тот код что я привел на Си не подходит? Но это стандартный код и таблицы для Modbus.
Вероятнее всего я неверно перевел его в асм, о чем собственно и был вопрос.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 14 авг 2011, 23:27 
Только пришел

Зарегистрирован: 24 сен 2010, 18:47
Сообщения: 23
Откуда: Россия, Московская обл.
Вообщем решил таки эту проблему. Как я и предполагал, неправильно перевел код.
Во вложении рабочий код на ассемблере, может кому пригодится


Вложения:
CRC16_.7z [1.33 Кб]
Скачиваний: 322
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 15 авг 2011, 00:23 
Старожил

Зарегистрирован: 22 мар 2010, 22:54
Сообщения: 3995
хммм... значит я ошибся. сорри:)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 18 авг 2011, 23:56 
Старожил
Аватара пользователя

Зарегистрирован: 06 ноя 2010, 15:24
Сообщения: 711
Откуда: Украина, Николаев
А при подсчете контрольной суммы нужно учитывать стартовый импульс, стоповый,адрес?
Как правильно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 20 авг 2011, 20:16 
Заглядывает иногда

Зарегистрирован: 10 фев 2010, 00:33
Сообщения: 198
Откуда: Нижний Новгород
Хорошо, что получилось.) Тоже хотел почитать про модбас.

_________________
http://chyvack.ru/ Умные используют компьютер для экономии времени, дураки - чтобы его потратить...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 20 авг 2011, 23:55 
Только пришел

Зарегистрирован: 24 сен 2010, 18:47
Сообщения: 23
Откуда: Россия, Московская обл.
kontroller писал(а):
А при подсчете контрольной суммы нужно учитывать стартовый импульс, стоповый,адрес?
Как правильно?

Что такое стартовый/стоповый импульс?
Считается контрольная сумма всех принятых кадров посылки кроме младшего и старшего байтов CRC


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 21 авг 2011, 14:58 
Старожил

Зарегистрирован: 10 авг 2011, 19:26
Сообщения: 632
вот рабочий код без таблицы:
Код:
// CRC16 Modbus (0401000a000d=0x98dd; 0401020a11=0x50b3; 0402000a000d=0x9899;)
#define CRC16_MODBUS_INIT 0xffff
#define CRC16_MODBUS_POLY 0xa001
#define inc_crc16_modbus_upd(data, crc_prev) { \
    U8 cnt_bits, flag_xor; \
    crc_prev ^= data; \
    for (cnt_bits = 8; cnt_bits; cnt_bits--) { \
        flag_xor = crc_prev & 1; \
        crc_prev >>= 1; \
        if (flag_xor) crc_prev ^= CRC16_MODBUS_POLY; \
    } \
}
/*CRC16 Modbus*/
U16 crc16_modbus_upd(U8 data, U16 crc_prev) {
    inc_crc16_modbus_upd(data, crc_prev);
    return(crc_prev);
}

U16 crc16_modbus_buf(U8 *buf, U16 buf_size, U16 crc_prev) {
    while (buf_size) {
        crc_prev = crc16_modbus_upd(*buf, crc_prev);
        buf++;
        buf_size--;
    }
    return(crc_prev);
}




Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 01 авг 2012, 13:18 
Только пришел

Зарегистрирован: 31 июл 2012, 19:53
Сообщения: 5
S_B писал(а):
Вообщем решил таки эту проблему. Как я и предполагал, неправильно перевел код.
Во вложении рабочий код на ассемблере, может кому пригодится

В поиске объяснения особенностей CRC-16 в Modbus, обнаружил Ваш ассемблерный пример. Большое спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 19 авг 2013, 22:51 
Старожил
Аватара пользователя

Зарегистрирован: 29 май 2010, 18:46
Сообщения: 4189
Откуда: Киев
Чтобы не плодить новые темы. Эта как-то ближе всего подходит под уточнение.
S_B писал(а):
Считается контрольная сумма всех принятых кадров посылки кроме младшего и старшего байтов CRC

А что будет, если в подсчет CRC включить и саму CRC, которая находится в принятом сообщении? Не получится ли тут ноль (при отсутствии ошибок в сообщении)?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 19 авг 2013, 23:04 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1589
Откуда: Киев
Получится ноль


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 19 авг 2013, 23:57 
Старожил
Аватара пользователя

Зарегистрирован: 29 май 2010, 18:46
Сообщения: 4189
Откуда: Киев
Спасибо!
То есть, если на входе CRC имеется в конце буфера, то, указав обычной ф-ции вычисления CRC длину буфера включительно с двумя байтами CRC, мы должны на выходе получить в аккурат ноль.
Или, альтернативно, просто вычислять "честную" CRC по буферу без CRC, а потом производить сравнение двух CRC.
Кагбэ однохерственно. Верно?

При оформленни же своего буфера уже вариантов нет: функции вычисления CRC требуется чистая длина буфера. Получим "честную" CRC и припишем ее в конец.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 20 авг 2013, 16:36 
Только пришел

Зарегистрирован: 09 авг 2013, 16:33
Сообщения: 7
код для вычисления CRC16: 12 тактов AVRовского ядра на 1 байт данных.


Вложения:
Комментарий к файлу: CRC16.asm
CRC16.rar [928 байт]
Скачиваний: 274
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 16 фев 2020, 09:53 
Старожил
Аватара пользователя

Зарегистрирован: 14 фев 2012, 19:11
Сообщения: 335
Откуда: Энергодар, Нижневартовск, Екатеринбург
Ещё одна реализация CRC16 (полином 0xA001, modbus). Гораздо быстрее применяемого обычно для avr двойного цикла, но чуть медленнее табличного метода: https://godbolt.org/z/9txEB2

ATmega16 @ 16 МГц:

Данные: "123456789"
Ключ: -O1
GetCrc16Table() - 13.3 мкс
GetCrc16Simple() - 20.0 мкс
GetCrc16Cycle() - 57.5 мкс

Данные: массив, размером 256 байт
Ключ: -O1
GetCrc16Table() - 0.35 мсек
GetCrc16Simple() - 0.53 мсек
GetCrc16Cycle() - 1.6 мсек

_________________
git.io/vOZo0


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 16 фев 2020, 10:03 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
нафига всё так сложно...вот жеж

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 16 фев 2020, 14:26 
Старожил
Аватара пользователя

Зарегистрирован: 14 фев 2012, 19:11
Сообщения: 335
Откуда: Энергодар, Нижневартовск, Екатеринбург
Надо указывать тип полинома, порядок вычисления бит, начальное значение crc, а проще если, то результат работы для строки: "123456789".

Crc16 существует большое разнообразие и оптимальные алгоритмы заточены под конкретный алгоритм.

_________________
git.io/vOZo0


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 16 фев 2020, 14:32 
Старожил
Аватара пользователя

Зарегистрирован: 14 фев 2012, 19:11
Сообщения: 335
Откуда: Энергодар, Нижневартовск, Екатеринбург
Полином 0x1021, CRC-16/CCITT-FALSE: https://godbolt.org/z/ja9Lwq

4 варианта, для строки "123456789" на ATmega16 @ 16 МГц дают:

Table - 13.9 мкс (таблица 512 байт)
Optim - 22.9 мкс (без таблицы)
Simple - 24.6 мкс (без таблицы)
Cycle - 51.3 мкс (без таблицы)

_________________
git.io/vOZo0


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблема с подсчетом CRC16 для Modbus
СообщениеДобавлено: 16 фев 2020, 22:43 
Старожил
Аватара пользователя

Зарегистрирован: 14 фев 2012, 19:11
Сообщения: 335
Откуда: Энергодар, Нижневартовск, Екатеринбург
Полином 0xA001, CRC16/MODBUS:

4 варианта, для строки "123456789" на ATmega16 @ 16 МГц дают:

Table - 12.9 мкс (таблица 512 байт)
Optim - 17.3 мкс (без таблицы, avrlibc)
Simple - 20.0 мкс (без таблицы)
Cycle - 52.4 мкс (без таблицы)


Вложения:
Комментарий к файлу: Исходники
crc16-modbus.pdf [23.99 Кб]
Скачиваний: 71

_________________
git.io/vOZo0
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 21 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: ILYAUL


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB