Большинство 2-проводных реализаций RS485, которые я видел, используют как контакты UART RX, так и TX, что, конечно же, работает. И я сделал это.
Но мне было интересно, является ли использование UART в полудуплексном режиме хорошей альтернативой, которая, возможно (?) имеет преимущество в более чистом коде и уменьшении количества выводов.
Приложение представляет собой Modbus ASCII, а синхронизация настолько четкая (3,5 символа), что переключение (которое я все равно делаю для DataEnable) можно объединить с TransmitEnable.
(Некоторый контекст: у меня были передатчики RS485 с локальным эхом на линии UART RX)
Это может быть хорошей идеей, если вы находитесь в ситуации, когда вам нужно сохранить булавки.
Но это также усложняет некоторые вещи.
Вам необходимо переключить один контакт MCU между режимами RX и TX для одного провода UART, в дополнение к управлению контактами включения передатчика/приемника.
Ему также может потребоваться подтягивание к линиям данных, чтобы он оставался в режиме ожидания между изменением направления вывода MCU — некоторые MCU имеют внутренние подтягивания, которые могут оставаться включенными все время, а не включаться только при вводе.
Это также делает невозможным считывание того, что передается MCU, поэтому обнаружение сбоев, коллизий или ошибок невозможно.
RS485 уже является полудуплексным. Итак, почему бы не рассказать немного больше об интерфейсе PHY.
Это хорошая идея, если вы можете найти надежный метод арбитража RX и TX на локальных узлах и арбитража шины. Став еще более активным, вы можете ввести способ обнаружения конфликтов на шине. Что касается программного обеспечения, канальный уровень может с радостью потерять какую-то серьезную часть кода.
Когда я пишу это, это действительно кажется очень интересной идеей; что-то вроде Ethernet на RS485 PHY, или там уже должно быть что-то.
Хм... стандартный Modbus/ASCII не использует тайм-аут прерывания кадра в 3,5 символа. Этот тайм-аут характерен для Modbus/RTU. Очевидно, что если вы владеете реализацией всех узлов, это мало что значит. Если ваша подпрограмма RX кадра может определить конец кадра на основе содержимого кадра (кадры переменной длины имеют длину, закодированную в начале кадра), вам, вероятно, даже не нужно соблюдать 3,5 символа ценности с точки зрения времени обработки RX/TX. ".
Когда-то я написал библиотеку Modbus для ПК, а также немного разбирался в 16C550A и совместимых UART, но эти знания устаревают. И я, конечно, ничего не знаю о UART, встречающемся в MCU. Будучи избалованным расточительным подходом к подсчету контактов в оборудовании ПК и имея лишь ржавую память о кодировании аппаратного обеспечения UART 16C550A, я не вижу, что «использование UART в полудуплексном режиме» может спасти меня с точки зрения размер или сложность кода.
Тем не менее, если я могу предложить что-то для облегчения полудуплексной работы RS485, это будет использование UART, который может автоматически управлять RX / TX , экспортируя внутренний флаг, называемый «Сдвиговый регистр передатчика пуст», в качестве внешнего дискретного сигнала, который может быть подключен непосредственно к преобразователю уровня RS485 (приемопередатчику).
Примечание: не путайте требуемый «Пустой регистр сдвига передатчика» с «Пустой регистр хранения передатчика» = другой флаг состояния в UART. Первое означает, что байт в данный момент побитно сдвигается в строку. Последнее относится к FIFO — и флаг THRE становится активным, как только FIFO пуст, т. е. пока сдвиговый регистр все еще занят смещением последнего байта, т. е. слишком рано, чтобы трансивер RS485 отключился в высокий Z/прослушивание. состояние.
Некоторые реализации UART могут отправлять этот сигнал в качестве альтернативной функции контактов RTS или DTR, другие имеют выделенные выходные контакты или могут отображать его на какой-либо GPIO. Стандартный 16C550A имеет только TSRE, также известный как TEMT, в качестве внутреннего флага состояния, но не имеет возможности экспортировать его на любой выходной контакт. То есть 16C550A не лучший выбор для RS485. В качестве блестящего примера правильно выполненной этой функции хотелось бы упомянуть покойный OX16C950 UART от Oxford Semiconductor, ныне уже не производимый (технический прогресс имеет свою оборотную сторону, и была череда приобретений, примерно OX Semi -> PLX - > Avago -> Broadcom). Если память не изменяет, современные UART от EXAR тоже могут это делать, и некоторые чипы LPC SuperIO также могут поддерживать это на некоторых или всех каналах UART (Fintek, SMSC, возможно, некоторые недавние ITE и Nuvoton, урожденная Winbond). я не
Кажется, я припоминаю некоторые UART, в которых эта функция несовершенна, а именно я вспоминаю дополнительную плату PCI для ПК с портами RS485 и аппаратным управлением, где UART переключал приемопередатчик в режим high-Z (RX) на один бит раньше, чем нужно. срезание стопового бита. Который, по-видимому, отлично работал против других UART ... Я не помню марку чипа UART на этой плате.
Я также видел ошибку проектирования на уровне платы (думаю) в некоторых азиатских промышленных ПК, где режим RS485 был реализован путем управления управляющим штифтом приемопередатчика RX / TX с помощью TTL Data TX UART, так что приемопередатчик переключался между лог. 1 и высокий Z...
Эта функция, т.е. "TSRE=TEMT для управления RX/TX RS485", может избавить вас от головной боли, связанной с точной синхронизацией в программном обеспечении. Это, безусловно, головная боль на ПК, особенно под некоторыми современными ОС ... независимо от того, является ли синхронизация головной болью или нет на вашем конкретном MCU, это, очевидно, ваше личное дело, YMMV.
Марко Буршич
Тони Стюарт EE75
ДжеромБу1982