реклама на сайте
подробности

 
 
> AVR Modbus RTU, Поможите)
vazz
сообщение Aug 2 2010, 05:12
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 189
Регистрация: 21-01-10
Пользователь №: 54 971



В общем с AVRами дружу недавно, столкнулся с острой необходимостью использования протокола Modbus RTU (т.к. оборудование уже используют на многих объектах и нужно общение приборов с новыми прошивками работающими по тому же принципу). В общем, надеюсь, найдутся добрые люди, которые смогут мне простому смертному помочь в освоении этого протокола на базе ATMega16. Собственно готовых кодов не нужно, мне б полностью принцип понять применительно к моей задаче. Я кое чего нашел от прежнего программиста, вот все что есть:

-------------------------------
Протокол передачи данных ModBus RTU.
Функция для передачи данных: 04 - «read input registers».
Запрашивать 14 регистров начиная с нулевого. Каждый регистр – двухбайтное слово. Обращаю внимание, что в протоколе ModBus все слова передаются старшим байтом вперед. Были случаи что попадалась документация с разными таблицами CRC и разными полиномами. Ниже приведу свои таблицы.
Порядок передаваемых данных:

1. Значение A
2. Значение B
3. Значение C
4. Значение D
5. Значение E
6. Значение F
7. Значение G
8. Значение H
9. Значение I
10.Значение J
11.Значение K
12.Значение L
13.Значение M
14.Значение N

Запись параметров - 16 (10 Hex) Preset Multiple Registers
Порядок передаваемых данных:

1. Значение I
2. Значение J
3. Значение K
4. Значение L
5. Значение M
6. Значение N


const unsigned char CRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};

const unsigned char CRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40};

Надеюсь на помощь!


--------------------
Не так страшна автоматизация, как её малюют.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
vazz
сообщение Apr 1 2011, 14:41
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 189
Регистрация: 21-01-10
Пользователь №: 54 971



я снова тут! вобщем делюсь своими успехами, изучил особенности модбаса касательно своей задачи основательно и вобщем сделал всем моим приборам поддержку этого протокола, всего одной функции (чтения), но больше и не надо было, зато качественно, выдают ответы как положено, в т.ч. выдают ошибки типа функция не поддерживается, ошибка поля данных и т.д. и т.п. (с модификацией старшего бита функции в случае ошибок, усё как положено). Вобщем сейчас задача встала передо мной, никак не могу сообразить как это решить. Создал я ужо почти некую систему измерения температуры с 16разрядным АЦП, ИОНом крутым, вобщем все оч качественно, с компенсацией цифровых шумов и т.д. и т.п. Так вот система эта состоит из 4 компонентов: 1. комп 2.радиомодуль с usb (к компу) 3. радиомодуль с rs485 (к измерительным блокам) 4.измерительные модули (до 256 на одной шине, подключаются к п.3), все это уже собрано и отлажено многочисленным испытаниями, как точности измерения тк и дальностью взаимодействия, осталось ток дописать под винду программулину, которая всем этим ворочает. Так вот каждый измерительный модуль имеет 72 измерительных входа для датчиков (ну и дополнительные входы для измерения напряжения на проводах компенсации, 3хпроводная схема). Каждый модуль измерительный способен хранить в своей EEPROM 1 полное измерение (с датой и временем). В этом полном измерении (т.е. измерено 72 датчика), для каждого там сохранено 4 байта информации для последующей обработки на компе. Структура записи измерения в EEPROM: [5 байт на дату и время] + [1 байт кол-ва датчиков в отчете] + [5 байт на датчик, 1 на номер датчика, 4 на результаты измерения]x72. В итоге получается массив размером 5+1+5х72 = 366 байт, плюс к этому прибавляется 4 байта служебно информации для передачи по интерфейсу. Итого: 370 байт. Моя процедура подсчета CRC16 корректно считает сумму для пакета длиной не более 256 байт. КАК ПОСЧИТАТЬ CRC16 ДЛЯ ПАКЕТА БОЛЬШЕ 256 БАЙТ? :-) извините если вопрос неуместен и глуп.. ПОМОЖИТЕ, а то кроме этого мне ничо не мешает эту систему довести до конца


--------------------
Не так страшна автоматизация, как её малюют.
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Apr 1 2011, 15:08
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(vazz @ Apr 1 2011, 17:41) *
КАК ПОСЧИТАТЬ CRC16 ДЛЯ ПАКЕТА БОЛЬШЕ 256 БАЙТ? :-)

Вероятно Вы уперлись в разрядность счетчика, который байты считает, абсолютно никаких других ограничений и придумать не получается. Выделите 2-байтовую переменную под счетчик и вперед к новым победам....
Если еще что-то смущает, то код функции подсчета crc приведите, тогда проще будет советы давать sm.gif
Go to the top of the page
 
+Quote Post
vazz
сообщение Apr 1 2011, 15:25
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 189
Регистрация: 21-01-10
Пользователь №: 54 971



Цитата(Ruslan1 @ Apr 1 2011, 19:08) *
Вероятно Вы уперлись в разрядность счетчика, который байты считает


Добрый день , Ruslan1! Вобщем считаю я по таблицам, которые приведены в начале темы, а алгоритм следующий (он слегка кривенький в плане написания, но до 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
mov temp9,temp8
loopXORbyte:
mov temp6,temp5
mov temp8,temp9
sub temp6,temp1 ;в temp6,temp8 остается адрес текущего байта принятого фрэйма
sbc temp8,temp10
mov ZH,temp8
mov ZL,temp6
ld temp6,Z ;в temp6 остается значение байта
eor temp2,temp6
mov temp4,temp2 ;получаем новое значение CRCIndex (CRCLo при этом теряется)
ldi ZH,0x02 ;выбираем старший массив
mov ZL,temp4 ;выбираем элемент массива (по CRCIndex)
lpm temp6,Z ;в temp6 получаем значение элемента массива
eor temp3,temp6 ;получаем новое значение CRCLo (CRCHi при этом теряется)
mov temp2,temp3
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

Не клюйте за ассемблер, пока до Си руки не дошли (но скоро дойдут, т.к. скоро приедтся с arm работать и 7дюймовым tft)

кстати это алгоритм считает и после 256 байт, я пробовал добавить просто 2ой байт для счетчика, но видимо шо-то не то или с таблицами такой метод не работает. Свыше 256 байт этот алгорит выдает некое значение CRC16, но оно не совпадает к примеру со значеним которое выдает программка для работы с портами при досчете для того же самого пакета

Цитата(rezident @ Apr 1 2011, 19:15) *
Но я хотел бы задать встречный вопрос: как вы посредством протокола ModBus собираетесь передавать данные больше, чем 252 байта? Стандартными командами ModBus это не получится сделать. Ведь длина пакета не может быть больше, чем 256 байт, а у вас запись 370 байт.


Извините что сразу не уточнил, я после своего поста ток понял что этот вопрос последует неминуемо) в этой системе было решено создать свой протокол "засекреченный" типа, он оч похож на модбас, но не совсем, этот протокол позволяет мне значительно сократить время общения главного с подчиненными (вдаваться в подробности думаю нет смысла, хотя если это интересно я могу и рассказать). Сейчас проблема только с подсчетом црц для пакета больше 256 длиной. Система имеет свой собственный радиоканал + локальный физ.интерфейс RS485, к которому больше никакое оборудование никогда не будет цепляться, ну есть еще кое какие маркетинговые причины почему свой протокол.


--------------------
Не так страшна автоматизация, как её малюют.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- vazz   AVR Modbus RTU   Aug 2 2010, 05:12
- - MrYuran   А вопрос-то, собственно, в чём? freemodbus.berlios...   Aug 2 2010, 05:17
- - vazz   Вопросов много.. За ссылку конечно спасибо, но вид...   Aug 2 2010, 05:47
- - MrYuran   Если тупо на пальцах именно про RTU, то основная ф...   Aug 2 2010, 06:02
- - zltigo   QUOTE (vazz @ Aug 2 2010, 08:12) В общем ...   Aug 2 2010, 06:03
|- - war4one   Почитайте это и вот это. Контрольная сумма считае...   Aug 2 2010, 06:09
|- - vazz   Цитата(war4one @ Aug 2 2010, 09:09) Почит...   Aug 2 2010, 06:43
- - MrYuran   Кодunsigned int usMBCRC16(unsigned char * pucF...   Aug 2 2010, 07:57
|- - vazz   Цитата(MrYuran @ Aug 2 2010, 10:57) Возвр...   Aug 2 2010, 08:50
|- - MrYuran   Цитата(vazz @ Aug 2 2010, 12:50) Вот спас...   Aug 2 2010, 09:13
- - vazz   попробовал я с двухбайтной посылкой на бумажке пос...   Aug 2 2010, 09:29
- - rezident   Почему никто из отвечающих не дал ссылки на текст ...   Aug 2 2010, 10:58
- - vazz   на железе сегодня полностью отладил прием 8ми байт...   Aug 5 2010, 08:40
|- - MrYuran   Цитата(vazz @ Aug 5 2010, 12:40) также сд...   Aug 5 2010, 08:51
||- - vazz   Цитата(MrYuran @ Aug 5 2010, 11:51) Это н...   Aug 5 2010, 10:14
||- - demiurg_spb   Цитата(vazz @ Aug 5 2010, 14:14) Так вот,...   Aug 13 2010, 11:49
||- - vazz   Цитата(demiurg_spb @ Aug 13 2010, 14:49) ...   Aug 17 2010, 11:54
||- - demiurg_spb   Цитата(vazz @ Aug 17 2010, 15:54) в данно...   Aug 18 2010, 08:51
|- - rezident   Цитата(vazz @ Aug 5 2010, 14:40) при скор...   Aug 5 2010, 11:09
|- - vazz   Цитата(rezident @ Aug 5 2010, 14:09) Вы у...   Aug 6 2010, 04:01
- - XVR   Цитатаbytes_qty - как я понимаю ответ прибора типа...   Aug 18 2010, 07:33
||- - rezident   Цитата(vazz @ Apr 1 2011, 21:25) Извините...   Apr 1 2011, 15:48
||- - vazz   Цитата(rezident @ Apr 1 2011, 19:48) Ну м...   Apr 1 2011, 16:38
|- - rezident   Цитата(vazz @ Apr 1 2011, 20:41) В итоге ...   Apr 1 2011, 15:15
- - rezident   Как вы можете доверять непонятно какому калькулято...   Apr 1 2011, 18:53
- - vazz   к сожалению ничего не могу найти в сети по моему в...   Apr 2 2011, 09:11
|- - rezident   Цитата(vazz @ Apr 2 2011, 15:11) мож все ...   Apr 2 2011, 11:11
|- - vazz   Цитата(rezident @ Apr 2 2011, 15:11) Прав...   Apr 2 2011, 11:26
- - vazz   Короче переделал я алгоритм расчета crc из табличн...   Apr 3 2011, 05:54
- - ukpyr   Цитатаfreemodbus.berlios.de - готовый модуль.имхо ...   Apr 3 2011, 08:19
|- - vazz   Цитата(ukpyr @ Apr 3 2011, 12:19) vazz по...   Apr 3 2011, 09:00
- - truppik   Добрый день! Думаю правильно будет спросить в ...   Aug 17 2014, 12:07
- - truppik   Немного разобрался с тем, почему при чтении выдава...   Aug 17 2014, 18:10
- - Lagman   Скорей всего это особенность вашего мастера, в про...   Aug 19 2014, 17:10


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 04:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01446 секунд с 7
ELECTRONIX ©2004-2016