Назад к основам: универсальный асинхронный приемник/передатчик (UART)
Данная техническая статья кратко объясняет некоторые низкоуровневые детали широко распространенного (я бы даже сказал, вездесущего) интерфейса связи UART.
Во всем мире, вероятно, лишь очень малая часть инженеров и энтузиастов электроники не имела дела с интерфейсом универсального асинхронного приемника/передатчика (UART). В мире, где технология может стать устаревшей очень быстро, мы должны отдать должное тому, кто создал эту простую цифровую схему связи, которая до сих пор в течение многих десятилетий пользуется огромной популярностью.
Примечание: термин «UART» довольно расплывчат. Различные аспекты интерфейса – количество битов данных, количество стоповых битов, логические уровни, четность – могут быть адаптированы под требования системы. В данной статье мы остановимся на реализации UART, которая обычно встречается в современных приложениях на микроконтроллерах.
Возможности и характеристики
Как вы, наверное, знаете, базовая система UART обеспечивает надежную, среднескоростную, полнодуплексную связь только с тремя сигналами: Tx (последовательно передаваемые данные), Rx (последовательно принимаемые данные) и земля. В отличие от других протоколов, таких как SPI и I2C, в нем не требуется никаких сигналов синхронизации, так как пользователь дает аппаратному обеспечению UART необходимую для синхронизации информацию.
На самом деле, сигнал синхронизации существует, но он не передается от одного устройства связи к другому; и приемник, и передатчик имеют внутренние тактовые сигналы, которые управляют тем, как изменение логических уровней генерируется (на стороне Tx) и интерпретируется (на стороне Rx). Неудивительно, что связь через UART не работает, если передатчик и приемник настроены на разные частоты передачи данных. Кроме того, внутренние тактовые сигналы должны быть:
- достаточно точны и близки к ожидаемой частоте;
- достаточно стабильны в течение долгого времени и изменений температуры.
Ключевые термины
Давайте рассмотрим некоторые термины и попутно характеристики UART:
- Стартовый бит
- Первый бит в передаче одного байта через UART. Он указывает на то, что линия данных покидает состояние ожидания. В состоянии ожидания, как правило, на линии установлен высокий логический уровень, поэтому стартовый бит равен низкому логическому уровню. Стартовый бит является вспомогательным, это означает, что он обеспечивает связь между приемником и передатчиком, но не передает значимых данных.
- Стоповый бит
- Последний бит в передаче одного байта через UART. Его логический уровень равен логическому уровню в состоянии ожидания, то есть, логической единице. Это еще один вспомогательный бит.
- Битовая скорость
- Приблизительная скорость (в битах в секунду, или бит/с, bps), с которой данные могут быть переданы. Более точное определение частоты (в бит/с) соответствует времени (в секундах), необходимому для передачи одного бита цифровых данных. Например, для системы 9600 бит/с, для передачи одного бита требуется 1/(9600 бит/с) ≈ 104,2 мкс. Эта система не может на самом деле передавать 9600 бит значимых данных в секунду, так как требуется дополнительное время для передачи служебных битов и, возможно, для задержек между передачами отдельных байтов.
- Бит четности
- Бит обнаружения ошибок, добавленный к концу байта. Возможны два типа: «нечетность» означает, что бит четности будет равен логической 1, если байт данных содержит четное количество битов, равных логической 1, и «четность» означает, что бит четности будет равен логической 1, если байт данных содержит нечетное количество битов, равных логической 1. Это может показаться нелогичным, но идея состоит в том, что бит четности гарантирует, что количество битов, равных логической 1, всегда будет нечетным (для нечетности) или четным (для четности). Поэтому, если вы используете четность, и байт имеет три бита, равных логической 1, то общее количество битов, равных логической 1 в переданных данных, (то есть, сам байт плюс бит четности) будет четным.
Принудительно приводя количество битов, равных логической единице, к четному (при четности) или нечетному (при нечетности) количеству, бит четности обеспечивает грубый механизм обнаружения ошибок – если где-то в процессе передачи какой-либо бит будет перевернут, то количество битов, равных логической 1, не совпадет с выбранным режимом четности. Конечно, этот метод не поможет, если будут перевернуты значения сразу двух битов, поэтому бит четности не так уж и надежен. Если вам действительно нужна устойчивая к ошибкам связь, я бы рекомендовал использовать CRC.
Синхронизация и выборка
Стандартные цифровые данные бесполезны без какого-либо механизма синхронизации. На рисунке ниже показано почему:
Типовой сигнал данных представляет собой просто напряжение, уровень которого изменяется между состояниями логического нуля и единицы. Приемник может правильно преобразовать эти логические состояния в цифровые данные, только если он знает, когда сделать выборку сигнала. Это может быть легко выполнено с помощью отдельного тактового сигнала – например, передатчик обновляет сигнал данных при каждом нарастающем фронте тактового сигнала, а приемник затем делает выборку данных по каждому заднему фронту.
Однако, как следует из названия «универсальный асинхронный приемник/передатчик», интерфейс UART не использует тактовый сигнал для синхронизации устройств Tx и Rx. Так как же приемник узнает, когда сделать выборку сигнала данных передатчика?
Передатчик формирует битовый поток на основе своего тактового сигнала, а целью приемника является использование своего тактового сигнала для выборки входящих данных в середине каждого битового периода. Выполнение выборки в середине битового периода не является обязательным, но этот момент оптимален, так как выборка ближе к началу или к концу битового периода делает систему менее устойчивой к различиям тактовых частот приемника и передатчика.
Последовательность приемника начинается с заднего фронта стартового бита. Это очень важный момент процесса синхронизации. Внутренний тактовый генератор приемника полностью независим от внутреннего тактового генератора передатчика – другими словами, эта граница спада сигнала может соответствовать любой точке в тактовом сигнале приемника.
Чтобы гарантировать, что активный фронт тактового сигнала приемника будет приходиться примерно на середину битового периода, частота тактового сигнала битовой скорости, переданная в модуль приемника, значительно выше (в 8 или 16, или даже в 32 раза) реальной битовой скорости.
Допустим, что один битовый период соответствует 16 циклам тактового сигнала приемника. В этом случае синхронизация и выборка могут быть выполнены следующим образом:
- процесс приема запускается по границе спада стартового бита;
- приемник ждет в течение 8 циклов тактового сигнала, чтобы установить момент выборки, который находится близко к середине периода бита;
- приемник ждет в течение 16 циклов тактового сигнала, которые приводят его к середине периода первого бита данных;
- первый бит данных оцифровывается и сохраняется в регистре приемника, а затем модуль снова ожидает 16 циклов тактового сигнала перед выборкой второго бита данных;
- этот процесс повторяется до тех пор, пока все биты данных не будут выбраны и сохранены, а затем нарастающий фронт стопового бита возвращает интерфейс UART в режим ожидания.
Заключение
Данная статья охватывает некоторые подробности о протоколе передачи данных, который вы, возможно, успешно использовали много раз. Интерфейс UART вполне можно использовать, очень мало зная о реальном поведении сигналов и аппаратного обеспечения, но немного дополнительных знаний может быть полезно, когда ваша связь через UART не работает, как ожидалось.