Dima1060 0 26 ноября, 2015 Опубликовано 26 ноября, 2015 · Жалоба Так подключите MAX485 прямо к FT232R или CP2103 или возьмите готовый переходник, а всю обработку делайте на компьютере. Зачам там еще МК? А этот преобразователь, он же только данные отправляет? А счетчик USB фрейма? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 17 26 ноября, 2015 Опубликовано 26 ноября, 2015 · Жалоба А мне удобнее COBS преобразование сделать в датчике, а в МК1 добавить байт - номер датчика. А почему датчик не может сразу добавить свой номер и CRC, а потом закодировать сообщение? Добавить байт (т.е номер датчика) к уже закодированному COBS сообщению - вообще-то проблема, даже если этот номер не равен 0. Потому что в корректной реализации при раскодировании сообщения на месте этого байта должен быть или 0 (это значит, что сообщение закончено), или число последующих ненулевых байт в сообщении. Конечно, можно наставить костылей, например, если длина сообщения фиксирована, то последний байт обрабатывать не так, как остальные. Только нехорошо это. почему? данных же мало, всего то 12 байт. Потому иначе намного больше вероятность, что что среди ложных сообщений будет такое, что пройдет проверку. А этот преобразователь, он же только данные отправляет? А счетчик USB фрейма? SOF-ы автоматически считаются "на нижнем уровне". А накой вам этот счетчик? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 26 ноября, 2015 Опубликовано 26 ноября, 2015 · Жалоба А почему датчик не может сразу добавить свой номер и CRC, а потом закодировать сообщение? а как? датчик же не знает какой у него номер. все датчики одинаковые, воткнул в 1-е гнездо, значит датчик №1, если в о 2-е, то №2 SOF-ы автоматически считаются "на нижнем уровне". А накой вам этот счетчик? Для синхронизации. У меня в USB МК отправляется сначала счетчик фрейма (2 байта), потом данные Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 17 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба а как? датчик же не знает какой у него номер. все датчики одинаковые, воткнул в 1-е гнездо, значит датчик №1, если в о 2-е, то №2 Тогда пусть все датчики ставят в нужное место номер 1, кодируют и отправляют. А ваш МК1 просто заменит номер 1 в этом месте на действительный номер датчика. Если он не будет равен 0, то на COBS это никак не повлияет. Однако при этом придется обойтись без CRC на все сообщение, поскольку CRC надо добавлять до того, как кодировать по COBS. Можно, конечно, CRC считать в датчике, а "1" добавлять потом, но при этом номер датчика не будет охвачен CRC. Это не очень хорошо, но работать будет. Для синхронизации. У меня в USB МК отправляется сначала счетчик фрейма (2 байта), потом данные Какой счетчик? Взятый в тот момент, когда вы получили сообщение, или в тот момент когда вы его сформировали в буфере для отправки? Неужто вы думаете, что он будет отправлен в том же фрейме? Ведь вы же BULK используете, а он асинхронный. Специфиkация USB: 5.12.4.1.1 Asynchronous Asynchronous endpoints cannot synchronize to SOF or any other clock in the USB domain. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Тогда пусть все датчики ставят в нужное место номер 1, кодируют и отправляют. А ваш МК1 просто заменит номер 1 в этом месте на действительный номер датчика. Если он не будет равен 0, то на COBS это никак не повлияет. Однако при этом придется обойтись без CRC на все сообщение, поскольку CRC надо добавлять до того, как кодировать по COBS. Можно, конечно, CRC считать в датчике, а "1" добавлять потом, но при этом номер датчика не будет охвачен CRC. Это не очень хорошо, но работать будет. Хорошая идея, я подумаю... Нет смысла охватывать номер датчика CRC, он же все равно будет переписан. Хотя может быть испорчен дальше, но дальше все таки дифф пара RS-485. Какой счетчик? Взятый в тот момент, когда вы получили сообщение, или в тот момент когда вы его сформировали в буфере для отправки? Неужто вы думаете, что он будет отправлен в том же фрейме? Ведь вы же BULK используете, а он асинхронный. Специфиkация USB: 5.12.4.1.1 Asynchronous Asynchronous endpoints cannot synchronize to SOF or any other clock in the USB domain. я использую изохронный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 17 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Нет смысла охватывать номер датчика CRC, он же все равно будет переписан. Хотя может быть испорчен дальше, но дальше все таки дифф пара RS-485. А вы этот номер передавайте в самом байте дважды: в младших 4 битах сам номер, а в старших четырех битах - его инверсию. Так вы любые одиночные ошибки в этом байте обнаружите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба А вы этот номер передавайте в самом байте дважды: в младших 4 битах сам номер, а в старших четырех битах - его инверсию. Так вы любые одиночные ошибки в этом байте обнаружите. Понятно, спасибо. А еще Вы писали, что в Википедии "сложный" вариант перекодировки COBS. Где тогда можно простой посмотреть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Опять товарища =AK= куда-то понесло - предложил для RS485 с шумами в паузах протокол канального уровня, позволяющий отловить конец пакета, но не его начало после шума. А потом еще предложил всунуть между канальным и физическим уровнями кусок транспортного (номер пакета). Аплодисменты. Atlantis-, почитайте про сетевую модель OSI. У вас есть физический уровень - RS485. Поверх него вы строите канальный, отвечающий за разбивание потока вашей информации на пакеты и контрольную сумму. COBS тут не подходит по указанной выше причине - малейший шум в паузе и пакет вы потеряли. Посмотрите на SLIP, реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета. Далее строите сетевой уровень - добавляете в протокол адреса ваших датчиков. Если у вас каждый датчик воткнут в свой отдельный интерфейс - сетевой уровень на этом участке вам не нужен. Далее сверху накладываете транспортный уровень - добавляете в протокол номер пакета. И сверху водружаете прикладной уровень - собственно ваши данные. При передаче идете по модели сверху вниз: берете данные (прикладной уровень), добавляете к ним номер пакета(транспортный уровень), добавляете адрес(сетевой уровень), считаете контрольную сумму и обкладываете все это байт-стаффингом (канальный уровень, SLIP-подобные протоколы позволяют делать это побайтно, прямо в процессе передачи, не видя пакета целиком) и в конце передаете получившийся пакет данных через UART в RS-485 (физический уровень). На приемной стороне вы двигаетесь по модели снизу вверх: принимаете байты из RS-485 (физический уровень), обрабатывая SLIP-подобный протокол убираете байт-стаффинг и выделяете начало/конец пакета, считаете контрольную сумму (канальный уровень), далее отделяете и обрабатываете адрес (сетевой уровень), следом номер пакета (транспортный уровень) и в результате получаете ваши исходные данные очищенные от всей этой шелухи, т.е. в том виде, в котором эти данные поступили из прикладного уровня на передающей стороне. И все изменения данных вы делаете только двигаясь по этой цепочке. Приняли вы на физическом уровне пакет не содержащий адреса, надо вам добавить в него адрес - вы очистили пакет от обертки канального уровня (остался пакет транспортного уровня), добавли к этому пакету транспортного уровня адрес, снова завернули получившийся пакет сетевого уровня в обертку канального уровня и передали по физическому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=AK= 17 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба в Википедии "сложный" вариант перекодировки COBS. Где тогда можно простой посмотреть? "а это уж вы сами" © Щербаков предложил всунуть между канальным и физическим уровнями кусок транспортного (номер пакета). COBS тут не подходит по указанной выше причине - малейший шум в паузе и пакет вы потеряли. К сожалению, вы ничего не поняли, даже какой-то "номер пакета" вдруг выдумали и приплели ни к селу ни к городу. Никакой шум в паузе не повлияет на прием пакета из-за того, что передатчик передает два 0 до начала пакета. После паузы приемник гарантировано получит хотя бы один 0, после чего "шумовой" пакет будет проверен и отвергнут из-за несовпадения CRC, а также из-за несоответствия правилам COBS. А следующий сразу же вслед за этим истинный пакет будет принят без искажений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Посмотрите на SLIP, реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета. SLIP использует разделитель фреймов, который используется и в начале и в конце пакета и в любом количестве. Никакой шум в паузе не повлияет на прием пакета из-за того, что передатчик передает два 0 до начала пакета. Совет неверный. Нужен один 0xFF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Совет неверный. Нужен один 0xFF. Что-то мне эта тема напомнила... Ага, вот эту тему. Там долго выясняли способ гарантированно восстановить битовую синхронизацию при непрерывной передаче потока. =AK= описал применяемый им способ посылки двух подряд символов 0x0F, при котором второй символ гарантированно ловится. Потом выяснилось, что это не так, по крайней мере, не со всеми контроллерами UART. Символ же 0xFF, переданный перед началом пакета, гарантированно восстановит битовую синхронизацию: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Символ же 0xFF, переданный перед началом пакета, гарантированно восстановит битовую синхронизацию: Байтовую :) Битовая, если надо, захватывается по 0x55. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба SLIP использует разделитель фреймов, который используется и в начале и в конце пакета Границей SLIP-кадра является уникальный флаг END (0xC0).Как-то неразумно называть признак начала кадра именем "END". RFC 1055: The SLIP protocol defines two special characters: END and ESC. END is octal 300 (decimal 192) and ESC is octal 333 (decimal 219) not to be confused with the ASCII ESCape character; for the purposes of this discussion, ESC will indicate the SLIP ESC character. To send a packet, a SLIP host simply starts sending the data in the packet. If a data byte is the same code as END character, a two byte sequence of ESC and octal 334 (decimal 220) is sent instead. If it the same as an ESC character, an two byte sequence of ESC and octal 335 (decimal 221) is sent instead. When the last byte in the packet has been sent, an END character is then transmitted. Про признак начала ничего не сказано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Как-то неразумно называть признак начала кадра именем "END". Это не ко мне :). В реальные реализации протокола ПРАВИЛЬНО отрабатывают и одиночные разделители и начало-конец и любое количество "END" в качестве разделителей. Что совершенно ествественно и соответственно никаких "реализуйте что-то похожее, но с отметкой не только конца, но и начала пакета" не требуется. RFC 1055 Про признак начала ничего не сказано. Из этого-же RFC: /* SEND_PACKET: sends a packet of length "len", starting at * location "p". */ void send_packet(p, len) char *p; int len; { /* send an initial END character to flush out any data that may * have accumulated in the receiver due to line noise */ send_char(END); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 206 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба Предлагаю конец теме — передаём, после получения TC=1 отключаем драйвер, делаем задержку, устанавливаем RE=1, немного попринимали, далее сразу устанавливаем RE=0, включаем драйвер, делаем задержку и снова передаём. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться