Обработка ошибок UART

Я не сосредотачиваюсь на конкретном микроконтроллере, поскольку UART большинства контроллеров имеет аналогичную архитектуру. У них есть FIFO для Tx и Rx.

Наиболее распространенные ошибки, генерируемые UART: 1. Ошибка кадрирования 2. Ошибка четности 3. Ошибка переполнения (переполнение Tx/Rx FIFO) 4. Ошибка прерывания приема (некоторая ошибка со стоп-битами)

Как следует обрабатывать эти состояния ошибок, чтобы поддерживать связь должным образом?

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

Ответы (3)

Чтобы на самом деле ответить на ваш вопрос, я обычно отбрасываю все, что получено с ошибкой. Это может включать повторную инициализацию аппаратного обеспечения UART, в зависимости от того, какая это ошибка, и деталей аппаратного обеспечения UART.

Единственное исключение, если вы хотите намеренно получать перерывы. Они проявляются как ошибки кадрирования. В этом случае вы передаете ошибки кадрирования на более высокие уровни как особые условия. Однако это требует передачи внеполосной информации на более высокие уровни, и поэтому интерфейс приемника UART нельзя рассматривать как нечто столь же простое, как получение потока байтов. Я думаю, что делал это ровно один раз во многих проектах микроконтроллеров, потому что это должно было быть совместимо со старой системой, в которой преднамеренно использовались разрывы.

Стивен дал вам несколько хороших идей, что делать с этим на более высоком уровне. Когда вы считаете, что существует реальная вероятность ошибок и важна целостность данных, вы обычно инкапсулируете фрагменты данных в пакеты с контрольными суммами. Получатель отправляет ACK для каждой правильно полученной контрольной суммы.

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

Эти ошибки не могут быть исправлены, поэтому требуется повторная передача. Для этого нужен какой-то протокол на более высоком уровне, чем UART; обычно вы хотите подтвердить правильный прием пакета данных. Этот пакет может состоять из 1 байта, но могут использоваться и более длинные пакеты, если при обмене мало ошибок. Подтверждайте каждый пакет, отправляя ACK передатчику, NACK, если произошла ошибка. В последнем случае отбрасывайте пакет и ждите повторной передачи.
Если вы используете пакетную передачу, вы можете рассмотреть возможность проверки ошибок CRC вместо контроля четности, что не очень эффективно (добавляет 1 бит на байт) и выявляет только однобитовые ошибки.

Когда в полученных данных UART есть ошибка кадрирования, велика вероятность того, что все последующие байты будут мусором, пока, в зависимости от UART, между последовательными падающими фронтами на проводе данных не будет десяти или более битовых периодов, девятнадцати битовых интервалов. последовательного интервала или девяти битов, умноженных на последовательную маркировку (последний из них будет работать на всех UART). Если получен правильно сформированный байт со значением 0x00 или 0x80 (0x100 в 9-битном режиме) и либо передатчик не отправляет длинные паузы, либо приемник прекращает попытки разобрать байты из любых длинных пауз, которые посылает передатчик, можно будьте уверены, что это правильно, и последующие байты также будут правильными. Если кто-то получает значение, в котором 0-6 последовательных «нулей» в младших битах, а остальные биты все установлены,

S=START P=данные предыдущего байта s=stop D=текущий байт - =ожидание
0111111101000000011111 -- Сигнал на линии
Ps------SDDDDDDDDDs--- : как задумано передатчиком (0x02)
SPPPPPPPPsSDDDDDDDDs- : как получено (0xC0)

Если каждый пакет начинается с 0x00, а за ним следует 0xFF, ошибка кадрирования в одном пакете не повлияет на следующий. Когда получатель замечает ошибку кадрирования, он может начать отбрасывать данные до тех пор, пока не увидит правильно сформированный 0x00, после чего он будет знать, что у него есть законное начало пакета.