Исторически параллельный интерфейс был введен в персональный
компьютер (ПК) для подключения принтера (отсюда и аббревиатура LPT - Line
printer - построчный принтер). Однако впоследствии параллельный интерфейс
стал использоваться для подключения других периферийных устройств - сканеров,
дисководов типа Zip и ряда других устройств. Базовая разновидность порта
позволяет передавать данные только в одном направлении (от ПК к ПУ), однако
позднее был разработан ряд стандартов двунаправленной передачи данных.
Адаптер параллельного интерфейса представляет собой набор
регистров, расположенных в адресном пространстве устройств ввода/вывода.
Количество регистров зависит от типа порта, однако три из них стандартны
и присутствуют всегда - регистр данных, регистр состояния и регистр управления.
Адреса регистров отсчитываются от базового, стандартные значения которого
3BCh, 378h, 278h. Узнать количество установленных портов в компьютере и их базовые
адреса можно просканировав область данных BIOS по адресам 0:408h для LPT1,
0:40Ah для LPT2, 0:40Ch для LPT3 и 0:40Eh для LPT4. Если по данным адресам содержится
слово (2 байта) с ненулевым значением, то это и есть базовый адрес порта. Если слово
содержит нулевое значение - порт не установлен. BIOS не поддерживает больше 4 LPT-портов.
Порт может использовать аппаратное прерывание (IRQ7 или
IRQ9). Многие современные системы позволяют изменять режим работы порта,
его адрес и IRQ из настроек BIOS Setup. Например, в AWARD BIOS имеется
раздел Integrated Peripherals, позволяющий настраивать режим, адрес и IRQ
порта.
LPT порт имеет внешнюю 8-битную шину данных, 5-битную
шину сигналов состояния и 4-х битную шину управляющих сигналов.
При начальной загрузке BIOS пытается обнаружить параллельный
порт, причем делает это примитивным и не всегда корректным образом - по
возможным базовым адресам портов передается тестовый байт, состоящий из
чередующегося набора нулей и единиц (55h или AAh), затем производится чтение
по тому же адресу, и если прочитанный байт совпал с записанным, то считается,
что по данному адресу найден LPT порт. Определить адрес порта LPT4 BIOS
не может. Для работы с ПУ в BIOS предусмотрено прерывание INT 17h, предоставляющее
возможность передавать данные (побайтно), инициализировать ПУ и получать
информацию о его состоянии.
Понятие Centronics относится к набору сигналов, протоколу обмена и разъему, устанавливаемому в принтерах. Большинство современных принтеров совместимы с интерфейсом Centronics. Назначение сигналов и контакты разъема ПУ, на который они выведены приведены в таблице 1.1
Сигнал | Т | Конт. | Напр. | Назначение |
Strobe | 0 | 1 | i | Строб данных. Передается ЭВМ, данные фиксируются по низкому уровню сигнала. |
D0 ... D7 | 1 | 2-9 | i | Линии данных. D0 - младший бит. |
Ack | 0 | 10 | o | Acknowledge - импульс подтверждения приема байта (запрос на прием следующего). Может использоваться для формирования прерывания. |
Busy | 1 | 11 | o | Занят. Прием данных возможен только при низком уровне сигнала |
PE | 1 | 12 | o | "1" сигнализирует о конце бумаги |
Select | 1 | 13 | o | "1" сигнализирует о включении принтера (ГП - готовность приемника), обычно +5 В через резистор от источника питания ПУ) |
Auto LF | 0 | 14 | i | Автоматический перевод строки. Если "0", то ПУ при получении символа CR (перевод каретки) выполняет функцию LF - перевод строки |
Error | 0 | 32 | o | Ошибка ПУ (off-line, нет бумаги, нет тонера, внутренняя ошибка) |
Init | 0 | 31 | i | Инициализация (переход к началу строки, сброс всех параметров на значения по умолчанию) |
Slct In | 0 | 36 | i | Выбор принтера. При "1" принтер не воспринимает остальные сигналы интерфейса |
GND | 33 | - | Общий провод |
Сигнал Auto LF практически не применяется, но его неправильное значение приводит к тому, что принтер либо делает пропуски строк, либо печатает строки поверх друг друга, либо дублирует строки при печати в два прохода.
Отечественным аналогом интерфейса Centronics является
ИРПР-М. Кроме него существует интерфейс ИРПР (устаревший), который отличается
протоколом обмена, отсутствием сигнала "Error" и инверсией линий данных.
Кроме того, ко всем входным линиям ИРПР подключены пары согласующих резисторов:
220 Ом к +5 В и 330 Ом к общему проводу. Это перегружает большинство интерфейсных
адаптеров современных ПК, поэтому при адаптации такого принтера необходимо
удалить эти резисторы.
Протокол обмена по интерфейсу Centronics приведен на рис.
1.1
Передача начинается с проверки источником сигнала "Error". Если он установлен, то обмен не производится. Затем проверяется состояние сигнала "Busy". Если он равен "0", то источник приступает к передаче байта данных. Для передачи байта источник выставляет на линии D0-D7 байт данных и выдает сигнал Strobe. Приемник по сигналу Strobe# (здесь и далее по тексту значок "#" после названия сигнала является признаком того, что сигнал имеет низкий активный уровень) читает данные с шины данных и выставляет сигнал Busy на время его обработки. По окончании обработки приемник выдает сигнал ACK# и снимает сигнал Busy. Если в течение длительного времени (6 - 12 сек) источник не получает ACK#, то он принимает решение о ошибке "тайм-аут" (time-out) устройства. Если после приема байта приемник по какой - либо причине не готов принимать данные, то он не снимает сигнал Busy. При программной реализации обмена по указанному протоколу желательно ограничить время ожидания снятия Busy (обычно 30 - 45 сек), иначе возможно зависание программы.
Стандартный параллельный порт называется SPP (Standard Parallel Port - Стандартный Параллельный Порт). SPP порт является однонаправленным, на его базе программно реализуется протокол обмена Centronics. Порт обеспечивает возможность генерации IRQ по импульсу ACK# на входе. Сигналы порта выводятся на стандартный разъем DB-25S (розетка), который размещен непосредственно на плате адаптера или соединяется с ним плоским шлейфом (в случае, если адаптер интегрирован с материнской платой). Названия сигналов соответствуют названиям сигналов интерфейса Centronics (таблица 1.2).
В таблице 1.2 I/O - направление передачи: I - вход; O - выход; O(I) - выход, состояние которого может быть считано при определенных условиях, O/I - выходные линии, состояние которых читается при чтении из соответствующих регистров порта.
Разъем и шлейф стандартного LPT порта
DB-25S | шлейфа | I/O | Сигнал | DB-25S | шлейфа | I/O | Сигнал | |
1 | 1 | O/I | Strobe# | 10 | 19 | I* | ACK# | |
2 | 3 | O(I) | D0 | 11 | 21 | I | Busy | |
3 | 5 | O(I) | D1 | 12 | 23 | I | PE | |
4 | 7 | O(I) | D2 | 13 | 25 | I | Select | |
5 | 9 | O(I) | D3 | 14 | 2 | O/I | Auto LF# | |
6 | 11 | O(I) | D4 | 15 | 4 | I | Error# | |
7 | 13 | O(I) | D5 | 16 | 6 | O/I | Init# | |
8 | 15 | O(I) | D6 | 17 | 8 | O/I | Select In# | |
9 | 17 | O(I) | D7 | 18 - 25 | 16,18,20,22,24,26 | - | GND |
В качестве недостатков стандартного LPT порта (SPP) следует отметить невысокую скорость передачи данных (100 - 150 КБ/сек), загрузку процессора при передаче данных, невозможность двунаправленного побайтного обмена. Существует "радиолюбительская" методика двунаправленного обмена, которая состоит в том, что для ввода данных на линии D0-D7 выставляют "1", а в качестве передатчика используют микросхемы с открытым коллектором, которые при открытом транзисторе могут "подсаживать" напряжение логической единицы до уровня порядка 1.5 - 1.7 В. Ток ограничен на уровне 30 мА. Как очевидно из уровней сигналов, они не соответствуют уровням ТТЛ, поэтому многие порты не работают в таком режиме или работают нестабильно. Кроме того, такой способ может быть опасен для адаптера порта, который будет работать с предельными для него токами.
Стандарт на параллельный интерфейс IEEE 1284, принятый в 1994 году, определяет термины SPP, ЕРР и ЕСР. Стандарт определяет 5 режимов обмена данными, метод согласования режима, физический и электрический интерфейсы. Согласно IEEE 1284, возможны следующие режимы обмена данными через параллельный порт:
Compatibility Mode - однонаправленный (вывод) по протоколу Centronics. Этот режим соответствует стандартному (традиционному) порту SPP
Nibble Mode - ввод байта в два цикла (по 4 бита), используя для ввода линии состояния. Этот режим обмена может использоваться на любых адаптерах.
Byte Mode - ввод байта целиком, используя для приема линии данных. Этот режим работает только на портах, допускающих чтение выходных данных (Bi -Directional или PS/2 Type 1).
ЕРР (Enhanced Parallel Port) Mode - двунаправленный обмен данными, при котором управляющие сигналы интерфейса генерируются аппаратно во время цикла обращения к порту (чтения или записи в порт). Эффективен при работе с устройствами внешней памяти, адаптерами локальных сетей.
ЕСР (Extended Capability Port) Mode - двунаправленный обмен с возможностью аппаратного сжатия данных по методу RLE (Run Length Encoding), использования FIFO-буферов и DMA. Управляющие сигналы интерфейса генерируются аппаратно. Эффективен для принтеров и сканеров.
В современных АТ - машинах с LPT-портом на системной плате
режим порта - SPP, ЕРР, ЕСР или их комбинация задается в BIOS Setup. Режим
Compatibility Mode полностью соответствует SPP и часто установлен по умолчанию.
Все остальные режимы расширяют функциональные возможности интерфейса и
повышают его производительность. Кроме того, стандарт регламентирует способ
согласования режима, доступного как ПК, так и периферийному устройству.
Стандарт IEEE 1284 определяет физические характеристики приемников и передатчиков сигналов. IEEE 1284 предусматривает два уровня интерфейсной совместимости: первый уровень - для устройств, не требующих высоких скоростей обмена, но использующих возможность смены направления передачи данных; уровень два - устройства, работающие в расширенных режимах, с высокими скоростями и длинными кабелями.
Требования к передатчикам приведены в таблице 1.3, для
приемников - в таблице 1.4.
Требования стандарта IEEE 1284 к передатчикам
Требование | Значение |
Диапазон уровней сигналов без нагрузки | -0.5...+5.5 В |
Уровень "1" при токе нагрузки 14 мА, не менее | +2.4 В |
Уровень "0" при токе нагрузки 14 мА, не более | +0.4 В |
Выходной импеданс, измеренный на разъеме | 50+ 5 Ом |
Скорость нарастания/спада импульса (должен находиться в указанных пределах) | В/нс |
Требования стандарта IEEE 1284 к приемникам
Требование | Значение |
Допустимые пиковые значения сигналов, выдерживаемые без разрушения и ошибок в работе, В | -2.0 ... +7.0 |
Порог срабатывания "1", не выше, В | 2.0 |
Порог срабатывания "0", не ниже, В | 0.8 |
Гистерезис приемника (триггер Шмитта) (пределы), В | 0.2 - 1.2 |
Входной ток (втекающий и вытекающий), не более, мкА | 20 |
Входная емкость, не более, пФ | 50 |
Примечание: Входные линии соединяются с шиной питания резистором 1.2 кОм.
Стандарт IEEE 1284 определяет три типа используемых разъемов: А (DB-25), B (Centronics-36), C (новый малогабаритный 36-контактный разъем).
Интерфейсные кабели могут иметь от 18 до 25 проводников (в зависимости от числа проводников GND). Не предъявляется жестких требований к экранировке и прочим параметрам, однако, такие кабели могут работать только на низких скоростях при длине не более 2 метров. Стандарт IEEE 1284 для кабелей:
Работа с параллельным портом на низком уровне (т.е. на уровне прямого обращения к контроллеру порта) применяется при решении различного круга задач по обмену информацией с нестандартными устройствами, для написания драйверов принтеров и ряда других задач. Прямая работа с контроллером позволяет реализовать любой протокол обмена с устройством и использовать линии порта по своему усмотрению.
Контроллер порта расположен в адресном пространстве устройств ввода-вывода и обращение к нему производится посредством команд IN и OUT ассемблера. Информацию о портах LPT1 - LPT3 можно получить, прочитав переменные BIOS, приведенные в табл. 1.5.
Переменные BIOS для LPT портов
Имя порта | Адрес в BIOS | Тип переменной | Описание |
LPT1 | 0040:0008h | Word | Базовый адрес порта LPT1. Если переменная равна 0, то порт LPT1 не найден |
0040:0078h | Byte | Константа, задающая тайм-аут | |
LPT2 | 0040:000Ah | Word | Базовый адрес порта LPT2. Если переменная равна 0, то порт LPT2 не найден |
0040:0079h | Byte | Константа, задающая тайм-аут | |
LPT3 | 0040:000Ch | Word | Базовый адрес порта LPT3. Если переменная равна 0, то порт LPT3 не найден |
0040:007Ah | Byte | Константа, задающая тайм-аут | |
LPT4 | 0040:000Eh | Word | Базовый адрес порта LPT4. Если переменная равна 0, то порт LPT4 не найден |
0040:007Bh | Byte | Константа, задающая тайм-аут |
push dx
mov ax, 40h
mov es, ax ; в es - сегмент = 0040h
mov dx, es:[08] ; dx = базовый адрес порта LPT1
mov lpt1_adr, dx ; запомнили адрес порта LPT1 в переменной lpt1_adr
pop dx
Переменная lpt1_adr имеет тип word и должна быть определена
в сегменте данных.
Стандартный порт имеет три 8-битных регистра, расположенных
по соседним адресам, начиная с базового (Base) адреса - табл. 1.6.
Адрес | Название | W-R |
Base+0 | Data Register - регистр данных (DR) | W/R |
Base+1 | Status register - регистр состояния (SR) | R |
Base+2 | Control Register - регистр управления (CR) | W/R |
где W-R - доступные операции (W - запись, R - чтение,
W/R - чтение/запись)
1.5.1.Регистр данных.Записанные в этот регистр данные выводятся на выходные линии интерфейса
D0-D7. Результат чтения этого регистра зависит от схемотехники адаптера
и соответствуют либо записанным ранее данным, либо сигналам на линиях D0-D7,
что не всегда одно и тоже (на этом принципе и базируется "радиолюбительский"
метод двунаправленного обмена, основанный на "подсаживании уровней "1"
на выходе порта до уровня "0"). При стандартном включении справедлив первый
вариант - читаемые данные равны ранее записанным.
1.5.2. Регистр состояния.Представляет собой 5-ти битный порт ввода, на который заведены сигналы
от внешнего устройства. Допускает только чтение. Назначение битов регистра
состояния приведены в таблице 1.7.
Биты регистра состояния
Бит | Вес | Название | Назначение |
7 | 128 | BUSY | Инверсное отображение состояния линии Busy (11). При низком уровне на линии 11 (Busy) - бит равен "1" - ПУ готово к приему очередного байта |
6 | 64 | ACK | Отображение состояния линии ACK#
(10). "0"-подтверждение приема, "1"-обычное состояние |
5 | 32 | PE | Отображение состояния линии Paper
End (12). "0" - норма, "1" - в ПУ нет бумаги |
4 | 16 | SLCT OUT | Отображение состояния линии Select
(13). "0" - ПУ не выбрано, "1" - ПУ выбрано |
3 | 8 | Error инв. | Отображение состояния линии Error
(15). "0" - ошибка ПУ, "1" - обычное состояние |
2 | 4 | PIRQ | Флаг прерывания по ACK# (только PS/2). Обнуляется, если ACK# вызвал аппаратное прерывание. "1" - после сброса или после чтения регистра состояния |
1-0 | 4-1 | -- | Не используются (резерв) |
1.5.3. Регистр управления.Регистр управления представляет собой 4-х битный порт вывода, допускающий чтение и запись. Биты 0,1,3 инвертируются, т.е. "1" в данных битах регистра управления соответствует "0" на соответствующих линиях порта. Назначение бит регистра управления приведены в таблице 1.8. Бит 5 используется только портами PS/2.
Биты регистра управления
Бит | Вес | Название | Назначение |
7 | 128 | - | Резерв |
6 | 64 | - | Резерв |
5 | 32 | Direction | Бит управления направлением порта
PS/2. "1" - режим ввода, "0" - режим вывода |
4 | 16 | AckIntEn | Бит управления генерацией прерывания
по ACK# "1" - разрешить прерывание по спаду ACK# (10) |
3 | 8 | SLCT IN | Управление линией SLCT IN# (17). "1" - работа принтера разрешена. |
2 | 4 | INIT | Управление линией INIT# (16). "1" - обычное состояние, "0" - аппаратный сброс ПУ |
1 | 2 | Auto LF | Управление линией Auto LF# (14). "1" - включить режим "Auto LF", "0" - обычное сост. |
0 | 1 | Strobe | Управление линией Strobe# (1). "1" - стробирование данных, "0" - обычное сост. |
1.5.4. Пример программы для передачи строки данных на низком уровне.
; Пример разработан на TASM.Коротко о работе программы. В начале программы описан сегмент данных, содержащий выводимую ASCIIZ строку (строку, завершающуюся нулем) и переменную типа Lpt1_adr типа Word для хранения базового адреса порта Lpt1.
DATA Segment byte public 'DATA' ; Описываем сегмент
; данных
String DB 'Test printer !!!',0Dh, 0Ah,0 ; выводимая строка
Lpt1_adr DW 0 ; Переменная для хранения базового адреса LPT1DATA ENDS ; конец сегмента данных
; Сегмент кода - в нем расположим саму программу
CODE Segment byte public 'CODE'
ASSUME CS:CODE,DS:DATA,ES:DATASTART: ; Начало программы
mov ax, data ; установим ds на сегмент данных
mov ds, ax
push dx
mov ax, 40h
mov es, ax ; в es - сегмент = 0040h
mov dx, es:[08] ; dx = базовый адрес порта lpt1
mov lpt1_adr, dx ; запомнили адрес порта lpt1 в переменной lpt1_adr
pop dx
LOOP1: ; цикл печати строки
mov ah, ds:[bx] ; прочитали очередной символ строки
cmp ah, 0h ; это конец строки ?
je exit ; да, выход
call out_byte ; нет, печатаем его
inc bx ; на следующий символ
jmp loop1 ; повторяем, пока не достигли конца строки
EXIT: ; завершение программы
mov ax,4C00h ; завершить с кодом возврата 0
int 21h;**** процедуры и функции программы ****
OUT_BYTE: ; процедура вывода символа из ah на принтер с ожиданием
push dx
LOOP2:
mov dx, lpt1_adr
inc dx ; адрес регистра состояния (lpt1_adr+1)
in al, dx ; Читаем регистр состояния
test al, 80h ; Проверим сигнал BUSY (<1> - принтер готов)
jz loop2 ; если нет, то повторим опрос
dec dx ; адрес регистра данных (lpt1_adr)
mov al, ah ; Загрузка передаваемого байта в AL
out dx, al ; Запись байта в регистр данных
inc dx
inc dx ; адрес регистра управления (lpt1_adr+2)
in al, dx ; Читаем регистр управления
; Формируем строб
and al, 11111110b ; Бит 0 (Strobe):=0
out dx, al ; Запись в регистр управления
or al, 00000001b ; Бит 0 (Strobe):=1
out dx, al ; Запись в регистр управления
and al, 11111110b ; Бит 0 (Strobe):=0
out dx, al ; Запись в регистр управления
pop dx
ret ; выход в основную программу
code ends
end start
Как очевидно из рассмотренного в п.п. 1.5.4 примера работы
с портом на низком уровне, написание программы сложно и невозможно перехватить
вывод информации в порт. Это означает, что невозможно разработать программу
- драйвер для перекодировки символов, передаваемых в порт или для реализации
нестандартного протокола обмена. Качественно иной подход - использование
программного прерывания BIOS INT 17h. Оно предоставляет программисту набор
стандартных функций для работы с ПУ: передать байт, сброс ПУ и опрос состояния
ПУ. Данное прерывание может быть перехвачено или замещено программой -
драйвером. Вниманию программистов: не все программы, выводящие информацию
на ПУ, работают через INT 17h. Кроме того, при перекодировке символов нельзя
перекодировать символы, входящие в состав команд языка управления ПУ.
Параметры вызова функций INT 17h приведены в таблице
1.9.
Функции INT 17h
Функция | Регистры при вызове | Регистры при возврате |
Вывод символа по протоколу Centronics | ah = 00h al = выводимый символ dx = номер принтера (0 - 3) | AH - слово состояния |
Инициализация принтера | ah = 01h dx = номер принтера (0 - 3) | AH - слово состояния |
Принтер - получить состояние | ah = 01h dx = номер принтера (0 - 3) | AH - слово состояния |
В качестве примера рассмотрим ту же программу, что и в примере по прямой работе с LPT портом.
; Описываем сегмент данных, в котором расположим все данные программыDATA Segment byte public 'DATA'
String DB 'Тест принтера !!!',0 ; выводимая строка
Error DB 'Ошибка: принтер не готов !!!!$' ; сообщение об
; ошибке
DATA ENDS ; конец сегмента данных
; Сегмент кода - в нем расположим саму программу
CODE Segment byte public 'CODE'
; Зададим соответствие регистров для использования по умолчанию
ASSUME CS:CODE, DS:DATA, ES:DATA
START: ; Начало программы
mov ax, data ; установим ds на сегмент данных
mov ds, ax
mov dx, 0 ; принтер на lpt1
mov ah, 2 ; функция int 17 "получить состояние принтера"
int 17h ; проверим состояние принтера
test ah,80h ; принтер готов ?
jz err_exit ; если нет, то выход с сообщением о ошибке
mov bx, offset string ; смещение на выводимую строку
LOOP1: ; Цикл печати строки
mov al, ds:[bx] ; прочитали очередной символ строки
cmp al, 0h ; это конец строки ??
je exit ; да, выходим
call out_byte ; нет, печатаем его
inc bx ; на следующий символ
jmp loop1 ; повторим
ERR_EXIT: ; Выход по ошибке
mov dx, offset error ; вывод строки на экран
mov ah, 9
int 21h
mov ax, 4c00h ; завершить с кодом возврата 1
int 21h
EXIT: ; Нормальное завершение
mov al, 0ah ; дадим перевод каретки
call out_byte
mov ax,4c00h ; завершить с кодом возврата 0
int 21h
; **** Процедуры и функции программы ****
OUT_Byte: ; Процедура вывода символа из AL на принтер с
; ожиданием
push ax ; процедура должна быть рентабельна
push dx
LOOP2:
mov dx, 0
mov ah, 2
int 17h ; проверим состояние принтера
test ah,80h ; готов ?
jz loop2 ; если нет, то повторим опрос
mov ah, 0
int 17h ; выводим символ
pop dx
pop ax
ret ; выход в основную программу
CODE ENDS ; Завершение кодового сегмента
END START ; Конец программы
Проблема двунаправленного обмена возникла при появлении устройств типа накопителя ZIP, которые удобно подключать к LPT порту. Существует несколько стандартных решений, одобренных IEEE 1284. Рассмотрим два наиболее простых. В описании двунаправленного обмена применяются следующие термины:
Хост (Host) - ПК с LPT портом
Прямой канал (передача в прямом направлении) - канал (передача)
от хоста к ПУ; обратный канал - канал ввода данных в Хост от ПУ
Режим полубайтного обмена (Nibble Mode) наиболее универсален и может использоваться на любом стандартном (SPP) порту. SPP порт имеет 5 линий ввода, используемых для ввода сигналов состояния ПУ. Их можно использовать для ввода данных за два прима по 4 бита (Nibble - полубайт). Назначение и название сигналов, используемых в Nibble Mode приведены в таблице
Конт. | SPP | NM | I/O | Назначение |
14 | Auto Feed# | HostBusy | O | Сигнал квитирования. "0" - готовность к приему тетрады "1"-подтверждение приема тетрады |
17 | SLCT IN# | - | O | "1" - признак обмена по IEEE 1284 "0" - обмен по SPP |
10 | ACK# | PtrClk | I | "0" - действительность тетрады "1" - ответ на HostBusy |
11 | BUSY | - | I | Прием битов 3, 7 |
12 | PE | - | I | Прием битов 2, 6 |
13 | SELECT | - | I | Прием битов 1, 5 |
15 | ERROR# | - | I | Прием битов 0, 4 |
Рис. 1.2.
Временные диаграммы обмена приведены на рис. 1.2.
Прием в режиме Nibble Mode производится следующим образом: ПК сигнализирует о готовности к приему низким уровнем HostBusy. ПУ в ответ выставляет на линии младшую тетраду данных и сигнализирует о ее действительности низким уровнем PtrClk. ПК в ответ устанавливает высокий уровень HostBusy, сигнализируя о занятости приемом и обработкой. ПУ отвечает на это высоким уровнем PtrClk. Затем все перечисленные действия повторяются для старшей тетрады данных.
Nibble Mode универсален и гарантированно работает на любом
порте любого типа (SPP, EPP, ECP), поэтому применяется в устройствах типа
накопителя ZIP как режим по умолчанию. Однако, прием данных в Nibble Mode
сильно загружает процессор, максимальная скорость обмена, как правило,
не превышает 50 - 60 кбайт/с. Обмен с ПУ получается aсимметричным - скорость
приема будет в два раза меньше скорости передачи.
Протокол EPP (улучшенный параллельный порт) был разработан задолго до принятия IEEE 1284 и предназначен для повышения производительности обмена данными по параллельному порту.
Протокол EPP обеспечивает 4 типа циклов обмена:
Конт. | SPP | EPP | I/O | Назначение |
1 | Strobe# | WRITE# | O | "0" - признак цикла записи, "1" - признак цикла чтения |
14 | Auto Feed# | DATASTB# | O | Строб данных. |
17 | SLCT IN# | ADDRSTB# | O | Адреса данных. |
16 | INIT# | RESET# | O | Сброс ПУ (по "0") |
10 | ACK# | INTR# | I | Прерывание от ПУ |
11 | BUSY | WAIT# | I | Сигнал квитирования. "0" - разрешает начало цикла "1" - разрешает завершение цикла |
12 | PE | ACKDATAREQ | I | Используется по усмотрению разработчика |
13 | SELECT | XFLAG | I | ---//--- |
15 | ERROR# | DATAAVAIL# | I | ---//--- |
По сравнению с SPP, EPP порт имеет расширенный набор регистров
- табл. 1.12
Имя регистра | Смещение | Режим | R/W | Описание |
SPP Data Port | Base+0 | SPP/EPP | W | Регистр данных SPP |
SPP Status Port | Base+1 | SPP/EPP | R | Регистр состояния SPP |
SPP Control Port | Base+2 | SPP/EPP | W | Регистр управления SPP |
EPP Address Port | Base+3 | EPP | R/W | Регистр адреса EPP |
EPP Data Port | Base+4 | EPP | R/W | Регистр данных EPP |
? | Base+5 ..+7 | EPP | ? | Может использоваться в некоторых контроллерах для 16/32 битных операций ввода/вывода |
Для передачи байта в качестве адреса или данных необходимо записать его в соответствующий регистр EPP порт, для чтения - прочитать.
Наличие сигнала WAIT# очень важно - при помощи этого сигнала периферийное устройство может подстраивать скорость обмена под свое быстродействие. Кроме того, протокол подстраивается под длину интерфейсного кабеля - вносимые за счет длины кабеля задержки просто приведут к удлинению циклов обмена. В данном сигнале наблюдается различие в стандартах EPP порта: EPP порт, удовлетворяющий IEEE 1284 поддерживает WAIT#, а некоторые старые разновидности портов - нет. Они меняют состояние стробирующих сигналов DATASTB# и ADDRSTB# независимо от WAIT#, как следствие периферийное устройство не может подстраивать скорость обмена. Такая спецификация называется EPP 1.7.
Ввиду того, что обмен по EPP идет в течение одного процессорного цикла обмена, необходимо исключить возможность "зависания" процессора в таком цикле обмена за счет того, что устройство долгое время не отвечает. Повисание исключено, так как через 15 мкс любой цикл обмена завершается принудительно.
Временные диаграммы записи приведены на рис. 1.3
Для записи данных в порт программа выполняет цикл записи
(IO WR) в порт EPP Data. Адаптер при этом устанавливает Write в низкий
уровень и помещает данные на линии порта. Затем адаптер при низком уровне
Wait устанавливает строб данных и ждет подтверждения от ПУ (перевода Wait
в высокий уровень). По приходу Wait, адаптер снимает строб данных - на
этом внешний цикл обмена завершается. Затем завершается процессорный цикл
ввода-вывода (снятие IO WR). Спустя некоторое время ПУ устанавливает низкий
уровень Wait, указывая на возможность нового цикла обмена.
Рис. 1.3
Рис. 1.4
Временные диаграммы процесса чтения приведены на рис.
1.4 и отличаются типом процессорного цикла ввода-вывода и стробом.
ECP - Extended Parallel Port - параллельный порт с расширенными возможностями. Предложен фирмами Hewlett Packard и Microsoft для связи с периферией типа принтеров и сканеров. Обеспечивает высокопроизводительный двунаправленный обмен данными с возможностью применения RLE компрессии (RLE - Run-Length Encoding - методика сжатия длинных повторяющихся последовательностей байт). Допускает буферизацию FIFO для прямого и обратного канала, использование DMA и программного ввода-вывода.
Протокол ECP обеспечивает передачу в обоих направлениях по двум типам циклов: циклу записи и чтения данных; циклу записи и чтения команд. Командные циклы, в свою очередь, подразделяются на два типа: передачу канальных адресов и счетчика RCL (Run-Length Counter). Канальная адресация ECP применяется для адресации множества логических устройств, входящих в одно физическое. Например, комбинированное устройство типа принтер/факс/модем допускает одновременную печать и прием факса - драйвер при работе с ним адресуется к другому логическому каналу одного и того же порта.
ECP аппаратно генерирует внешние протокольные сигналы. Обмен по ECP можно условно разделить на два независимых процесса, связанных через FIFO буфер: обмен программы с буфером FIFO (программным обменом или через DMA) и ПУ с буфером FIFO (аппаратно через адаптер ECP).
Сигналы порта в ECP режиме приведены в таблице 1.13.
Сигналы порта EPP
Конт. | SPP | ECP | I/O | Назначение |
1 | Strobe# | HostClk | O | Используется в паре с PeriphAck для передачи в прямом направлении. |
14 | Auto Feed# | HostAck | O | Индицирует тип команда/данные при передаче в прямом направлении. Используется в паре с PeriphClk для передачи в обратном направлении. |
17 | SLCT IN# | - | O | "1" - признак обмена по IEEE 1284 "0" - обмен по SPP |
16 | INIT# | Reverse Request # | O | "0" - передача в обратном направлении "1" - передача в прямом направлении |
10 | ACK# | PeriphClk | I | Используется в паре с HostAck для передачи в обратном направлении. |
11 | BUSY | PeriphAck | I | Используется в паре HostClk с для передачи в обратном направлении. Индицирует тип команда/данные при передаче в обратном направлении. |
12 | PE | Ack Reverse # | I | Переводится в "0" в качестве подтверждения Reverse Request # |
13 | SELECT | X Flag | I | Флаг расширяемости |
15 | ERROR# | Periph Request # | I | Устанавливается ПУ в для указания на доступность обратного канала |
2...9 | Data[0:7] | Data[0:7] | I/O | Двунаправленный канал данных |
Временные диаграммы рис. 1.5 показывают прямую передачу данных.
Для передачи байта данных ПК помещает данные на шину канала
обмена, устанавливает HostAck в соответствии с типом передаваемого байта
(данные или команда), затем устанавливает низкий уровень HostClk, указывая
на действительность данных. ПУ отвечает установкой "1" на PeriphAck, ПК
в ответ устанавливает высокий уровень HostClk.
Рис. 1.5
Этот перепад может использоваться для фиксации байта в
ПУ. После обработки принятого байта ПУ устанавливает низкий уровень PeriphAck,
указывая на готовность к приему следующего байта. На рис. 1.5 показана
передача данных и команды. Передача в обратном направлении аналогична,
только дополнительно используется пара сигналов Ack Reverse # и Reverse
Request # для смены направления обмена; изменяются сигналы квитирования
(см. таблицу 1.13).
Последовательная передача данных может осуществляться в синхронном и асинхронном режимах. При асинхронной передаче каждому байту данных предшествует старт-бит, за ним следуют биты данных, после них может передаваться бит паритета (четности) и, в завершение посылки, передается стоп-бит, гарантирующий определенную выдержку времени между соседними посылками (рис. 3.1). Старт-бит следующей посылки может передаваться в любой момент времени, начиная с момента окончания стоп-бита предыдущей посылки, таким образом, между передачами могут быть паузы произвольной (и неограниченной) длительности.
Старт-бит позволяет организовать простую синхронизацию приемника по сигналу от передатчика. При этом подразумевается, что приемник и передатчик работают на одной и той же скорости обмена (т.е. имеют одну и ту же тактовую частоту), измеряемую количеством передаваемых бит в секунду. Внутренний генератор синхронизации приемника содержит счетчик-делитель частоты, обнуляемый в момент начала старт-бита от передатчика. Этот счетчик формирует внутренние стробы Fc, по которым приемник фиксирует принимаемые биты. В идеальном случае, эти внутренние стробы должны приходиться на середину битовых интервалов, однако, из-за разностей скоростей приемника и передатчика возникает накапливающееся рассогласование. Для безошибочного приема 8 бит данных, 1 бита паритета и стоп-бита предельное рассогласование не может превышать 5% на бит (в идеале, строб приходится на середину бита, при отклонении 50% мы примем бит с ошибкой, 50% / 10 бит = 5%). Очевидно, что чем больше скорость передачи, тем строже требования к синхронизации приемника и передатчика, кроме того, с ростом скорости обмена усиливается влияние фронтов импульсов.
Для асинхронного режима принят ряд стандартных скоростей обмена: 50, 75, 110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600 и 115200 бит/сек.
Количество бит данных задается программно и может составлять 5, 6, 7 и 8 бит. Количество стоп-бит может быть 1, 1.5, 2 (по длине). Бит паритета может отсутствовать.
Таким образом, для установления связи при асинхронном режиме необходимо установить одинаковыми следующие параметры приемника и передатчика: скорость обмена, количество бит данных, наличие бита паритета, тип паритета (четность - нечетность), длину стоп-бита.
Асинхронный обмен в ПК реализуется с помощью COM порта с использованием протокола RS-232C.
Синхронный режим передачи данных предполагает постоянную активность канала связи. Посылка начинается с передачи синхробайта, за которым вплотную следует последовательность передаваемых бит. Если у передатчика нет данных для передачи, то он заполняет паузу непрерывной передачей старт-бит. Очевидно, что при синхронном обмене можно добиться больших скоростей обмена, т.к. не требуется предавать старт-бит, стоп-бит, бит паритета (в асинхронном на каждые 8 бит данных приходится не 3-4 служебных бита). При синхронном обмене необходима внешняя синхронизация, так как передается большой массив данных. При синхронизации только в начале передачи блока данных даже небольшая разность частот приведет к появлению быстро накапливающийся ошибке.
Внешняя синхронизация может обеспечиваться как за счет
использования отдельной линии для передачи сигнала синхронизации, так и
за счет применения самосинхронизирующихся методов кодирования данных (манчестерский
код, NRZ код), при использовании которых синхросигнал выделяется приемником
из потока принимаемых данных.
Существует несколько родственных последовательных интерфейсов: RS-232C, RS-423A, RS-422A, RS-455A. Характеристики этих интерфейсов сведены в таблицу 3.1.
Характеристики последовательных интерфейсов
Тип | Схема | V, L |
RS-232C | дуплекс | L=15 м, V=20 Кбит/с |
RS-423A | дуплекс | L=9 м, V=100 Кбит/с L=91 м, V=10 Кбит/с L=1200 м, V=1 Кбит/с |
RS-422A | дуплекс | L=12 м, V=10 Мбит/с L=120 м, V=1 Мбит/с L=1200 м, V=100 Кбит/с |
RS-485A | полудуплекс, до 32 параллельно соединенных приемопередатчиков | L=12 м, V=10 Мбит/с L=120 м, V=1 Мбит/с L=1200 м, V=100 Кбит/с |
Одним из вариантов последовательного интерфейса является интерфейс типа "токовая петля". В этом интерфейсе сигналом является не уровень напряжения, а ток в двухпроводной линии. Обычно, за единицу принимают ток 20 мА, за ноль - отсутствие тока. В таком варианте интерфейса приемник может распознавать обрыв линии - при обрыве принимаются одни нули и обрыв распознается по отсутствию стоп-битов. Обычно, "токовая петля" предполагает наличие гальванической развязки приемника и передатчика, как правило, выполняемой при помощи оптронов.
Питание токовой петли может осуществляться от передатчика (вариант с активным передатчиком) или от приемника (активный приемник). Токовая петля с гальванической развязкой позволяет передавать данные на расстояние до нескольких километров, определяемое уровнем помех и сопротивлением пары проводов. Поскольку интерфейс требует пары проводов для каждого сигнала, то обычно применяют две пары - принимаемые данные и передаваемые данные, а управление потоком ведется по протоколу XON/XOFF. Одним из классических примеров интерфейса "токовая петля" является интерфейс MIDI, применяемый в звуковых картах.
Все перечисленные выше варианты реализации интерфейса являются проводными, однако, существуют и беспроводные варианты, наибольшее распространение среди которых получил инфракрасный (ИК) интерфейс. Большинство ИК интерфейсов работают на расстоянии от одного до нескольких метров на низкой скорости (до 115,2 кбит/с), средней (до 1.152 Мбит/с) или высокой (до 4 Мбит/с) скоростью.
Интерфейс RS-232C использует несимметричные приемники и передатчики, сигнал передается относительно общего провода (схемной земли). Интерфейс RS-232C не обеспечивает гальванической развязки устройств. Логической единице на входе приемника соответствует уровень напряжения -3 ... -12 В. Для линий управляющих сигналов это состояние называют "ON", а для линий последовательных данных - "MARK". Логическому "0" соответствует напряжение +3 ... +12 В (называемое "OFF" или "SPACE", соответственно). Между уровнями +3 ... -3 В существует зона нечувствительности, обуславливающая гистерезис приемника. Состояние на выходе приемника изменяется только при пересечении напряжением порога +3 или -3 В. На рис. 3.2 показан искаженный помехой сигнал, который принимается без ошибки за счет гистерезиса приемника.
Уровни сигналов на выходах передатчика должны лежать в диапазоне +5...+12 В или -5 ... -12 В.
Интерфейс предполагает наличие защитного заземления обоих устройств.
Присоединение и отключение устройств с автономным питанием
должно производиться при отключенном питании, иначе разность невыровненных
потенциалов устройств в момент коммутации может превысить допустимые пределы
и вывести из строя микросхемы порта.
Для стандартизации оборудования обычно со стороны DTE (например в ПК) ставят разъем типа "вилка", со стороны DCE (например, в модеме) - разъем типа "розетка". Тип применяемых разъемов - DB-25S или DB-9S.
В таблице 3.2 приведена распайка кабеля для подключения
модема. Такой кабель иногда называют прямым (из-за того, что в нем соединяются
одноименные контакты).
Кабель для подключения модема
Сигнал | DB-9S | DB-25S | Направление | DB-25S | DB-9S | Сигнал |
TD | 3 | 2 | > | 2 | 3 | TD |
RD | 2 | 3 | < | 3 | 2 | RD |
DTR | 4 | 20 | > | 20 | 4 | DTR |
DSR | 6 | 6 | < | 6 | 6 | DSR |
RTS | 7 | 4 | > | 4 | 7 | RTS |
CTS | 8 | 5 | < | 5 | 8 | CTS |
DCD | 1 | 8 | < | 8 | 1 | DCD |
RI | 9 | 22 | < | 22 | 9 | RI |
SG | 5 | 7 | <> | 7 | 5 | SG |
Сигнал | DB25S | DB9S | Назначение |
PG | 1 | - | Защитная земля. Соединяется с корпусом устройства и экраном кабеля. |
SG | 7 | 5 | Сигнальная земля (относительно нее действуют линии сигналов) |
TD | 2 | 3 | Выход передатчика |
RD | 3 | 2 | Вход приемника |
RTS | 4 | 7 | Выход запроса передачи. Состояние "включено" уведомляет модем о том, что у терминала есть данные для передачи. В полудуплексе - переключение модема в режим передачи |
CTS | 5 | 8 | Вход разрешения передачи данных терминалу. Состояние "выключено" аппаратно запрещает передачу данных. Применяется для аппаратного управления потоками данных. |
DTR | 20 | 4 | Выход: "термина готов к передаче данных" |
DSR | 6 | 6 | Вход сигнала готовности от аппаратуры передачи данных |
DCD | 8 | 1 | Вход сигнала обнаружения несущей удаленного модема |
RI | 22 | 9 | Вход индикатора вызова (звонка) |
Для управления потоком данных могут использоваться два вида протоколов - аппаратный и программный. Не следует путать термин "управление потоком" с термином "квитирование". Квитирование - посылка уведомления о получении элемента, в то время как управление потоком предполагает посылку уведомления о временной невозможности последующего приема данных.
Аппаратный протокол управления RTS/CTS. Использует сигнал CTS, который позволяет остановить передачу данных, если приемник не готов к работе. Передача данных по этому протоколу показана на рис. 2.3 а. Байт, передаваемый на момент прихода CTS, будет передан, однако с момента окончания его передачи передатчик переходит к ожиданию готовности приемника (т.е. снятия CTS). Обеспечивает самую быструю реакцию передатчика на состояние приемника, позволяет организовать обмен, не прибегая к буферизации. Часто используется в принтерах и для соединения компьютеров. В случае с принтером линия CTS ПК должна соединяться с линией RTS принтера, при соединении двух ПК необходимо перекрестное соединение CTS-RTS. Если аппаратный протокол обмена не используется, то на линию CTS ПК необходимо подать сигнал "включено", что обычно достигается соединением CTS ПК с его же RTS перемычкой на разъеме. Аппаратный обмен невозможен через минимальный нуль-модемный кабель.
Рис. 2.3
Аппаратный протокол DTR/DSR. Аналогичен RTS/CTS, но использует другую пару сигналов (в данном случае "готовность приемника").
Программный протокол XON/XOFF. Предполагает наличие
двунаправленного канала обмена. Временные диаграммы обмена показаны на
рис. 2.3 б. Предполагает наличие у приемника буфера, так как время реакции
передатчика tp может оказаться достаточно большим. Когда буфер приемника
заполняется до определенного уровня (обычно 80-90%), он передает на приемник
команду XOFF (байт с кодом 13h). Приняв эту команду, передатчик прекращает
передачу и переходит в состояние ожидания до прихода команды XON (байт
с кодом 11h), по которому передатчик возобновляет передачу.
Распайки кабелей для подключения принтера по протоколам
XON/ XOFF и RTS/CTS приведены в приложении 1.
Программный протокол ACK. При обмене по этому протоколу
для получения очередного байта приемник посылает передатчику команду ACK
(байт с кодом 6h). В ответ передатчик посылает приемнику один байт (или
пакет байт определенного размера).
2.3.1. Микросхемы асинхронных приемопередатчиков и особенности работы с ними.
Преобразование параллельного кода в последовательный при
передаче и последовательного в параллельный при приме, контроль ошибок,
формирование запросов прерывания и ряд других сервисных функций осуществляется
специализированной микросхемой, называемой UART (Universal Asynchronous
Receiver -Transmitter) или УАПП (Универсальный Асинхронный Приемопередатчик).
COM порты IBP PC базируются на микросхемах, совместимых на уровне регистров
с UART i8250 - 8250/16450/16450A. Каждая из перечисленных микросхем совместима
с предыдущей, но не наоборот. Это следует учитывать при составлении программы
управления - если программа ориентирована на i8250, то она будет работать
со всеми последующими модификациями УАПП. В ряде отечественных ЭВМ применялись
микросхем КР580ВВ51 - аналог i8251, т.н. УСАПП (USART) - универсальный
синхронно-асинхронный приемопередатчик. Эта микросхема не совместима на
уровне регистров с i8250, однако в современных ПК она не применяется (подробнее
см. [4]).
Сравнительные характеристики УАПП, совместимых с i8250
приведена в таблице 2.4. Все микросхемы серии 8250 обладают низким быстродействием
и не допускают обращения к своим регистрам в смежных циклах процессора
- для корректной работы между обращениями организуют программные задержки
(команда типа JMP $+2)
Характеристики i8250 совместимых УАПП
УАПП | Характеристики |
8250 | Считается за базовую, самая примитивная по возможностям. Имеет ошибки, приводящие к возможности появления ложных прерываний |
8250А | Модернизированная 8050, ошибка устранена, непригоден в АТ для скорости 9600 бит/с, несовместим с XT BIOS |
8250B | Исправлены ошибки 8050 и 8050А, совместим с XT BIOS, работает в FN (кроме 9600 Кбит/с) |
16450 | Быстродействующая версия 8250 для AT. Соответствует минимуму для работы с OS/2. Не имеет ошибок, присущих 8250 |
16550 | Развитие 16450, имеет FIFO буфер (с ошибками, не позволяющими его корректно использовать !), может использовать DMA для обмена. |
16550А | Исправленная версия 16550, имеет нормально работающий 16-ти байтный FIFO буфер и DMA, которые должны применяться для работы на скоростях 9600 бит/сек и более без потери данных. |
,
где V - скорость передачи в бит/с. Входная частота синхронизации 1.8432 МГц делится адаптером на К и получается 16-ти кратная частота передачи.
Базовый адрес COM порта определяется путем чтения переменных
BIOS, адреса которых приведены в таблице 2.5. Стандартным адресом порта
COM является 3F8h, COM2 - 2F8h. Перед работой с портом рекомендуется определить
его адрес путем чтения переменной BIOS, а не брать стандартное значение.
Назначение регистров UART и их адреса относительно базового приведены в
таблице 2.6.
Адреса переменных BIOS для COM портов.
Имя порта | Адрес в BIOS | Тип переменной | Описание |
COM1 | 0040:0000h | Word | Базовый адрес порта COM1. Если переменная равна 0, то порт не найден |
COM2 | 0040:0002h | Word | --//-- |
COM3 | 0040:0004h | Word | --//-- |
COM4 | 0040:0006h | Word | --//-- |
Смещение | DLAB | R/W | 8250 | Значение |
0 | 0 0 | WO RO | ++ ++ | Регистр скорости обмена (LO) (табл.
2.7) Регистр передатчика Регистр приемника |
1 | 0 | R/W | +- | Регистр скорости обмена (HI) (табл.
2.8) Регистр маски разрешения прерываний (табл. 2.9) |
2 | x | WO | - | Регистр идентификации прерываний Регистр управления FIFO |
3 | x | R/W | + | Регистр управления линией (настройка параметров канала (табл. 2.11) |
4 | x | R/W* | + | Регистр управления модемом (табл. 2.12) |
5 | x | R/W* | + | Регистр состояния линии (табл. 2.13) |
6 | x | R/W | + | Регистр состояния модема (табл. 2.14) |
7 | x | R/W | - | Рабочий регистр для временного хранения данных |
Примечания:
1. * - некоторые биты допускают только чтение
2. "8250" - столбец, содержащий признак степени совместимости с 8250 (+ полная, '+-' - частичная, '-' - отсутствует в 8250).
Регистр разрешения прерываний. Единичное значение бита соответствует разрешению прерывания, назначение битов приведено в таблице 2.7. Если работа с портом идет без использования прерываний, то их следует запретить путем записи 0 в этот регистр.
Регистр разрешения прерываний
Бит | Значение |
7,6,5,4 | =0, не используются |
3 | по изменении статуса модема (STS, DSR, RI, RLSD ) |
2 | по ошибке приема данных |
1 | по завершению передачи |
0 | по приему символа ( в режиме FIFO - по тайм-ауту) |
Регистр идентификации прерываний. Ввиду
того, что контроллер обслуживается одним прерыванием, а возникать оно может,
в общем случае, в 4-х различных ситуациях, процедуре обработки прерывания
необходимо выяснить, по какой причине произошло прерывание.
Регистр идентификации прерываний
Бит | Значение |
7,6* | Признак режима FIFO: 11 - FIFO 16550А, 10 - FIFO 16550, 00 - обычный |
5, 4 | не используются |
3* | прерывание по тайм-ауту (не в режиме FIFO) |
2,1 | 00 - прерывание от приемника;
01 - есть данные в приемнике 10 - буфер передатчика пуст; 11 - изменение статуса модема |
0 | 1 - нет запроса прерывания, 0 - есть запрос |
В режиме FIFO биты 3-0 имеют иной смысл:
2,1,0* | 001 - регистр передатчика пуст; сброс - запись в регистр передатчика 000 - изменение состояния модема; сброс - чтение регистра состояния модема |
Регистр управления FIFO (только для записи, только 16550+) - таблица 2.9. Для очистки буферов FIFO необходимо запретить и затем снова разрешить режим FIFO.
Для задания основных параметров адаптера применяется регистр управления линией (табл. 2.10). Бит 7 регистра управления линией называется DLAB и предназначен для определения назначения регистров 0 и 1. Он устанавливается в 1 только на время программирования делителя управления скоростью передачи.
Регистр управления FIFO
Бит | Значение |
7,6 | Уровень заполнения FIFO буфера, при котором генерируется прерывание (00 - 1 байт, 01 - 4 байта, 10 - 8 байт, 11 - 14 байт) |
5,4 | Резерв |
3 | Разрешение операций DMA |
2 | Сброс счетчика FIFO передатчика |
1 | Сброс счетчика FIFO приемника |
0 | Разрешение ("1") режима FIFO для передатчика и приемника. При смене режима FIFO буфера очищаются! |
Бит | Значение |
7 | DLAB. Управление доступом к регистрам
адаптера интерфейса. 1-режим программирования делителя, 0 - чтение/запись. |
6 | Формирование "обрыва линии" (вывод нулей) |
5 | Принудительная четность (если 0, то бит паритета генерируется в соответствии с паритетом символа, "1" - всегда равен инверсному значению бита 4 этого регистра). |
4 | Тип паритета ("1"-четность, "0"-нечетность) |
3 | Разрешение бита контроля четности ("1" - формируется, "0" - запрещен ) |
2 | Длина стоп-бита ("0"-1, "1"-1.5 при длине слов 5 бит и 2 при длине слова 6-8 бит) |
1,0 | Длина слова в битах 00 - 5 ; 01 - 6; 10 - 7; 11 - 8 |
Бит 4 управляет типом паритета, бит 3 задает разрешение контроля паритета. Бит 2 задает длину стоп - бита. Биты 1-0 определяют длину слова. Наиболее часто применяются слова длиной 7 бит и 8 бит.
Регистр управления модемом позволяет управлять модемом,
назначение битов приведены в табл. 2.11.
Регистр управления модемом
Бит | Значение |
7,6,5 | =0 - резерв |
4 | "0" - нормальный режим, "1" - режим диагностики |
3 | OUT2 инверсный (разрешить прерывания от RS-232) |
2 | OUT1 инверсный (используется только в режиме диагностики) |
1 | RTSC - управление выходом RTS ("1" - активен (-V), "0" - пассивен (+V)) |
0 | DTRС - управление выходом DTR ("1" - активен (-V), "0" - пассивен (+V)) |
В режиме диагностики выход передатчика переводится в состояние
"1", вход приемника отключается, выход сдвигающего регистра передатчика
логически соединяется с входом приемника; входы DSR, CTS, RI, DCD отключаются
от входных линий и соединяются с DTRС, RTSC, OUT1, OUT2 соответственно,
выходы управления модемом переводятся в пассивное состояние. Переданный
в таком режиме байт должен немедленно приниматься, что позволяет проверять
внутренние каналы данных порта и сдвиговые регистры.
Регистр состояния линии
Бит | Значение |
7* | Ошибка принятых данных в режиме FIFO (буфер FIFO содержит хотя бы один символ, принятый с ошибкой). |
6 | Буфер передатчика пуст (символов нет ни в регистре передатчика, ни в сдвиговом регистре, ни в буфер FIFO) |
5 | Сдвиговый регистр передатчика пуст (буфер FIFO передатчика пуст). Может генерировать прерывание. |
4 | BD Индикатор обрыва линии (на входе приемника "0" не менее, чем время посылки одного символа) |
3 | FE Ошибка кадра (Стоп-бит не найден) |
2 | PE Ошибка контрольного бита |
1 | OE Ошибка переполнения. Означает потерю символа (имеет аналогичный смысл в режиме FIFO) |
0 | DR принятые данные готовы. Сбрасывается при чтении регистра приемника |
Регистр состояния линии позволяет определить состояние приемопередатчика (таблица 2.12).
Регистр состояния модема (табл. 2.13) позволяет определить
состояние модема. Биты 3-0 вызывают прерывание "Изменение состояние модема".
"1" в любом из этих битов свидетельствует о том, что состояние линии изменилось
по сравнению с состоянием на момент последнего чтения этого регистра.
Регистр состояния модема
Бит | Значение |
7 | Состояние линии DSD |
6 | Состояние линии RI |
5 | Состояние линии DSR |
4 | Состояние линии CTS |
3 | Изменение DSD |
2 | Изменение RI |
1 | Изменение DSR |
0 | Изменение STS |
2.4. Примеры работы с последовательным портом на низком уровне
Работа с последовательным портом на низком уровне аналогична работе с параллельным - вначале определяем базовый адрес порта, затем работаем с его регистрами. Главная отличительная особенность состоит в необходимости установки параметров COM порта перед началом работы. Приведем пример программы настройки параметров порта (скорость 4800 кбод, 1 стоп-бит, четность, 8 бит/слово): mov ax, 40h
mov es, ax ; в es - сегмент = 0040h
mov dx, es:[00] ; dx = базовый адрес порта COM1
mov COM1_adr, dx ; запомнили адрес порта COM1 в переменной
add dx, 3 ; DX=адресу регистра управления
mov al, 80h ; Установили бит DLAB - настройка делителя
out dx, al ; Рабочая скорость - 4800 Кбод
dec dx
dec dx ; DX=адресу старшего байта делителя скорости
mov al, 0
out dx, al
dec dx ; DX=адресу младшего байта делителя скорости
mov al, 18h ; Установка младшего байта делителя
out dx, al
add dx, 3 ; DX=адресу регистра управления
mov al, 00011011b ; DLAB=0, четность, 1 стоп-бит, 8 бит/слово
; (см. табл. 2.8)
out dx, al
dec dx
dec dx ; DX=адресу регистра разрешения прерываний
mov al, 00h ; Прерывания запрещены
out dx, al
Пример чтения байта с ожиданием без использования прерываний:
mov dx, COM1_adr ; DX=базовому адресу COM1
add dx, 5 ; DX=адресу регистра состояния
Wait:
in al, dx ; чтение байта состояния
test al, 01h ; Бит 1="1" (принят байт)
jz wait ; Нет - ждем
sub dx, 5 ; DX=адресу регистра приемника
in al, dx ; чтение принятого байта
Пример передачи байта из AH (без контроля готовности приемника):
mov dx, COM1_adr ; DX=базовому адресу COM1
add dx, 5 ; DX=адресу регистра состояния
Wait:
in al, dx ; чтение байта состояния
test al, 40h ; Бит 6=1 (готов к передаче очередного байта)
jz wait ; Нет - ждем
sub dx, 5 ; DX=адресу регистра передатчика
mov al, ah
out dx, al ; Передача
BIOS представляет программе пользователя набор стандартных функций для работы с последовательным портом. Данное прерывание может быть перехвачено или замещено программой - драйвером. Вниманию программистов : не все программы, выводящие информацию на ПУ, работают через INT 17h. Кроме того, при перекодировке символов нельзя перекодировать символы, входящие в состав команд языка управления ПУ. Параметры вызова основных функций приведены в таблице 2.14. Байты состояния линии и модема, возвращаемые обработчиком INT 14h, полностью соответствуют регистру состояния линии и регистру состояния модема адаптера порта.
Функция | Регистры при вызове | Регистры при возврате |
Инициализация порта | AH=00h AL= параметры инициализации порта DX= номер порта (0-3) | AH= состояние линии AL= состояние модема |
Передать символ | AH=01h AL= символ DX= номер порта (0-3) | AH - бит 7 сброшен, если успешное выполнение и установлен в случае ошибки. Биты 6-0 - состояние порта |
Принять символ | AH=02h DX= номер порта (0-3) | AH= состояние линии AL= принятый символ, если AH.7 |
Получить состояние порта | AH=03h DX= номер порта (0-3) | AH= состояние линии AL= состояние модема |
Параметры инициализации порта
Биты | Значение |
7,6,5 | Скорость передачи 000 - 110 бод (19200 бод для FOSSIL) 001 - 150 бод (38400 бод для FOSSIL) 010 - 300; 011 - 600; 100 - 1200; 101 - 2400; 110 - 4800 111 - 9600 (4800 на PCjr) |
4,3 | Контроль четности: 00 - нет; 01 - нечетность; 10 - нет; 11 - четность |
2 | Число стоп-битов: 0 - 1; 1 - 2 |
1,0 | Размер слова: 00 - 5 бит; 01 - 6 бит;10 - 7 бит; 11 - 8 бит |
2.6. Пример программы передачи строки на принтер по последовательному интерфейсу с использованием INT 14h
; Описываем сегмент данных, в котором расположим все данные программы
DATA Segment byte public 'DATA'
String DB 'Тест принтера !!!',0 ; выводимая строка
Error DB 'Ошибка: принтер не готов !!!!$' ; сообщение об
; ошибке
DATA ENDS ; конец сегмента данных
CODE Segment byte public 'CODE'
; Зададим соответствие регистров для использования по умолчанию
ASSUME CS:CODE, DS:DATA, ES:DATA
START: ; Начало программы
mov ax, data ; установим ds на сегмент данных
mov ds, ax
mov dx, 0 ; порт COM1
mov ah, 0 ; функция INT 14 "инициализация порта"
mov al, 11011111b; скорость обмена 4800, четность, 1 стоп-бит,
; 8- бит/слово
int 14h ; инициализировали порт
test al, 20h ; принтер готов (контроль линии DSR) ?
jz err_exit ; если нет, то выход с сообщением о ошибке
mov bx, offset string ; смещение на выводимую строку
LOOP1: ; Цикл печати строки
mov al, ds:[bx] ; прочитали очередной символ строки
cmp al, 00h ; это конец строки ?
je exit ; да, выходим
call out_byte ; нет, печатаем его
inc bx ; на следующий символ
jmp loop1 ; повторим
ERR_EXIT: ; Выход по ошибке
mov dx, offset error ; вывод строки на экран
mov ah, 9
int 21h
mov ax, 4c00h ; завершить с кодом возврата 1
int 21h
EXIT: ; Нормальное завершение
mov al, 0Ah ; дадим перевод каретки
call out_byte
mov ax,4C00h ; завершить с кодом возврата 0
int 21h
; **** Процедуры и функции программы ****
OUT_Byte: ; Процедура вывода символа из AL на принтер с
; ожиданием
push ax ; процедура должна быть рентабельна
push dx
LOOP2:
push ax
mov dx, 0 ; порт COM1
mov ah, 3 ; функция "получить состояние"
int 14h ; проверим состояние
test al, 20h ; готов (линия DSR) ?
pop ax
jz loop2 ; если нет, то повторим опрос
mov ah, 1 ; функция "вывод символа"
int 14h ; выводим символ
pop dx
pop ax
ret ; выход в основную программу
CODE ENDS ; Завершение кодового сегмента
END START ; Конец программы
Пример процедуры для синхронной передачи байта:
Procedure TransmitByte(b:byte);assembler;asm
mov BL, b { Передаваемый байт }
not bl
mov dx, Lpt_Adres { В DX - адрес регистра линий порта }
mov CX, 8 { Счетчик для передачи 8 бит из BL }
@L1: { Метка цикла передачи }
shl BL, 1 { Сдвиг влево - в флаге CF старший бит }
mov AL, 1 { AL.0:=1 }
jc @L2
mov AL, 0 { Если передаваемый бит=0, то AL.0:=0 }
@L2:
or al, 2 { D1= CLK =1 }
out dx, al { Установили: D0=передаваемому биту, D1= CLK =1 }
and al, 0FDh { AL.1:=0 }
out dx, al { Установили: D0=передаваемому биту, D1=CLK=0 }
push cx { Временная задержка }
mov cx, del_int
@L3:
loop @L3
pop cx
or al, 2 { AL.1:=1 }
out dx, al { Установили: D0=передаваемому биту, D1= CLK =1 }
push cx { Временная задержка }
mov cx, del_int
@L4:
loop @L4
pop cx
loop @L1 { Повторять 8 раз }
end;
Временные задержки определяют скорость передачи и
задаются глобально для процедур приема и передачи данных. Данные передаются
по линии D0. Синхросигнал передается по линии D1, причем активным уровнем
является "0".