Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Как организовать корректный обмен
Обратим внимание на другую сторону проблемы. При асинхронной передаче пакетов данных без предварительного запроса со стороны приемника возникает вопрос о том, как распознать начало посылки — велика вероятность, что приемник включится где-то в середине очередной последовательности. Например, навигаторы GPS каждую секунду выдают довольно длинный пакет данных, содержащий порядка 500 байтов информации и состоящий более чем из десятка отдельных кадров-сообщений по протоколу NMEA, и эти кадры нужно как-то различать (не все сообщения требуются на практике).

Самый распространенный прием, которым мы уже пользовались при записи данных во flash-память (чтобы отличить кадры измеренных величин от кадров времени, см. главу 12) — предварять нужный кадр специальным байтом, который не может встречаться в основной последовательности. У нас это был байт $FA (ни среди измеренных величин, ни среди значений времени не может встретиться байт, превышающий 127), в протоколе NMEA это символ "$" (численное значение $24). Приемник, встретив такой байт, "понимает", что перед ним начало определенного кадра, отдельные байты которого нужно интерпретировать соответствующим образом. Другой пример— в распространенном среди производителей промышленных контроллеров протоколе MODBUS, основанном на передаче ASCII-символов, любое сообщение начинается с двоеточия (код $ЗА) и заканчивается символами "возврат каретки" — "перевод строки" (CR LF, $0D $0А). Здесь также имеются две проблемы.
В общем случае число информационных байтов в кадре не определено (это мы задавали, что их будет определенное количество, а, например, в протоколе NMEA в разных сообщениях число байтов варьируется от десятка-полутора до нескольких десятков), и тогда приходится писать специальную программу-парсер, разбирающий кадры на отдельные элементы. Вторая проблема заключается в том, что подобрать специфический байт, однозначно идентифицирующий начало кадра, не всегда просто: при передаче данных сплошь и рядом встречаются ситуации, когда информационные байты могут иметь произвольное значение во всем диапазоне от 0 до 255. Иногда для этого применяют посылку девятого бита с определенным значением (см. также далее о дополнительных возможностях USART), в протоколе MODBUS числа передаются в ASCII-коде (например, 10 как пара символов "1" и "0"), и там перепутать их с символами начала и конца посылки невозможно, но такие приемы не очень удобны. Эффективным методом для преодоления этого препятствия будет формирование идентифицирующей последовательности байтов, которая не может возникнуть ни в результате действия помехи, ни — с большой степенью вероятности — встретиться в самом массиве информации.

Такую последовательность часто называют сигнатурой и широко используют в "большом" программировании для идентификации форматов файлов. Длина сигнатуры зависит от того, что мы передаем, и в простейшем случае может состоять из двух-трех повторяющихся байтов: например, $АА, $АА, $АА. В более сложных вариантах сигнатура может представлять, например, осмысленное слово, если интерпретировать байты, как символы ASCII: "Begin" ($42, $65, $67, $69, $6Е). А, например, в упоминавшемся протоколе NMEA в качестве сигнатуры применяются названия сообщений (GPRMC, GPGGA и пр.).

Подробности
В UART/USART также поддерживается хитрый механизм защиты от сбоев, заключающихся в возникновении ложных старт-битов. Стоп-бит представляет собой уровень логической единицы и не исключена ситуация, когда в паузе передачи данных возникнет ложный старт-бит (уровень 0), после которого приемник "захочет" принять сразу целую последовательность. Это особенно актуально для полудуплексного протокола RS-485 (см. далее), в котором и туда и обратно данные передаются по одной линии. Чтобы гарантированно сбросить приемник перед передачей массива данных, передатчик выдает на линию длинную последовательность единиц (можно просто передать $FF). Тогда, если эти единицы попадут на конец ложного байта, то будет засчитан верный стоп-бит, если же старт-бит при передаче $FF попадет на стоп-бит ложного байта, то будет засчитана ошибка кадра. Она определяется битом FE (Frame Error), который содержится в регистре USR для UART и в регистре исзиАдля USART. Если вместо первого стоп-бита принятого байта модуль обнаруживает логический ноль, то бит FE оказывается установленным в единичное состояние (на самом деле в него просто копируется инвертированное значение первого стоп-бита). Заметим, что если линия RS-232 "зависнет" в состоянии логического нуля (низкого уровня напряжения на линии UART), то это может восприниматься устройством, как состояние "обрыва линии" — не очень удобный механизм, и в МК AVR он аппаратно не поддерживается.

Дополнительные возможности USART
При включении синхронного режима работы USART (это делается установкой бита UMSEL в регистре UCSRC в единичное состояние) вместо внутреннего источника частоты для тактирования сдвигового регистра используется третий вывод порта под названием ХСК (по каким-то причинам этот вывод в большинстве моделей совпадает с выводом ТО — для подключения внешнего источника импульсов TimerO). При этом генератор тактирующих импульсов USART попросту переключается на этот контакт, если он установлен на выход (режим ведущего), либо, если он установлен на вход, вообще отключается, и USART тактируется внешними импульсами на этом выводе (режим ведомого).



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru