Интерфейс RS-485

Интерфейс RS-485

Последнее время я делаю по большей части промышленные устройства и все чаще там используется именно RS-485. Потому как он используется как физический для множества протоколов, принятых в проме, таких, например, как MODBUS или ProfiBUS.

▌Принцип работы
Интерфейс RS485 хорош тем, что он, по сути дела, является дифференциальным вариантом RS-232 и его можно вешать на банальный USART любого микроконтроллера.

Физически он состоит из двух линий связи. А и B. Наличие земли желательно, но вовсе не обязательно. Отсутствие земли чаще всего чревато тем, что входящие данные будут иногда начинаться с нуля. Т.е. шлешь строку 0xBA 0xDF 0xF0 0x0D, а приходит 0х00 0xBA 0xDF 0xF0 0x0D, а дальше все нормально.

Исходный входной сигнал разделяется на два сигнала и они улетают вдаль по двум свитым проводам, витой паре.

По линии А идет прямой UART, как он есть, а по линии В его зеркальная копия. А в приемнике, на дифференциальном операционном усилителе, одно вычитается из другого и получается исходный сигнал.



Зачем это сделано? Зачем вообще такие сложности? Линия может длиться километры, да, для RS485 длина сегмента допускается до 1200 метров. На таком расстоянии сигнал, если его послать по одному проводу и земле, упадет на сопротивлении линии и до приемника дойдут считанные доли вольта. Тут же, у нас компаратор на входе усилит разность сигнала даже крошечной величины, восстановив исходный сигнал. Нет нужды четко соглассовывать уровень земли приемника и передатчика, на большом расстоянии это может быть тяжело решаемой задачей.

Это первое, но куда более важным является то, что таким образом намного увеличивается помехозащищенность самой линии. Ведь если рядом будет какая-то электромагнитная помеха, которая наведет на наш длиннющий провод колебание напряжения, то, так как оба провода идут рядом, во втором проводе наведется ТОЧНО такая же помеха. А поскольку у нас на входе сигнал разностный А-B, из помехи в проводе А будет вычтена такая же помеха в проводе В и она обнулится.

По такому же принципу, дифференциальной линии, делают очень многие критичные к помехам цепи. USB, Ethernet, LVDS да много где… где то линия одна, как в USB, где то их несколько, как в Ethernet или LVDS. Но суть остается той же.

Естественно по данной линии связи передача может идти только в одну сторону. Т.е. RS485 у нас полудуплексный. Мы вначале в него орем, а потом слушаем что нам ответили с другой стороны. Общаться в обе стороны, как в UART по Rx и Tx не выйдет. Ну или придется пускать уже четыре провода, одна для передачи, другая для приема.

В обычно в трансивере 485 интерфейса передатчик и приемник в одном корпусе, на одной линии, а направление выбирается ногой, уровень на которой определяет в каком режиме микросхема в приеме или в передаче.

На одной линии может висеть несколько приемников и передатчиков. Они подключаются просто параллельно.

Разумеется общаться они могут строго по одному и общий галдеж в линии приведет к полной неработоспособности всей сети. Никакого аппаратного арбитража на основе «приоритета нуля», как в I2C тут нет.

Способы разрешения конфликтов тут исключительно программно логические. Например, все участники договариваются, что общаются по очереди и каждый после передачи выдает спец сообщение, говорящее о том, кто следующий имеет право сообщить в линию, как микрофон передают в зале по кругу. Если принявшему свой номер сказать нечего, то он обязан передать хотя бы служебное сообщение о том, что теперь может говорить следующий.
Когда передатчик один, а остальные приемники, как часто бывает у меня, то вначале шлем адрес, все его принимают и только тот кому адресовано это сообщение его обрабатывает, остальные же отправляют его в никуда. Короче, способов много и все это давно изобретено. Остается только погуглить всякие методы вроде Token Ring и сами разберетесь :)

▌Железо
Классической микросхемой такого интерфейса служит MAX485 или ST485, или ADM485… В общем, если видите на плате восьминожку с надписью что-то там 485 — скорей всего это оно :)

Она подключается к USART микроконтроллера и еще нужна одна нога, чтобы указывать направление обмена. Прием у нас или передача.

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

Разберемся сначала с резистором-терминатором.

Сигнал идет по проводу быстро, но не мгновенно, более того, он дойдя до конца линии может отразиться и пойти обратно. Как вода в желобе, пускаешь по желобу волну, волна дошла до стенки и пошла обратно. И эта волна может столкнуться с волной следующего импульса, смешаться и получить полную кашу на выходе. Разумеется эти эффекты возникают только при длинных линиях (В ТОЭ прям есть раздел такой — длинные линии, разбирающий все эти волновые эффекты), либо на высоких частотах. Так как с ростом частоты «длинной» может стать линия даже в 5см, например, когда речь идет о гигагерцах.

Поскольку у нас RS485 может работать до скорости вплоть до 10Мбит, а дальность свыше километра, то такие эффекты могут возникнуть. Чтобы подавить отраженную волну и нужен резистор-терминатор. Он стоит у приемника между линиями А и В. Его сопротивление обычно 120ом. Это не спроста так, все дело в том, что волновое сопротивление витой пары, как правило, 120 ом и чтобы погасить волну резистор должен быть с ней согласован.

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

Теперь о подтяжках. Они, как бы, опциональные, будет работать и без них, но лучше их поставить. Хотя бы на первом и последнем устройстве линии. Чтобы линию не телепало помехами и не генерировало вам непонятные сообщения. Подтяжка защитит нас от хаотичных данных при обрыве линии, например.
Конечно у приемника есть гистерезис, примерно на 200мв, т.е. разность между А и В меньше 200мВ не учитывается как сигнал, и на выходе будет 1, но все равно лучше подстраховаться.

Линию А подтягиваем вверх, а линию В вниз. Через резисторы в 1.2кОм с обеих концов.

Единственно, что у такого решения есть минус — через эти резисторы будет всегда течь ток и увеличивать потребление. Что может быть критичным для систем с батарейным питанием, но использующем RS485. Странная экзотика, но чего в жизни не бывает?

В этом случае можно использовать микросхемы с системой true failsafe, например MAX3080. Она позволяет отказаться от резисторов смещения, т.к. они мало того, что встроены в микросхему, так еще и пороги срабатывания там другие. И при обрыве или КЗ линии будут гарантировано давать 1 на выходе.

▌Защита
Так как линия у нас длинная, то на нее наводится всякая фигня. И естественно она прилетает нам в схему, учиняя беспредел. Первое с чем стоить бороться — перенапряжения. Для защиты от этого применяют супрессоры. Это такие мощные стабилитроны, часто собранные в одном корпусе встречно друг другу. И при превышении напряжения они открываются и стравливают перенапряжение в землю или питание, смотря как включено. А там с этой энергией разберутся конденсаторы и блок питания.

Разумеется поможет это только от кратких перенапряжений, от помех. От длительных перенапряжений нужны уже предохранители. Плавкие или самовосстанавливающиеся. Т.е. если что-то начало нам гнать в линию высокое напряжение, то вначале сработает супрессор, высадив его на землю, а потом выжгется предохранитель. Я использую SMBJ-5.0 супрессоры.

Также я ставлю варистор между А и В. Можно и двунаправленный супрессор поставить, но варистор компактней. Это резистор который пробивается на высоком напряжении. Резко уменьшая свое сопротивление с мегаомов до десяток ом. А потом вновь становится обрывом. У меня под это дело чтото вроде JMV0805S5R6T661 который открывается от 5.6 вольт и способен пережить 40А в пике.

Последнее время я не экономлю и делаю полноценную развязку интерфейсной части. Ставя туда питание на AM1D-0505SZ и изолируя интерфейс через ADM2483. Это RS485 трансивер со встроенной опторазвязкой.

Работает просто песня :)

▌Кабель, земля и экран
Вообще, на короткие расстояния, десятки метров, и при небольшой скорости, по 485 интерфейсу можно гнать сигнал через любое говно. Даже через старую, советскую плоскую телефонную лапшу. На практике же, для физического уровня приходится использовать все что под руку попадается и уже проложено на объекте. Например, кабель видеонаблюдения, с волновым сопротивлением в 75 Ом, но ему требуются низкоомные же терминаторы в 75 Ом, что снижает количество девайсов на одном сегменте — трансивер просто не вытащит по току. Второй популярный пример — комповая витуха, у ней волновое сопротивление 100Ом, что уже лучше. И сами кабели дешевые, но у них тонкая жила и по этому высокое сопротивление. Есть и специализированный кабель для RS485 с волновым сопротивлением в 120Ом, как по стандарту. Правда он дорогой, не всегда доступен и зачастую не нужен :)

Для улучшения качества передачи данных хорошо бы использовать экранированный провод. При этом оплетка кабеля подключается к заземлению, а к GND через резистор ом в сто (в случае опторазвязки — к изолированной GND) с одной стороны (!!!!) только с одной стороны! Чтобы не было протекания разных токов по ней.

Если же у нас есть земляной провод, то можно задействовать и его. В данном случае его называют дренажным. Его задача уравнивать потенциалы земель. И он подключается к земле устройства (при опторазвязке к изолированной земле) через сопротивление в сотню ом. Резистор тут надо выбирать хотя бы на пол ватта.

▌Борьба с граблями
Ну и напоследок еще парочка мелких граблей на которые можно наступить, так что лучше их сразу убрать. В момент передачи, микросхема MAX485 держит выход DO в HiZ, и вам туда может нателепать разного мусора. Поэтому линию RxD микроконтроллера подтягиваем к питанию. Либо включаем подтяжку внутри контроллера. Но я всегда это делаю внешним резистором. Надежней.

А линию DE/RE следует подтягивать к нулю. Зачем? А чтобы пока контроллер не стартанул, не проинициализировался и не привел свои ноги в нужный режим этот вывод не телепался без дела и не слал в линию разный мусор.

При перед передачей никогда не помешает сделать синхронизацию кадров. Т.е. передачи нет, все участники сети сидят и слушают. И вдруг какая-то помеха пробилась и сделал старт бит в линию. Естественно все «слушатели» начнут принимать данные и получат мусор. Да хоть тот самый ноль, о котором я выше говорил. Чтобы им и ограничилось крайне желательно сделать следующее. Переводим линию прием/передача в режим передачи, при этом у нас на TxD единичка, т.к. мы еще ничего не шлем. Но драйвер RS485 при этом выдаст уже уровни в линию. Ждем паузу, равную времени передачи двух трех байтов, чтобы весь мусор прошел и не затесался в нашу передачу и только после этого засылаем первый байт нашей передачи в UART. Это повышает надежность и качество передачи на порядок.

А еще не помешает контроль четности, и прочие методы анализа качества принятых данных. Расскажу об этом вследующий раз, когда буду разбирать MODBUS.

Спасибо!!! Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics!!! Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто!!! Сейчас идет заключение договора и подготовка к строительству!

А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок!!!

17 thoughts on “Интерфейс RS-485”

  1. Спасибо за примеры конкретных наименований деталек для обвязки, супрессоров там, варисторов. Как минимум начинающим это позволит от чего-то оттолкнуться, ибо выбора — глаза разбегаются, так хоть есть проверенный для «общих случаев» вариант.

  2. Отдельное «спасибо» за разбор «граблей»!
    Замечания-вопросы:
    — На схемах нарисовать бы тот самый резистор на RxD — чтоб как шпаргалка работало. У меня каждый раз ступор на пару секунд, когда начинаю вспоминать, к каким же ногам его рекомендовал один из производителей чипов тянуть :)
    — Есть такая TVS сборка — SM712 — специально для 485. Почему отдельные 5-вольтовые, а не его — осознанно или по-незнанию?
    — Особенно интересно будет почитать про стартовую паузу в контексте modbus, а уж если с идеями реализации для FreeModbus, например, — вообще прекрасно! :)

    зы: что-то не отправляется коммент. сорри, если задублируется

    1. Картинку добавлю… как раз нашел тут сплан8. Он вызывает меньше ненависти чем сплан7 :)

      Отдельные чтобы номенклатуру не плодить. У меня они же не только на 485 идут, а вообще везде на все торчащие гпио, на питание… покупаю их бухтами и втыкаю везде. А место на плате редко экономить приходится. Обычно его дохренища просто.

  3. Еще есть adm2587/adm2582, сразу с гальванически развязаным блоком питания. К тому же здесь True Fail-Safe, то есть не надо линии подтягивать к питянию/земле, так как дифференциальное пороговое напряжение на входе было отрегулировано -200 мВ и до -30 мВ (AN-960
    APPLICATION NOTE). Но у нас на них цены космические, мы на lcsc берем по 8$ сейчас.

  4. На схеме с ADM2483 согласующий сопротивление резистор должен быть 100 Ом. У вас же там последовательно два резистора по 10 Ом. Суммарно у вас 140 Ом согласование выйдет. Также в схемах с самовосстанавливающимися предохранителями следует делать поправку на их внутреннее сопротивление при выборе сопротивления согласующего резистора.

    1. Замечание верное, да. Там просто кусок схемы из реального проекта, в данном моем случае защита важней согласования, т.к. скорость там низкая и расстояния маленькие.

  5. Мне кажется стоит уточнить ситуацию с GND выведенному наружу. Поясню. На схеме с резисторами 10 Ом GND выведено на внешний разъем. В схеме же расключения линии вывод разъема подключается к GND через 100 Ом. Получается в первой схеме нужен резистор 100 Ом между выводом колодки GND и GND во внутренней цепи.

  6. Рад что Ваша работа над статьями для начинающих и не только, продолжается. Как человеку что стремится стать хотя бы средненьким разработчиком электроники — очень полезно. Было бы интересно почитать статью о том, какой дорожкой идти новичкам чтобы преисполниться.

  7. Чертовщина твориться, не могу зайти на форум. Только сюда. Что сделать? Пароль не сбрасывается. Пишет «Введенная информация о email/имени пользователя не найдена.». При попытке зарегистрироваться выдает «использование email запрещено»

    1. Регистрация на всех моих сайтах раздельная, т.к. везде разные движки. А на форуме, вдобавок, просто запрещен весь Mail.ru слишком много с него было «ручного спама» модеры задолбались чистить эти авгиевы конюшни и просто заблочили весь майлру :)

  8. Все железо и железо. Вот по софту бы…

    Интересно было-бы посмотреть на реализацию модбас сервера какого, не чтенией байтиков, а вот именно повыше взаимодействие и интеграцию его в остальной код проекта.

    Такой инфы катастрофически не хватает.

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

Добавить комментарий

Ваш e-mail не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.