_Pasha 0 15 января, 2010 Опубликовано 15 января, 2010 · Жалоба А кто как борется с коллизиями? RXE всегда включен - это ясно. При отправке байта пишем его в переменную типа: volatile uint8_t RS485_last_sent; //............................................... UDR = RS485_last_sent = *rx_ptr++; Прерывание от RX не выключается никогда. Но можно нарваться на момент, когда прерывание RX не успело подхватить RS485_last_sent и сравнить его. Поскольку UDR буферизирован, прочтем старое принятое значение - и кирдык. Ложная реакция обеспечена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 15 января, 2010 Опубликовано 15 января, 2010 · Жалоба А кто как борется с коллизиями?Если один мастер и "Команда мастера - ответ слэйва", то и бороться не нужно. А, другого - и не использую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 8 15 января, 2010 Опубликовано 15 января, 2010 · Жалоба А кто как борется с коллизиями? Если имеется в виду исключение одновременного выхода на линию нескольких мастеров, то 1. Все слушают всех и не выходят в передачу, когда линия занята 2. После освобождения линии у каждого девайса СВОЙ таймаут выхода в передачу (с повторной проверкой свободности линии) 3. Для большей надежности можно завести прерывание по старт-биту (на переход в 0 сигнала на линии), по нему - таймаут на передачу байта-полутора, и если в заданный промежуток перепадов больше не пришло - линия свободна. UART контроллер при этом не задействован, и проблемы с буферированием исчезают Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 15 января, 2010 Опубликовано 15 января, 2010 · Жалоба Да и "тяжелость" определяется ещё и скоростью передачи, особенно на очень высоких скоростях (тут уж - как не облегчай прерывания, а при некотором числе высокоприоритетных прерываний они всё равно превращаются в "тяжелое"). Да все так, только давайте посмотрим что может бегать по 485-му: В Modbus RTU например, который бегает по 485-му, недопустимы какие-то непрогнозируемые паузы между символами. Пауза больше чем 1.5 символа по стандарту является поводом для отбраковки всего пакета! Чтобы получить несвоевременный TXC, обработка UDRE должна опоздать аж на 2 символа! Т.е. межсимвольная пауза в системе где может случайно вылезти TXC посреди пакета - может достигать 2х символов. Как следствие этого - работа в Modbus RTU протоколе становится невозможной впринципе в такой системе. Что делать? Отказаться от RTU? - нельзя, причины сами знаете. Поэтому обработчики более выскоприоритетных прерываний строятся так, чтобы была гарантия отработки более низкоприоритетных во-время. Если не получается это сделать на одном AVR, тогда ставится еще один чип в помощь, либо берется другой МК, т.к. заранее известно, что система без этого захлебнется. PS: С очень высокими скоростями по UART'у на AVRках не работаю - 115200 макс. AVRки у меня всегда не ниже 11.059 тактируются, в основном 14.7456. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
admiral 0 18 января, 2010 Опубликовано 18 января, 2010 · Жалоба admiral, если "правильность" софта не пугает и это будет временной мерой, то достаточно будет перед засыпанием установить задержку в виде N*2 холостых циклов. где N - это к-во тактов необходимые для отправки одного байта по USART. а умножаем на 2, т к у USART'а двойная буферизация. глупее не бывает, но вроде как временная мера сойдет Я так и сделал - установил задержку 2мс перед засыпанием и стало все нормально. Просто мучал меня этот вопрос т.к. нерационально получается - вдруг когда-то придется использовать USART не только для отладки. Да и думал может в документации ошибка закралась, т.к. не пойму почему не сделали сброс флага TXC при занесении данных в UDR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maik-vs 0 20 января, 2010 Опубликовано 20 января, 2010 · Жалоба Я так и сделал - установил задержку 2мс перед засыпанием и стало все нормально. Просто мучал меня этот вопрос т.к. нерационально получается - вдруг когда-то придется использовать USART не только для отладки. Да и думал может в документации ошибка закралась, т.к. не пойму почему не сделали сброс флага TXC при занесении данных в UDR. Сбрасывать флаг прерывания должно только прерывание, иначе разрушится мир :) Затраты на сброс флага невелики - если прерывание разрешено, это время на 2 загрузки адреса + 1 такт на reti. Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны. Вам нужно вместо задержки 2 мс поставить ожидание флага TXC, его сброс (записью в TXC единицы!) и можно засыпать. Прерывание TXC должно быть запрещено (бит TXCIE =0), чтобы флаг TXC стоял не сбрасывался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 20 января, 2010 Опубликовано 20 января, 2010 · Жалоба Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны. А что мешает отслежить состояние флага перед записью в UDR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба В Modbus RTU например, который бегает по 485-му, недопустимы какие-то непрогнозируемые паузы между символами. Пауза больше чем 1.5 символа по стандарту является поводом для отбраковки всего пакета!Вы забыли упомянуть ещё о такой особенности таймаутов Modbus RTU:#define MB_MIN_15T_TIMEOUT MB_SEC_TO_TCNT_TIC( 0.000750f ) // 750 us if bps>19200 #define MB_MIN_35T_TIMEOUT MB_SEC_TO_TCNT_TIC( 0.001750f ) // 1.750 ms if bps>19200 Я её использую. Раз уж пошёл разговор про Modbus RTU, то хочу спросить кто как обеспечивает гарантию паузы 3,5T меду пакетами? Я всегда отправляю преамбулу из 4 dummy байтов с отключенным передатчиком драйвера RS485. Какие у Вас соображения на сей счёт? Может это лишняя паранойя, ведь я и так отлавливаю конец посылки по паузе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба кто как обеспечивает гарантию паузы 3,5T между пакетами? Никакая не паранойя - можно позволить УАРТУ за счет собственных средств не только разделять пакеты при передаче, но и обнаруживать паузу при приеме, отсылая также пустые фреймы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба А я вот всё больше и больше склоняюсь к тому что это лишне. Будь я slave или master, я ловлю конец посылки по паузе в 3,5Т ВСЕГДА - это ведь и есть гарантия разделения пакетов. Так что слейв может отвечать немедленно без преамбулы сразу по факту получения пакета. ИМХО. Я сейчас поэкспериментирую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Я всегда отправляю преамбулу из 4 dummy байтов с отключенным передатчиком драйвера RS485. Такой подход имеет смысл применять тогда, когда мастер отправляет несколько broadcast сообщений (address 0x00 / 0xFF) подряд, не дожидаясь ни от кого ответа. Настройка системы, синхронизация времени, старт синхро-измерения и т.п. Во всех остальных случаях - достаточно факта определения конца посылки по паузе в 3,5Т, и мастеру и слейвам. Но на мой взгляд отправка 4х dummy байтов с отключенным передатчиком ломает всю "тупизну и прямолинейность" :) драйвера UART'a. Если без этого действует простейший алгоритм: - включить передатчик - отправить символ - выключить передатчик если TXC. то в случае с преамбулой будут варианты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Никакая не паранойя - можно позволить УАРТУ за счет собственных средств не только разделять пакеты при передаче, но и обнаруживать паузу при приеме, отсылая также пустые фреймы.Поясните если не трудно про: "обнаруживать паузу при приеме, отсылая также пустые фреймы". Интересно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Что ж тут непонятного. Время на передачу байта фиксированное. Оно и используется в качестве таймера. А байт дальше драйвера 485 не уйдет. На быcтрую руку примерно так: По RxC: UDR = dummy; TimeOut = 0; По TxC: if (++TimeOut <= N) {UDR = dummy;} else {DoOnTimeOut} N, по моему, должен быть равен 4. таким образом обнаруживается пауза > (4T...5T) (т.е. не факт, что пауза 4,5Т будет обнаружена) P.S. Можно в качестве dummy-байта взять 0x0F. ТОгда получим фронт в середине байта на 0,5Т. И выход Tx завести на прерывание (по фронту). ТОгда можно будет обнаруживать паузы > (3,5Т...4,5Т). Но надо ли? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 23 января, 2010 Опубликовано 23 января, 2010 · Жалоба ТОгда получим фронт в середине байта на 0,5Т. Вы ж не забывайте, что длительности в 1,5 и 3,5 Т выбирались исходя их соображений накрыть всех "опоздавших" и "неуспевающих" однозначным событием разделения данных. Имхо, если внутри распознается соответственно 2 и 4 Т, ничего страшного и "роняющего перфоманс" не происходит. Проще надо быть с модбасом :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 29 января, 2010 Опубликовано 29 января, 2010 · Жалоба Проще надо быть с модбасом :) Товарищи! Возник у меня ещё один вопрос про modbus. Хотелось бы узнать какие-нибудь элегантные способы решения проблемы поддержания функционирования стандартных функций чтения-записи регистров и коилов в контексте 8-ми битного little-endian MCU. Я решаю сейчас данную закавыку через remap-таблицу во FLASH. Она зараза большая становится, когда много данных нужно ремапить, да и нудно её редактировать (хоть всё уже и так через макросы зафигачено). Я уже и так и сяк, но ничего другого выдумать не могу. Прошу ALL не стеснятся и высказывать любые здравые предложения! Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться