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

 
 
> Modbus RTU подобный протокол, проблема реализации, Может есть готовый с описанием.
Alex ma
сообщение Jul 29 2007, 17:34
Сообщение #1


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

Группа: Новичок
Сообщений: 81
Регистрация: 9-08-06
Пользователь №: 19 445



Вся фишка в проблеме определения стартовой последовательности, в Modbus – это пауза 3,5 кадра вроде, другой вариант уникальная стартовая последовательность, проблема исключения стартовой последовательности в данных, для МК мне кажется проще всего отслеживать паузу чем обрабатывать массив с поиском и заменой стартовой последовательности, чтоб она не встретилась в данных. Да, но на PC таймер под Windows только 1 мс дискретность.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 28)
SasaVitebsk
сообщение Jul 29 2007, 18:18
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Alex ma @ Jul 29 2007, 20:34) *
Вся фишка в проблеме определения стартовой последовательности, в Modbus – это пауза 3,5 кадра вроде, другой вариант уникальная стартовая последовательность, проблема исключения стартовой последовательности в данных, для МК мне кажется проще всего отслеживать паузу чем обрабатывать массив с поиском и заменой стартовой последовательности, чтоб она не встретилась в данных. Да, но на PC таймер под Windows только 1 мс дискретность.


Отслеживание стартовой последовательности (начальная метка) реализуется весьма просто и используется очень широко. Например вводится метка "FF" за ней следует комманда. В потоке данных при встрече "FF" она удваивается. А на приёме, при приёме FF смотрится байт следом. Если "FF", то удаляется если нет, то принимается комманда.

Такие вещи используются при непрерывном потоке данных. В протоколе Modbus используется кадрирование. И паузы. Я бы вам рекомендовал использование пауз. Использование уникальных стартовых последовательностей - это из другой оперы. Это когда вы не можете не передовать. То есть вообще отсутствует понятие молчания в линии.

Гарантированно получить 1мс таймером под PC вам не удастся. Дискретность 1мс - это объявленная дискретность. Если использовать стандартный таймер, например из DELFI, то вам не удастся получить паузу менее 20мс. При использовании таймера типа
Код
procedure TimeProc(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD) stdcall;

я умудрился получить порядка 10мс. Меньше не пробовал - не требовалось, но со стабильностью что-то есть проблемы. Наверное точное время можно получить только в режиме ядра или в каком-нибудь монопольном режиме или приоритет как-то выставить. Здесь я плаваю.

Но вам это и не надо. Там надо чтобы пауза была "не меньше".
Go to the top of the page
 
+Quote Post
oran-be
сообщение Jul 29 2007, 19:23
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621



А разве в спецификации MODBUS RTU есть определение стартовой последовательности по детерминированному набору байт? MODBUS ASCII стартует по escape символу, а RTU - по разрыву между пакетами.
Не совсем понятен состав оборудования - где мастер, а где слэйв? Если слэйв на МК( как обычно), то выделить 3.5 байта, зарезервировав под это отдельный таймер, нетрудно, если же на РС, то между РС и MODBUS RTU проще поставить МК, поскольку у Виндозы дискретность не 1 мс, и не 10, это значение не знает никто, кроме планировщика задач, работа которого не документируется. Если Мастер на РС, то за паузами можно не следить, поскольку мастер сам их и формирует.
Go to the top of the page
 
+Quote Post
Alex ma
сообщение Jul 29 2007, 19:55
Сообщение #4


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

Группа: Новичок
Сообщений: 81
Регистрация: 9-08-06
Пользователь №: 19 445



У ведущего МК два USART один мастер второй слейв, один к PC, второй к другим МК, PC – мастер. Определение старта склоняюсь к паузе как в MODBUS RTU, использовать в чистом виде MODBUS RTU, цели нет. Сообщение: пауза, адрес, команда, данные, кс. пауза. Точно, нужно использовать паузу для разделения посылок, смущала реализация пауз на PC, но действительно не что не мешает сделать 20 – 30 мс, а между контроллерами меньше.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 29 2007, 20:10
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



При реализации RTU-ных протоколов в контроллере надо закладывать настраиваемые паузы. Особенно когда для коммуникации используется RS485.
Как минимум:
- минимальная пауза перед началом ответа,
- максимальное время отведенное для ответа.
Для RS485 еще дополнительно:
- пауза перед переключением драйвера RS485 на передачу,
- пауза перед началом передачи после переключения драйвера RS485 на передачу,
- пауза перед переключением драйвера RS485 на прием после окончания передачи.
Манипулируя этими временами, можно настроить любую связь хоть с PC, хоть с другим сегментом RS485, подключенного через один или цепочку репитеров RS485 (которые вносят задержку распространения пакета). Для связи с PC времена паузы можно удлиннить вне стандарта того же ModBus RTU, но зато на PC не нужно будет рвать ж@пу для ловли 1мс пауз и связь будет устойчивая. В то же время драйвер связи в целевом МК и для связи с PC и для межконтроллерного обмена будет использоваться один и тот же.
P.S. кстати, при выборе протокола (если конечно вы не связаны ТЗ) нужно анализировать эффективность траффика и уже в зависимости от этого выбирать между RTU-ными протоколами, ASCII-ными, протоколами использующими байт-стаффинг и т.п. Ну и немаловажное значение имеет наличие уже готовой реализации какого-либо протокола в вашей коллекции.
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 30 2007, 06:46
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Это все условно.Никто на практике паузу в 3,5 символа не анализирует. Все под контролем мастера.
Подчиненный контроллер должен сразу ответить.Согласен с rezident необходимо только правильно
организовать минимальную паузу перед началом ответа ,чтобы РС успел отреагировать на ответ и
максимальное время отведенное для ответа, чтобы долго не ожидать ответа.Обычно это около 1 сек.
Естественно минимальная пауза зависит от того какой у вас драйвер СОМ-порта в РС и времени
переключения RS-485 преобразователя.
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jul 30 2007, 07:38
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704



Один из вариантов - в приложении. Представляет собой реализацию RTU-слейва (ASCII не прописывал за отсутствием необходимости, но таковое предусмотрено. надо только добавить соответствующие проверки режима и дописать ветки в обработчиках прерываний.)
Прикрепленные файлы
Прикрепленный файл  ModBus.rar ( 6.6 килобайт ) Кол-во скачиваний: 189
 
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 30 2007, 10:58
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(upc2 @ Jul 30 2007, 09:46) *
Это все условно. Никто на практике паузу в 3,5 символа не анализирует. Все под контролем мастера.
Подчиненный контроллер должен сразу ответить.Согласен с rezident необходимо только правильно
организовать минимальную паузу перед началом ответа ,чтобы РС успел отреагировать на ответ и
максимальное время отведенное для ответа, чтобы долго не ожидать ответа.Обычно это около 1 сек.
Естественно минимальная пауза зависит от того какой у вас драйвер СОМ-порта в РС и времени
переключения RS-485 преобразователя.


Простите, а зачем вы за всех отвечаете? Я например брал и полностью реализовывал весь протокол. И все паузы выдерживал. Насколько я помню там ни одна а несколько пауз определяющих. Потом брал программу тестирующую и проверял свой протокол на работоспособность.

Кстати когда я делал, то тоже считал всё это не очень важным. Потому что пользовал 232 интерфейс. Потом когда переходил на rs485 понял зачем паузы и почему они такие. Они ведь не из головы взяты, а банально расчитаны. И я считаю что надо именно придерживаться стандарта или использовать свой протокол. Просто потому, что иначе это Modbus не назовёшь. Мастером вы можете и увеличить паузы. Например указание по 3.5символа, там "не меньше". То есть если пауза превысила данный таймаут, то пошла новая посылка, а предыдущая оборвана.

Не знаю сбрасывал ли кто. Попробую сбросить я. Прога на PC для тестирования Modbus. Возможно есть более новая версия - не знаю. Я с этим работал лет 7 назад ещё на х51. smile.gif

Да кстати ещё один момент. Если у вас один мастер на PC и несколько слэйвов на МК, то не надо транслировать. Вы можете подать паралельно на все МК. Будет меньше обработки, а ПО на МК будет однотипное. Просто разные адреса и/или команды. У меня к примеру сейчас 7 слэйвов.
Прикрепленные файлы
Прикрепленный файл  MODSCAN.ZIP ( 167.75 килобайт ) Кол-во скачиваний: 141
 
Go to the top of the page
 
+Quote Post
bodja74
сообщение Jul 30 2007, 11:35
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Делать задержки на таймере не самое лучшее решение,используйте API функцию SLEEP из KERNEL32.
Типа так обьявляем
Код
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


и пользуемся
Sleep 1
Sleep 100 и т.д.
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 30 2007, 13:06
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Цитата(SasaVitebsk @ Jul 30 2007, 13:58) *
Простите, а зачем вы за всех отвечаете? Я например брал и полностью реализовывал весь протокол. И все паузы выдерживал. Насколько я помню там ни одна а несколько пауз определяющих. Потом брал программу тестирующую и проверял свой протокол на работоспособность.

Кстати когда я делал, то тоже считал всё это не очень важным. Потому что пользовал 232 интерфейс. Потом когда переходил на rs485 понял зачем паузы и почему они такие. Они ведь не из головы взяты, а банально расчитаны. И я считаю что надо именно придерживаться стандарта или использовать свой протокол. Просто потому, что иначе это Modbus не назовёшь. Мастером вы можете и увеличить паузы. Например указание по 3.5символа, там "не меньше". То есть если пауза превысила данный таймаут, то пошла новая посылка, а предыдущая оборвана.

Не знаю сбрасывал ли кто. Попробую сбросить я. Прога на PC для тестирования Modbus. Возможно есть более новая версия - не знаю. Я с этим работал лет 7 назад ещё на х51. smile.gif

Да кстати ещё один момент. Если у вас один мастер на PC и несколько слэйвов на МК, то не надо транслировать. Вы можете подать паралельно на все МК. Будет меньше обработки, а ПО на МК будет однотипное. Просто разные адреса и/или команды. У меня к примеру сейчас 7 слэйвов.


Когда будет 2 и более мастера на шине, тогда я может-быть с вами и соглашусь.А сейчас все просто
Мастер дает запрос и ждет ответа. И RS485 здесь не причем.Не имею в виду реализацию Slave на РС.
Мой мастер прекрасно работает со стандартными датчиками и приборами ..Микрол,Элемер,Метран,
весы SBS и пр. Реализация мастера на МК проще чем на РС.
Больше хлопот доставляет Slave на микроконтроллере.Здесь есть много алгоритмов реализации.
Главное зависит от того , какую основную функцию выполняет МК. Главное не зацикливаться на Modbus.Modbus для него не главная задача.
С успехом в своих разработках применяю смешанный протокол.Посылка с начальным и завершающим
символом, а передаются байты.Все остальное от RTU .Это более скоростной протокол и проще программый код.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jul 30 2007, 13:26
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(bodja74 @ Jul 30 2007, 15:35) *
Делать задержки на таймере не самое лучшее решение,используйте API функцию SLEEP из KERNEL32.
Sleep штука очень не надежная.
Вот результаты работы Sleep на моем компе.
Измеряется реальная задержка в микросекундах.
20 замеров:
Код
Freq=3579545Hz           <--частота счетчиков ядра

Sleep results in microseconds

   Sleep( 0) Sleep( 1) Sleep( 2) Sleep( 3) Sleep(10) Sleep(16) Sleep(20)
----------------------------------------------------------------------
         5      5356     12438     12255     11406     22897     19093
       681      8942     13977      2635     12385     23951     24992
       130      4358      6315      2524      6867     17958     21907
        37      2867      7162     12062     14896     29876     28462
        56      6997       549     12618      5641     23522     16793
        59     10294     12313      8269      9699     29652     25246
       121      7651       459     14255       985     23322     24873
         5     13259     13542      7584      5488     19888     24991
       278      6649      1428      5654      1686     30749     27801
       164     14435     14506     14269     14127     27618     22679
       235      6621     12149      6513      6758     25621     16563
       139      9536     13358      2018     15205     22122     17909
        60      8184     11817     14828       721     24907     29682
       125      7033       403       151       412     18126     17158
         5      6331       865      8556      8092     28302     22481
        11      1372      3209       593      5084     26241     22725
       493     14089       737     13325     14392     19364     25576
       666     11077      4232      5808      7581     25980     15803
        97      4534       470     10276      5433     19632     20555
       147      2997      1649     15627     15497     18517     30676

заметьте, что при значениях Sleep < 16 результат
непредсказуем.(16 это такт оперционки на моем компе)
например Sleep(10) дает значения от 412 до 15497 микросекунд.
Sleep(3) дает значения от 151 до 15527 микросекунд.
Так что для задержки "не менее" 3,5 символов в модбас, Sleep явно не подходит.

Да, замечу еще, измерения проводились на "ненагруженном" компе.
Если запустить несколько жрущих ресурсы задач, то все становится еще хуже sad.gif
Go to the top of the page
 
+Quote Post
bodja74
сообщение Jul 30 2007, 16:16
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата(singlskv @ Jul 30 2007, 16:26) *
Sleep штука очень не надежная.
Вот результаты работы Sleep на моем компе.


ГЫ ,а счего вы взяли ,что сама ваша прога не делает выборки значений с переменны успехом lol.gif,или
вы думаете что Винда забьет на все дрова и ваш процесс будет пропускать вне очереди smile.gif

Если говорить из практики ,то если бы у меня был такой разброс значений ,то моя бы прога ,или страшно бы глючила или бы вообще не работала lol.gif

Ладно,вообще я другое имел ввиду smile.gif ,3.5 кадра естественно мерять Sleep нет смысла ,просто я предложил более простую реализацию задержки ,так как если делать через встроеный таймер нужно постоянно опрашивать его значение до получения необходимого результата или делать событие по его периоду и там что то решать.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jul 30 2007, 16:27
Сообщение #13


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(bodja74 @ Jul 30 2007, 20:16) *
ГЫ ,а счего вы взяли ,что сама ваша прога не делает выборки значений с переменны успехом lol.gif,или
вы думаете что Винда забьет на все дрова и ваш процесс будет пропускать вне очереди smile.gif

Если говорить из практики ,то если бы у меня был такой разброс значений ,то моя бы прога ,или страшно бы глючила или бы вообще не работала lol.gif
Ну если Вы не верите счетчикам ядра, то тады, я Вас вероятно не смогу убедить
что приведенные мной значения это правда 07.gif

погуглите по таким функциям:
QueryPerformanceFrequency
QueryPerformanceCounter

Возможно после этого Вы лучше поймете как все устроено у Windows, и поймете как
правильно измерять задержки под ней.
Go to the top of the page
 
+Quote Post
Maddy
сообщение Jul 30 2007, 17:41
Сообщение #14


Участник
*

Группа: Validating
Сообщений: 56
Регистрация: 15-10-06
Пользователь №: 21 335



Ну Sleep как-то не кошерно для _таких_ задержек пользовать ... Тогда-уж лучше в сторону multimedea timer'ов посмотреть .... там и четче можно ...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jul 30 2007, 18:01
Сообщение #15


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Maddy @ Jul 30 2007, 21:41) *
Ну Sleep как-то не кошерно для _таких_ задержек пользовать ... Тогда-уж лучше в сторону multimedea timer'ов посмотреть .... там и четче можно ...

Miltimedia Timers намного лучше чем Sleep, по крайней мере они, насколько я помню,
не дают при задержке например 3мс, задержку 150мкс smile.gif
Правда точность мультимедейных таймеров тоже не "блестящая", примерно 1-3 мс.
Так что если нужен полный контроль - PerformanceCounters,
в остальных случаях мультимедиа таймеры, а Sleep это только на на случай если
нашему процессу действительно нужно поспать по крайней мере 20 мс (максимальное время
такта операционки которое я лично встречал)
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 30 2007, 18:44
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Jul 30 2007, 21:01) *
Miltimedia Timers намного лучше чем Sleep, по крайней мере они, насколько я помню,
не дают при задержке например 3мс, задержку 150мкс smile.gif
Правда точность мультимедейных таймеров тоже не "блестящая", примерно 1-3 мс.
Так что если нужен полный контроль - PerformanceCounters,
в остальных случаях мультимедиа таймеры, а Sleep это только на на случай если
нашему процессу действительно нужно поспать по крайней мере 20 мс (максимальное время
такта операционки которое я лично встречал)



Совершенно с Вами согласен. Подписываюсь под всеми пунктами. Sleep я безусловно тоже использую. И потоки и MMTimer. Вариант процедуры его я и привёл. Но у меня поддёргивается чуть чуть. На взгляд синхронно с секундными тиками. smile.gif Думаю это тоже можно убрать, да просто нет необходимости пока.

Цитата
С успехом в своих разработках применяю смешанный протокол.Посылка с начальным и завершающим
символом, а передаются байты.Все остальное от RTU .Это более скоростной протокол и проще программый код.


Тоже так поступаю, но не называю это modbus. Ну а если делаешь modbus, то будь добр соблюдай весь протокол. Или называй его modbus- подобный протокол. smile.gif

Понятно, что если не можешь физически сделать, то что тут уже попишешь. Поэтому в мастере на PC я тоже отступаю от стандарта.


Ну а теперь я вообще не придерживаюсь modbus. Считаю его устаревшим. Мы уже здесь где-то обсуждали эти вопросы. Хочется использовать стандартный, но не перегруженный условностями протокол, взявший лучшее от modbus. Тут обсуждалась "пирамида", "wake" и др. Надо как-нибудь собраться с силами и прочитать-вникнуть. Может я стану горячим поборником. smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 30 2007, 20:15
Сообщение #17


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Alex ma @ Jul 29 2007, 20:34) *
Вся фишка в проблеме определения стартовой последовательности, в Modbus – это пауза 3,5 кадра вроде....
Да, но на PC таймер под Windows только 1 мс дискретность.

Ну не знаю как в PC (и надо ли оно вообще делать Modbus slave на PC).
На МК я поступаю так:
Приняв любой байт по УАРТу взвожу таймер, на интервал равный 4-м кадрам. И продолжаю прием.
По прерыванию таймера - взвожу флажек "Таймаут". В этом же обработчике таймера, отцепляю буфер текущего пакета, и подставляю вместо него новый.


Цитата(bodja74 @ Jul 30 2007, 14:35) *
Делать задержки на таймере не самое лучшее решение,используйте API функцию SLEEP из KERNEL32.
Типа так обьявляем

RTU-Мастер не обязан выдерживать точные паузы. Если скорость обмена некритична, то и таймером можно пользоваться, и Sleep'ом, чем угодно ;>

Самое плохое это то, что винда может втавлять непредсказуемые паузы внутри пакетов, что слейвом воспринимается однозначно - как куча битых пакетов.
Go to the top of the page
 
+Quote Post
oran-be
сообщение Jul 30 2007, 20:23
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621



Тема получения точных задержек в виндозе очень благодтная и крайне бесполезная. Даже если поднять приоритет потока до 31 все равно на маленьких задержках большой разброс будет. Причина в планировщике. Мелкософты большими красными буквами пишут - ВИНДОУЗ НЕ ОС РЕАЛЬНОГО ВРЕМЕНИ. Главное для МОДБАСА это то, что пауза между пакетами не менее, чем.
Теперь по теме.
Цитата
У ведущего МК два USART один мастер второй слейв, один к PC, второй к другим МК, PC – мастер.

Так МК реализует MODBUS? Как переходник между СОМ и MODBUS? А смысл? Мастер легко запустить и на РС, нормально будет работать, если только не понадобится суперскорость более 115200.
А если присутствие контроллера-мастера необходимо по определенным соображениям, и все слейвы тоже "свои", то может стоит использовать 9-битный формат? Никаких пауз, все очень четко и никакой головной боли.
А это как?:
Цитата
а между контроллерами меньше

Какое такое "между контроллерами"? Это же не крутой PROFIBUS!
Go to the top of the page
 
+Quote Post
bodja74
сообщение Jul 30 2007, 20:44
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата(singlskv @ Jul 30 2007, 19:27) *
Ну если Вы не верите счетчикам ядра, то тады, я Вас вероятно не смогу убедить
что приведенные мной значения это правда 07.gif

погуглите по таким функциям:
QueryPerformanceFrequency
QueryPerformanceCounter

Возможно после этого Вы лучше поймете как все устроено у Windows, и поймете как
правильно измерять задержки под ней.


Ей богу заставляете заниматься херней smile.gif

погуглил ,нашел ,и толку ?
нет конечно действительно погрешность существует,про корорую я в принципе знал ,но из 3мс на 150мкс - вы меня прям испугали smile.gif

Для чистоты эксперимента я QueryPerformanceCounter liStart и QueryPerformanceCounter liStop вложил
вовнутрь цикла.
Вот результат.
рис1 - задержка 10мс (разброс до 5)
рис2 - задержка 3мс (разброс до 1.5)
и заметьте разброс практически всегда в большую сторону ,хотя не скрою бывает хоть и редко ,но вменьшую до 10% от заданного значения ,но по крайней мере не в 20 раз меньше lol.gif

насчет мультимедийных таймеров - это хорошая мысль ,у них приоритет может быть выше ,надо будет почесать репу около них smile.gif
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 30 2007, 20:47
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



oran-be, когда вы цитируете кого-то, то указывайте автора цитаты. А то непонятно из какого сообщения и чья цитата в вашем сообщении.
Если копипастите текст, то для цитирования достаточно в открывающий тэг QUOTE дописать ник автора
QUOTE=nickname
Пример
Цитата(rezident)
Это моя цитата
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jul 30 2007, 21:04
Сообщение #21


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(bodja74 @ Jul 31 2007, 00:44) *
Ей богу заставляете заниматься херней smile.gif
Давайте не будем иронизировать пока не разобрались в вопросе smile.gif
Вот Вам код под Visual Studio(под другое сможете отрихтовать ?)
Код
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>


int _tmain(int argc, _TCHAR* argv[])
{
    LARGE_INTEGER freq,begin,end;
    __int64 b,e,f,r;
    int d[]={0,1,2,3,10,16,20};
    QueryPerformanceFrequency(&freq);
    f=(__int64)freq.QuadPart;
    printf("Freq=%u\n",f);
    printf("\nSleep results in microseconds\n\n");
    printf("   ");
    for (int i=0;i<sizeof(d)/sizeof(int);i++)
    {
        printf("Sleep(%2u) ",d[i]);
    }
    printf("\n");
    for (int i=0;i<sizeof(d)/sizeof(int);i++)
    {
        printf("----------",d[i]);
    }
    printf("\n");
    for (int j=0;j<20; j++)
    {
        for (int i=0;i<sizeof(d)/sizeof(int);i++)
        {
            QueryPerformanceCounter(&begin);
            Sleep(d[i]);
            QueryPerformanceCounter(&end);
            b=(__int64)begin.QuadPart;
            e=(__int64)end.QuadPart;
            f=(__int64)freq.QuadPart;
            r=((e-b)*10000000)/f/10;
            printf("%10u",r);
            int t=rand();
            for (int k=0;k<t;k++)
            {
                int tt=rand()/100;
                for (int kk=0;kk<tt;kk++) rand();
            }
        }
        printf("\n");
    }
    return 0;
}

Сразу же скажу, что код написан неоптимально(на коленке в N часов ночи) только для проверки.

Да, и еще, для чистоты эксперимента, вырубите все лишнее, например Qip,
дело в том что некоторые проги меняют такт операционки (Qip например), то что
они так поступают, не есть гуд, но они так поступают....
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jul 30 2007, 22:45
Сообщение #22


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Jul 31 2007, 00:15) *
Ну не знаю как в PC (и надо ли оно вообще делать Modbus slave на PC).

Вам тоже снятся такие сны ? Что Вас "заставили" сделать слейв на PC ? (шучу...)

ИМХО, слейв на PC, штука практически нереализуемая...
(в рамках стандарта, по крайней мере)
Go to the top of the page
 
+Quote Post
_Алекс
сообщение Jul 31 2007, 04:15
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377



Цитата(defunct @ Jul 30 2007, 23:15) *
На МК я поступаю так:
Приняв любой байт по УАРТу взвожу таймер, на интервал равный 4-м кадрам. И продолжаю прием.
По прерыванию таймера - взвожу флажек "Таймаут". В этом же обработчике таймера, отцепляю буфер текущего пакета, и подставляю вместо него новый.


А как вы сделали, «Приняв любой байт по УАРТу взвожу таймер», в это время по юарту идут байты, таймер тикает, и переполняется, устанавливается флаг переполнения, или вы по приему байта с юарта сбрасываете счетчик таймера?
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 31 2007, 04:49
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Цитата(SasaVitebsk @ Jul 30 2007, 21:44) *
Тоже так поступаю, но не называю это modbus. Ну а если делаешь modbus, то будь добр соблюдай весь протокол. Или называй его modbus- подобный протокол. smile.gif

Понятно, что если не можешь физически сделать, то что тут уже попишешь. Поэтому в мастере на PC я тоже отступаю от стандарта.
Ну а теперь я вообще не придерживаюсь modbus. Считаю его устаревшим. Мы уже здесь где-то обсуждали эти вопросы. Хочется использовать стандартный, но не перегруженный условностями протокол, взявший лучшее от modbus. Тут обсуждалась "пирамида", "wake" и др. Надо как-нибудь собраться с силами и прочитать-вникнуть. Может я стану горячим поборником. smile.gif


Ну, там где надо, я протокол не нарушаю Мне тоже не нравится Modbus, но многие фирмы реализуют
его в своей продукции и тут ничего не поделаешь.Конечно, если готовишь продукцию для рынка,
то надо более четко реализовать протокол.


Цитата(_Алекс @ Jul 31 2007, 07:15) *
А как вы сделали, «Приняв любой байт по УАРТу взвожу таймер», в это время по юарту идут байты, таймер тикает, и переполняется, устанавливается флаг переполнения, или вы по приему байта с юарта сбрасываете счетчик таймера?


Спецификация Modbus RTU предписывает непрерывный поток данных.Поэтому по каждому символу
необходимо сбрасывать (устанавливать) таймер настроенный на интервал равный 3,5 символам.Когда символы кончатся , сработает таймер.По срабатыванию таймера можно считать, что пакет пришел. Есть
и другие методы приема.
Go to the top of the page
 
+Quote Post
oran-be
сообщение Jul 31 2007, 04:55
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621



Цитата(rezident)
когда вы цитируете кого-то, то указывайте автора цитаты

Остается поблагодарить за раскрытие секретов мастерства.
Цитата(defunct)
Самое плохое это то, что винда может втавлять непредсказуемые паузы внутри пакетов

Если пакет достаточно длинный. В современных РС СОМ обычно интегрирован в чипсет и поэтому может отличатся от стандартного. Глубина ФИФО, как я ка то обнаружил экспериментальным путем, не соответствует стандартным 16 байтам, а обычно имеет совершенно левое значение. Чтобы узнать глубину фифо, надо соединить на COM'e RX и TX и сначала записать в него чего-нибудь большое, а потом считать. Считается столько, сколько осталось в ФИФО. Я прпробовал на двум мамках - на одной оказался 91 байт, на другой - 173. Если длина пакета менее длины ФИФО, паузы не будет.
А если не привязываться к ФИФО, то минимизировать вероятность появления пауз можно только путе повышения приоритета и соответствующей настройки СОМа.

Движок для слейва на МК под РС485 с использованием пауз для определения старта пакета может выглядеть следующим образом:
Используется аппаратный таймер и УАРТ.
Флаг переполнения таймера используется как признак адреса. При инициализации сбрасывается.
Время на таймере устанавливается при инициализации и при приеме любого байта равным требуемый интервал + время приема 1 байта.
Обработчик прерывания по УАРТ, после взвода таймера, анализирует флаг переполнения таймера и, если он установлен, то он сбрасывается и происходит анализ принятого значения. Если оно совпадает с заданным адресом, то обработчик переходит в режим приема пакета. Если адрес не совпадает, то обработчик переходит в режим отвергания пакета.
Если при приеме байта флаг таймера сброшен, то обработчик проверяет режим работы и либо принимает пакет, либо вываливается.

Сообщение отредактировал oran-be - Jul 31 2007, 05:27
Go to the top of the page
 
+Quote Post
_Алекс
сообщение Jul 31 2007, 05:46
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377



МК Slave:
Скажем есть функция обработки принятого пакета, запускается по таймауту таймера, рассчитываем КС, проверяем адрес, выбираем команду, в итоге код команды получен, как лучше дальше реализовать ветвление по командам, if, switch, т.е. перейти к обработке полученной команды. Сформировать пакет с ответом
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jul 31 2007, 06:53
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704



Цитата(defunct @ Jul 30 2007, 23:15) *
Ну не знаю как в PC (и надо ли оно вообще делать Modbus slave на PC).


Порой приходится делать...
Делал девайс, который работал под управлением процессорной платы ICOP (одноплатный 386-й)
Так вот задачей было сгородить на нем Слейв Модбаса для связи со СКАДой.
Плата работает под ДОС-ом, поэтому сказанное ниже некоторый оффтоп, но может кому пригодится идея...

Основной проблемой было отловить 3.5-кратный интервал тишины на линии...
Игра с таймером требуемого результата не принесла...
Внимательно изучив описание стандартного УАРТа заметил (smile.gif) очень "полезное" прерывание - по таймауту (4-х кратному интервалу передачи символа).
Ну а дальше - дело техники...
1) Настраиваем ФИФО например на 16 символов.
2) Если возникает прерывание заполнения ФИФО (не таймаут) - вычитываем 16 байт в буфер и продолжаем ожидать "доприема" пакета.
3) Если возникает прерывание по таймауту - вычитываем байты из ФИФО и считаем, что пакет принят, переходим к его анализу.

Естественно, это все не в основном цикле крутится - за все действия отвечают обработчики прерываний от СОМ-порта, выставляющие флаги, анализируемые основной программой.
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 31 2007, 09:53
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



To _Алекс

Прикрепил документ, где хорощо распиcаны алгоритмы приема.И то,кто как делает простенький рабочий примерчик свободно распространяемый поляком.Компилятор CCS.
Прикрепленные файлы
Прикрепленный файл  Modbus_Application_Protocol_V1_1b.pdf ( 320.73 килобайт ) Кол-во скачиваний: 282
Прикрепленный файл  PIC.ZIP ( 4.96 килобайт ) Кол-во скачиваний: 92
 
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 31 2007, 10:15
Сообщение #29


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(_Алекс @ Jul 31 2007, 07:15) *
или вы по приему байта с юарта сбрасываете счетчик таймера?

Именно так. Только не сбрасываю, а запускаю заново (если таймер был запущен, то он будет перезапущен).

Этот код у меня в конце обработчика прерывания RX:

Код
// initialize timeout timer
TCCR2 = 0; // stop mb timeout timer
TCNT2 = 0; // reset timeout timer
TIMSK |= (1 << OCIE2);
OCR2 = QuadCharInterval;  // <-- вычисляется при инициализации UART'a
TCCR2 = (1 << WGM21)|(1 << CS22)|(1 << CS20); // set prescaler to 1024 and run timer


Цитата(oran-be @ Jul 31 2007, 07:55) *
Я прпробовал на двум мамках - на одной оказался 91 байт, на другой - 173. Если длина пакета менее длины ФИФО, паузы не будет.

Вот оно оказывается что...
Спасибо за информацию!

Цитата(ALexx @ Jul 31 2007, 09:53) *
Порой приходится делать...
Делал девайс, который работал под управлением процессорной платы ICOP (одноплатный 386-й)
Так вот задачей было сгородить на нем Слейв Модбаса для связи со СКАДой.
Плата работает под ДОС-ом, поэтому сказанное ниже некоторый оффтоп, но может кому пригодится идея...

Знаю эти платы, на M6117. Неплохой вариант для быстрых решений если под рукой нет более подходящего железа.. Пока девайс на M6117 проходит стадию показухи, есть время чтобы сделать более подходящий девайс. Ну а по поводу программирования MB слейва под DOS, дык сложностей никаких не вижу, однозадачка как никак, настроил таймер на частоту кратную символам UART'a и все под контролем.

В серийке M6117 чрезмерно дорого получается, особенно если брать готовые платы. Девайс на базе AVR'ки (напр m128) по возможностям (производительности) будет то же самое, по надежности и потреблению - лучше, плюс быстрее стартует (перестартует), и дешевле в разы.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 00:00
Рейтинг@Mail.ru


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