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





Отметим, что вызывать эту процедуру предпочтительно в основном цикле программы — пока байт не поступит, контроллер будет "висеть" в ожидании. В основном цикле это ожидание будет перемежаться с событиями, вызывающими прерывания, а если вызвать процедуру incom из прерывания, то это гарантированно "повесит" контроллер, пока байт все-таки не придет (можно, правда, разрешить другие прерывания, но зачем необоснованно усложнять программу?). Гораздо проще дело обстоит с передачей, потому что там приходится всего лишь ожидать, пока передатчик UART не освободится. За это отвечает бит UDRE В ТОМ же регистре UCSRA ИЛИ USR (между прочим, один из немногих битов I/O-регистров, который по умолчанию установлен в единичное значение), что иллюстрирует листинг 13.4.

Out_com: /посылка байта из temp с ожиданием готовности
sbis UCSRA,UDRE /для Classic UCSRA заменить на USR
rjmp out_com
out UDR,temp /собственно посылка байта
ret /возврат из процедуры Out_com

Если посылается всего один байт, то вообще ожидать ничего не приходится: передатчик, скорее всего, сразу окажется в состоянии готовности. Если посылать несколько байтов подряд, то для каждого последующего UART "умрет" на время, зависящее от установленной скорости обмена (например, для скорости 9600 бит/с это порядка миллисекунды). Опять же в данном случае рекомендуется вызывать последовательность процедур Outcom из основного цикла, а не из прерывания, иначе это затормозит работу остальных прерываний, и некоторые из них могут потеряться.

Можно ничего не бояться потерять, если использовать прерывания UART. Такой способ более громоздкий, но в случае UART облегчается тем, что с ним связаны несколько прерываний (а не одно на все случаи жизни, как для SPI и TWI): "прием завершен" (RX Complete), "регистр данных пуст" (ТХ UDR Empty), а также "передача завершена" (ТХ Complete), о последнем далее будет сказано несколько слов отдельно. Вот как можно организовать описанную процедуру ожидания приема байта (команды) и посылки нескольких байтов отклика (примеры для "чистого" UART).
Сначала вы инициализируете прерывание "прием завершен" (для чего нужно установить бит RXCIE В регистре UCR). Возникновение этого прерывания означает, что в регистре данных UDR имеется принятый байт. Процедуру обработки этого прерывания иллюстрирует листинг 13.5.

Листинг 13.5
UART_RXC:
in temp,UDR /принятый байт — в переменной temp
cbi UCR,RXCIE /запрещаем прерывание "прием закончен"
<анализируем команду, • если это не та команда — опять разрешаем прерывание "прием закончен" и выходим из процедуры:
sbi UCR,RXCIE
reti
В противном случае готовим данные, самый первый посылаемый байт должен быть в переменной temp>
sbi UCR,UDRIE ,-разрешение прерывания "регистр данных пуст" reti

Далее у нас почти немедленно возникает прерывание "регистр данных пуст". Обработчик этого прерывания посылает байт, содержащийся в переменной temp, и готовит данные для следующей посылки (листинг 13.6).
Листинг 13.6
UART_DRE:
out UDR,temp /посылаем байт
cbi UCR,UDRIE /запрещаем прерывание "регистр данных пуст"
<готовим данные, следующий•байт — в temp. Если же был отправлен последний нужный байт, то опять разрешаем прерывание "прием закончен" и далее выходим из процедуры, иначе выполняем следующий оператор:
sbi UCR,UDRIE ,-разрешаем прерывание "регистр данных пуст"
reti

Для USART вместо UCR В текст примеров следует подставить UCSRB. Обратим внимание на то, что после обработки первого прерывания переменная temp здесь может содержать подготовленный для отправки байт и не должна в промежутках между прерываниями использоваться еще где-то. В противном случае подготовленные данные необходимо сохранять, например, в стеке, или отвести для этого специальный регистр промежуточного хранения данных.

Отметим также, что если прерывание "прием завершен" (RX Complete)
инициализировано, то в нем должно быть выполнено, по крайней мере, чтение данных из UDR— только эта операция сбрасывает флаг RXC в регистре UCSRA, сигнализирующий об окончании приема. Если в прерывании "прием завершен" не прочесть данные, то немедленно по выходу из обработчика оно возникнет заново. В регистре статуса UCSRA, кроме битов готовности передатчика и приемника, имеются флаги ошибок: FE— ошибка кадра, РЕ — ошибка четности, о которых далее, и DOR — ошибка переполнения, возникает, если предыдущий принятый байт не был считан. Если их требуется анализировать, то значение регистра UCSRA следует прочесть раньше, чем данные из регистра UCR, иначе он будет испорчен (то же относится и к девятому биту RXB8, см. далее). В модуле "чистого" UART все немного иначе: бит ошибки переполнения OR (OverRun) в регистре USR обновляется после чтения данных, и если он оказался установлен, то это означает, что последний принятый байт остался в сдвиговом регистре и будет потерян.
Поэтому его необходимо анализировать после чтения данных. Кроме всего прочего, это означает, что при пропусках в обмене в случае UART в регистре данных окажется первый байт из пропущенных, а для USART — последний. Заметьте, что прерывание "передача завершена" (ТХ complete) здесь не используется — это чисто "аппаратное дело", которое, вообще говоря, программиста не интересует, ему важно то, что находится в регистре данных UDR. Однако знание того, что передача на самом деле закончилась, может быть важно в некоторых случаях — например, при управлении приемопередатчиками RS-485 (см. долее в этой главе) или при вызове режимов энергосбережения (см. главу 14). Альтернативный способ обнаружения того, что передат ча реально завершилась, заключается в отслеживании состояния бита тхс в регистре UCSRA (USR) — когда регистр сдвига UART освобождается, этот бит устанавливается в единичное состояние, и его потом следует сбросить записью в него логической единицы (прерывание сбрасывает его аппаратно).



     
 

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