УДК 681.3 (075.8)
К 681.3:621.382.049.77 (075.8)
317
 

Коммуникацинные порты персонального компьютера

(С) Зайцев О.В., 1999 zaitsev@smolen.elektra.ru
Утверждено учебным управлением МЭИ в качестве учебного пособия для студентов

Данный HTML документ является электронной версией методических указаний, подготовленных на кафедре Промышленной электроники Смоленского филиала МЭИ

Содержание

Введение

Коммуникационные порты компьютеров (LPT и COM) широко используются для управления различными периферийными устройствами, такими как принтеры, сканеры, плоттеры, а так же для связи с промышленными объектами в системах автоматизации управления. Через последовательный порт так же осуществляется связь с удаленными объектами через модем, включая и выход в глобальную сеть Internet.

В то же время в учебно-методической литературе схемотехника и методика применения портов компьютера освещена достаточно слабо. В частности не освещены новые режимы работы параллельных портов, такие как EPP и ECP, используемые в современных компьютерах. Предлагаемое пособие предназначено для того, чтобы хотя бы частично закрыть эту проблему.

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

Оригинальная прикладная программа LPT_MON, приведенная в пособии, дает возможность исследовать работу параллельного порта и производить отладку алгоритмов работы с устройством через параллельный порт.

В пособии описаны основные протоколы обмена через последовательный (COM) порт. Даны сведения не только по расширенному интерфейсу RS-232, но и по современным интерфейсам RS-422 и RS-485.

Приведенные в пособии справочные данные по портам делают его полезным не только для в учебных целях, но и в практической деятельности специалистов, работающих в области эксплуатации компьютерных систем, и разработчиков программно-аппаратных средств управления.
 


Параллельный интерфейс.

Исторически параллельный интерфейс был введен в персональный компьютер (ПК) для подключения принтера (отсюда и аббревиатура LPT - Line printer - построчный принтер). Однако впоследствии параллельный интерфейс стал использоваться для подключения других периферийных устройств - сканеров, дисководов типа Zip и ряда других устройств. Базовая разновидность порта позволяет передавать данные только в одном направлении (от ПК к ПУ), однако позднее был разработан ряд стандартов двунаправленной передачи данных.
Адаптер параллельного интерфейса представляет собой набор регистров, расположенных в адресном пространстве устройств ввода/вывода. Количество регистров зависит от типа порта, однако три из них стандартны и присутствуют всегда - регистр данных, регистр состояния и регистр управления. Адреса регистров отсчитываются от базового, стандартные значения которого 3BCh, 378h, 278h. Порт может использовать аппаратное прерывание (IRQ7 или IRQ9). Многие современные системы позволяют изменять режим работы порта, его адрес и IRQ из настроек BIOS Setup. Например, в AWARD BIOS имеется раздел Integrated Peripherals, позволяющий настраивать режим, адрес и IRQ порта.

LPT порт имеет внешнюю 8-битную шину данных, 5-битную шину сигналов состояния и 4-х битную шину управляющих сигналов. Очевидно, что порт резко асимметричен - 12 линий работают на вывод и только 5 на ввод.

При начальной загрузке BIOS пытается обнаружить параллельный порт, причем делает это примитивным и не всегда корректным образом - по возможным базовым адресам портов передается тестовый байт, состоящий из чередующегося набора нулей и единиц (55h или AAh), затем производится чтение по тому же адресу, и если прочитанный байт совпал с записанным, то считается, что по данному адресу найден LPT порт. Определить адрес порта LPT4 BIOS не может. Для работы с ПУ в BIOS предусмотрено прерывание INT 17h, предоставляющее возможность передавать данные (побайтно), инициализировать ПУ и получать информацию о его состоянии.
 


1.1. Интерфейс Centronics


 


Понятие Centronics относится к набору сигналов, протоколу обмена и разъему, устанавливаемому в принтерах. Большинство современных принтеров совместимы с интерфейсом Centronics. Назначение сигналов и контакты разъема ПУ, на который они выведены приведены в таблице 1.1

     

    Таблица 1.1.
Сигналы интерфейса Centronics
СигналТКонт.Напр.Назначение
Strobe01iСтроб данных. Передается ЭВМ, данные фиксируются по низкому уровню сигнала.
D0 ... D712-9iЛинии данных. D0 - младший бит.
Ack010oAcknowledge - импульс подтверждения приема байта (запрос на прием следующего). Может использоваться для формирования прерывания.
Busy111oЗанят. Прием данных возможен только при низком уровне сигнала
PE112o"1" сигнализирует о конце бумаги
Select113o"1" сигнализирует о включении принтера (ГП - готовность приемника), обычно +5 В через резистор от источника питания ПУ)
Auto LF014iАвтоматический перевод строки. Если "0", то ПУ при получении символа CR (перевод каретки) выполняет функцию LF - перевод строки
Error032oОшибка ПУ (off-line, нет бумаги, нет тонера, внутренняя ошибка)
Init031iИнициализация (переход к началу строки, сброс всех параметров на значения по умолчанию)
Slct In036iВыбор принтера. При "1" принтер не воспринимает остальные сигналы интерфейса
GND 
19-30,

33

-Общий провод

Примечание: столбец "T" - активный уровень сигнала: "1" - высокий активный уровень, "0" - низкий активный уровень. Столбец "Напр." - направление передачи по отношению к принтеру: I - вход, 0 - выход.

Сигнал Auto LF практически не применяется, но его неправильное значение приводит к тому, что принтер либо делает пропуски строк, либо печатает строки поверх друг друга, либо дублирует строки при печати в два прохода.

Отечественным аналогом интерфейса Centronics является ИРПР-М. Кроме него существует интерфейс ИРПР (устаревший), который отличается протоколом обмена, отсутствием сигнала "Error" и инверсией линий данных. Кроме того, ко всем входным линиям ИРПР подключены пары согласующих резисторов: 220 Ом к +5 В и 330 Ом к общему проводу. Это перегружает большинство интерфейсных адаптеров современных ПК, поэтому при адаптации такого принтера необходимо удалить эти резисторы.

Контроль и модификация сигналов интерфейса Centronics может производиться при помощи программы LPT-MON, описанной ниже.
 



Рис. 1.1


 




Протокол обмена по интерфейсу Centronics приведен на рис. 1.1

Передача начинается с проверки источником сигнала "Error". Если он установлен, то обмен не производится. Затем проверяется состояние сигнала "Busy". Если он равен "0", то источник приступает к передаче байта данных. Для передачи байта источник выставляет на линии D0-D7 байт данных и выдает сигнал Strobe. Приемник по сигналу Strobe# (здесь и далее по тексту значок "#" после названия сигнала является признаком того, что сигнал имеет низкий активный уровень) читает данные с шины данных и выставляет сигнал Busy на время его обработки. По окончании обработки приемник выдает сигнал ACK# и снимает сигнал Busy. Если в течение длительного времени (6 - 12 сек) источник не получает ACK#, то он принимает решение о ошибке "тайм-аут" (time-out) устройства. Если после приема байта приемник по какой - либо причине не готов принимать данные, то он не снимает сигнал Busy. При программной реализации обмена по указанному протоколу желательно ограничить время ожидания снятия Busy (обычно 30 - 45 сек), иначе возможно зависание программы.

1.2. Стандартный параллельный порт ПК

Стандартный параллельный порт называется SPP (Standard Parallel Port - Стандартный Параллельный Порт). SPP порт является однонаправленным, на его базе программно реализуется протокол обмена Centronics. Порт обеспечивает возможность генерации IRQ по импульсу ACK# на входе. Сигналы порта выводятся на стандартный разъем DB-25S (розетка), который размещен непосредственно на плате адаптера или соединяется с ним плоским шлейфом (в случае, если адаптер интегрирован с материнской платой). Названия сигналов соответствуют названиям сигналов интерфейса Centronics (таблица 1.2).

В таблице 1.2 I/O - направление передачи: I - вход; O - выход; O(I) - выход, состояние которого может быть считано при определенных условиях, O/I - выходные линии, состояние которых читается при чтении из соответствующих регистров порта.

Таблица 1.2.


Разъем и шлейф стандартного LPT порта

Контакт 

DB-25S

Провод

шлейфа

I/OСигнал 
Контакт 

DB-25S

Провод

шлейфа

I/OСигнал
11O/IStrobe# 1019I*ACK#
23O(I)D0 1121IBusy
35O(I)D1 1223IPE
47O(I)D2 1325ISelect
59O(I)D3 142O/IAuto LF#
611O(I)D4 154IError#
713O(I)D5 166O/IInit#
815O(I)D6 178O/ISelect In#
917O(I)D7 18 - 25
10,22,14,

16,18,20,22,24,26

-GND
* - Вход ACK# соединен с питанием +5 В через резистор 10 кОм. Это сделано для исключения ложных прерываний, т.к. прерывание генерируется по отрицательному перепаду сигнала на входе ACK#.

В качестве недостатков стандартного LPT порта (SPP) следует отметить невысокую скорость передачи данных (100 - 150 КБ/сек), загрузку процессора при передаче данных, невозможность двунаправленного побайтного обмена. Существует "радиолюбительская" методика двунаправленного обмена, которая состоит в том, что для ввода данных на линии D0-D7 выставляют "1", а в качестве передатчика используют микросхемы с открытым коллектором, которые при открытом транзисторе могут "подсаживать" напряжение логической единицы до уровня порядка 1.5 - 1.7 В. Ток ограничен на уровне 30 мА. Как очевидно из уровней сигналов, они не соответствуют уровням ТТЛ, поэтому многие порты не работают в таком режиме или работают нестабильно. Кроме того, такой способ может быть опасен для адаптера порта, который будет работать с предельными для него токами.

1.3. Стандарт IEEE 1284 -1994

Стандарт на параллельный интерфейс 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 и часто установлен по умолчанию. Все остальные режимы расширяют функциональные возможности интерфейса и повышают его производительность. Кроме того, стандарт регламентирует способ согласования режима, доступного как ПК, так и периферийному устройству.
 


1.4. Физический и электрический интерфейс


 


Стандарт IEEE 1284 определяет физические характеристики приемников и передатчиков сигналов. IEEE 1284 предусматривает два уровня интерфейсной совместимости: первый уровень - для устройств, не требующих высоких скоростей обмена, но использующих возможность смены направления передачи данных; уровень два - устройства, работающие в расширенных режимах, с высокими скоростями и длинными кабелями.

Требования к передатчикам приведены в таблице 1.3, для приемников - в таблице 1.4.
 
 

Таблица 1.3.


Требования стандарта IEEE 1284 к передатчикам

ТребованиеЗначение
Диапазон уровней сигналов без нагрузки -0.5...+5.5 В
Уровень "1" при токе нагрузки 14 мА, не менее+2.4 В
Уровень "0" при токе нагрузки 14 мА, не более+0.4 В
Выходной импеданс, измеренный на разъеме50+ 5 Ом
Скорость нарастания/спада импульса (должен находиться в указанных пределах)
0.05 ... 0.4

В/нс

Таблица 1.4.


Требования стандарта 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 для кабелей:

  1. Все сигнальные проводники должны быть перевиты с отдельными обратными (общими) проводами.
  2. Каждая пара должна иметь импеданс 62+ 6 Ом в диапазоне частот 4-16 МГц
  3. Уровень перекрестных помех не должен превышать 10%
  4. Кабель должен иметь экран, покрывающий не менее 85 процентов внешней поверхности. На концах кабеля экран должен быть окольцован и соединен с контактом разъема.
Кабели, удовлетворяющие этим требованиям, маркируются как "IEEE Std 1284 - 1994 Compliant". Они могут иметь длину до 10 метров.

1.5. Работа с SPP портом на низком уровне


 


Работа с параллельным портом на низком уровне (т.е. на уровне прямого обращения к контроллеру порта) применяется при решении различного круга задач по обмену информацией с нестандартными устройствами, для написания драйверов принтеров и ряда других задач. Прямая работа с контроллером позволяет реализовать любой протокол обмена с устройством и использовать линии порта по своему усмотрению.

Контроллер порта расположен в адресном пространстве устройств ввода-вывода и обращение к нему производится посредством команд IN и OUT ассемблера. Информацию о портах LPT1 - LPT3 можно получить, прочитав переменные BIOS, приведенные в табл. 1.5.

Таблица 1.5.


Переменные BIOS для LPT портов

Имя портаАдрес в BIOSТип переменнойОписание
LPT10040:0008hWordБазовый адрес порта LPT1. Если переменная равна 0, то порт LPT1 не найден
 0040:0078hByteКонстанта, задающая тайм-аут 
LPT20040:000AhWordБазовый адрес порта LPT2. Если переменная равна 0, то порт LPT2 не найден
 0040:0079hByteКонстанта, задающая тайм-аут 
LPT30040:000ChWordБазовый адрес порта LPT3. Если переменная равна 0, то порт LPT3 не найден
 0040:007AhByteКонстанта, задающая тайм-аут 
LPT40040:000EhWordБазовый адрес порта LPT4. Если переменная равна 0, то порт LPT4 не найден
 0040:007BhByteКонстанта, задающая тайм-аут 
Примечание: BIOS ищет порты по адресам 3BCh, 378h, 278h. Порт LPT4 BIOS найти не может.
Пример определения базового адреса (TASM):
 
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.
 
 

Таблица 1.6.
Регистры стандартного LPT порта
АдресНазваниеW-R
Base+0Data Register - регистр данных (DR)W/R
Base+1Status register - регистр состояния (SR)R
Base+2Control 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. 


Таблица 1.7.


Биты регистра состояния

БитВесНазваниеНазначение
7128BUSYИнверсное отображение состояния линии Busy (11). При низком уровне на линии 11 (Busy) - бит равен "1" - ПУ готово к приему очередного байта
664ACKОтображение состояния линии ACK# (10). 

"0"-подтверждение приема, "1"-обычное состояние

532PEОтображение состояния линии Paper End (12). 

"0" - норма, "1" - в ПУ нет бумаги

416SLCT OUTОтображение состояния линии Select (13). 

"0" - ПУ не выбрано, "1" - ПУ выбрано

38Error инв.Отображение состояния линии Error (15). 

"0" - ошибка ПУ, "1" - обычное состояние

24PIRQФлаг прерывания по ACK# (только PS/2). Обнуляется, если ACK# вызвал аппаратное прерывание. "1" - после сброса или после чтения регистра состояния
1-04-1--Не используются (резерв)

1.5.3. Регистр управления.Регистр управления представляет собой 4-х битный порт вывода, допускающий чтение и запись. Биты 0,1,3 инвертируются, т.е. "1" в данных битах регистра управления соответствует "0" на соответствующих линиях порта. Назначение бит регистра управления приведены в таблице 1.8. Бит 5 используется только портами PS/2.

Таблица 1.8.


Биты регистра управления

БитВесНазваниеНазначение
7128-Резерв
664-Резерв
532DirectionБит управления направлением порта PS/2. 

"1" - режим ввода, "0" - режим вывода

416AckIntEnБит управления генерацией прерывания по ACK#

"1" - разрешить прерывание по спаду ACK# (10)

38SLCT INУправление линией SLCT IN# (17). 

"1" - работа принтера разрешена.

24INITУправление линией INIT# (16). 

"1" - обычное состояние, "0" - аппаратный сброс ПУ

12Auto LFУправление линией Auto LF# (14). 

"1" - включить режим "Auto LF", "0" - обычное сост.

01StrobeУправление линией Strobe# (1).

"1" - стробирование данных, "0" - обычное сост.

1.5.4. Пример программы для передачи строки данных на низком уровне.


; Пример разработан на TASM.
DATA Segment byte public 'DATA'   ; Описываем сегмент
                                  ; данных
String   DB  'Test printer !!!',0Dh, 0Ah,0 ; выводимая строка
Lpt1_adr DW 0  ; Переменная для хранения базового адреса LPT1

DATA ENDS ; конец сегмента данных
 

; Сегмент кода - в нем расположим саму программу
CODE Segment byte public 'CODE'
ASSUME CS:CODE,DS:DATA,ES:DATA

START:   ; Начало программы
 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

  Коротко о работе программы. В начале программы описан сегмент данных, содержащий выводимую ASCIIZ строку (строку, завершающуюся нулем) и переменную типа Lpt1_adr типа Word для хранения базового адреса порта Lpt1.
В начале программы она определяет базовый адрес Lpt1 и сохраняет его в переменной Lpt1_adr. Затем идет цикл побайтного вывода строки, критерий завершения - текущий символ равен 0. Вывод символа производится процедурой OUT_BYTE (передаваемый символ должен находиться в AL на момент вызова процедуры).
При запуске OUT_BYTE читает регистр состояния порта и проверяет 7-й бит (BYSY). Если он равен 0 (принтер занят), то повторяем опрос регистра состояния до достижения готовности принтера (цикл LOOP2). Затем в регистр данных записывается код передаваемого символа, после чего формируется импульс Strobe.
Данный пример несколько некорректен - цикл ожидания готовности принтера может продолжаться бесконечно, если по какой либо причине он держит на линии сигнал BUSY. Для устранения повисания в цикле LOOP2 необходимо сделать привязку к таймеру для проверки времени ожидания и, в случае ожидания более чем 15 - 20 сек, выдать сообщение о том, что принтер не готов к работе. Кроме того, после определения базового адреса необходимо проверить, не равен ли он 0 (признак отсутствия LPT порта.
 


1.6. Работа с SPP портом через INT 17h


 


Как очевидно из рассмотренного в п.п. 1.5.4 примера работы с портом на низком уровне, написание программы сложно и невозможно перехватить вывод информации в порт. Это означает, что невозможно разработать программу - драйвер для перекодировки символов, передаваемых в порт или для реализации нестандартного протокола обмена. Качественно иной подход - использование программного прерывания BIOS INT 17h. Оно предоставляет программисту набор стандартных функций для работы с ПУ: передать байт, сброс ПУ и опрос состояния ПУ. Данное прерывание может быть перехвачено или замещено программой - драйвером. Вниманию программистов: не все программы, выводящие информацию на ПУ, работают через INT 17h. Кроме того, при перекодировке символов нельзя перекодировать символы, входящие в состав команд языка управления ПУ.
Параметры вызова функций INT 17h приведены в таблице 1.9.

Таблица 1.9.


Функции INT 17h

ФункцияРегистры при вызовеРегистры при возврате
Вывод символа по протоколу Centronicsah = 00h

al = выводимый символ

dx = номер принтера (0 - 3)

AH - слово состояния
Инициализация принтераah = 01h

dx = номер принтера (0 - 3)

AH - слово состояния
Принтер - получить состояниеah = 01h

dx = номер принтера (0 - 3)

AH - слово состояния
Слово состояния принтера: слово состояния принтера содержит биты 1..7 регистра состояния указанного порта (см. п.п. 1.5.2), а бит 0 является флагом тайм-аута. Если он установлен, то ПУ не снимает сигнал BUSY в течении времени, заданного в соответствующей переменной BIOS.

1.6.1. Пример программы для передачи строки через INT 17h


 


В качестве примера рассмотрим ту же программу, что и в примере по прямой работе с 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 ; Конец программы
 
 

1.7. Реализации двунаправленного обмена данными

Проблема двунаправленного обмена возникла при появлении устройств типа накопителя ZIP, которые удобно подключать к LPT порту. Существует несколько стандартных решений, одобренных IEEE 1284. Рассмотрим два наиболее простых. В описании двунаправленного обмена применяются следующие термины:

Хост (Host) - ПК с LPT портом

Прямой канал (передача в прямом направлении) - канал (передача) от хоста к ПУ; обратный канал - канал ввода данных в Хост от ПУ
 


1.7.1. Полубайтный обмен - Nibble Mode.


 


Режим полубайтного обмена (Nibble Mode) наиболее универсален и может использоваться на любом стандартном (SPP) порту. SPP порт имеет 5 линий ввода, используемых для ввода сигналов состояния ПУ. Их можно использовать для ввода данных за два прима по 4 бита (Nibble - полубайт). Назначение и название сигналов, используемых в Nibble Mode приведены в таблице

Таблица 1.10. Сигналы, используемые при вводе в Nibble Mode
Конт.
Сигнал

SPP

Сигнал

NM

I/OНазначение
14Auto Feed#HostBusyOСигнал квитирования. 

"0" - готовность к приему тетрады

"1"-подтверждение приема тетрады

17SLCT IN#-O"1" - признак обмена по IEEE 1284

"0" - обмен по SPP

10ACK#PtrClkI"0" - действительность тетрады

"1" - ответ на HostBusy

11BUSY-IПрием битов 3, 7
12PE-IПрием битов 2, 6
13SELECT-IПрием битов 1, 5
15ERROR#-IПрием битов 0, 4


Рис. 1.2.

Временные диаграммы обмена приведены на рис. 1.2.

Прием в режиме Nibble Mode производится следующим образом: ПК сигнализирует о готовности к приему низким уровнем HostBusy. ПУ в ответ выставляет на линии младшую тетраду данных и сигнализирует о ее действительности низким уровнем PtrClk. ПК в ответ устанавливает высокий уровень HostBusy, сигнализируя о занятости приемом и обработкой. ПУ отвечает на это высоким уровнем PtrClk. Затем все перечисленные действия повторяются для старшей тетрады данных.

Nibble Mode универсален и гарантированно работает на любом порте любого типа (SPP, EPP, ECP), поэтому применяется в устройствах типа накопителя ZIP как режим по умолчанию. Однако, прием данных в Nibble Mode сильно загружает процессор, максимальная скорость обмена, как правило, не превышает 50 - 60 кбайт/с. Обмен с ПУ получается aсимметричным - скорость приема будет в два раза меньше скорости передачи.
 


1.7.2. РежимEPP.


 


Протокол EPP (улучшенный параллельный порт) был разработан задолго до принятия IEEE 1284 и предназначен для повышения производительности обмена данными по параллельному порту.

Протокол EPP обеспечивает 4 типа циклов обмена:

    Цикл записи данных
    Цикл чтения данных
    Цикл записи адреса
    Цикл чтения адреса
Циклы чтения/записи адреса и данных отличаются протоколами (используют разные стробирующие сигналы). Внешние сигналы EPP порта формируются аппаратно в течении одного процессорного цикла ввода/вывода, что позволяет достичь скоростей 0.5 - 2 Мбайт/с . Назначение сигналов LPT порта в EPP режиме приведены в таблице 1.11.
 
 
Таблица 1.11.
Сигналы, используемые в режиме EPP
Конт.
Сигнал

SPP

Сигнал

EPP

I/OНазначение
1Strobe#WRITE#O"0" - признак цикла записи, 

"1" - признак цикла чтения

14Auto Feed#DATASTB#OСтроб данных. 
17SLCT IN#ADDRSTB#OАдреса данных. 
16INIT#RESET#OСброс ПУ (по "0")
10ACK#INTR#IПрерывание от ПУ
11BUSYWAIT#IСигнал квитирования. 

"0" - разрешает начало цикла

"1" - разрешает завершение цикла

12PEACKDATAREQIИспользуется по усмотрению разработчика
13SELECTXFLAGI---//---
15ERROR#DATAAVAIL#I---//---

По сравнению с SPP, EPP порт имеет расширенный набор регистров - табл. 1.12
 

Таблица 1.12.
Регистры порта EPP
Имя регистраСмещениеРежимR/WОписание
SPP Data PortBase+0SPP/EPPWРегистр данных SPP
SPP Status PortBase+1SPP/EPPRРегистр состояния SPP
SPP Control PortBase+2SPP/EPPWРегистр управления SPP
EPP Address PortBase+3EPPR/WРегистр адреса EPP
EPP Data PortBase+4EPPR/WРегистр данных EPP
?Base+5 ..+7EPP?Может использоваться в некоторых контроллерах для 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 и отличаются типом процессорного цикла ввода-вывода и стробом.
 


1.7.3. Режим ECP.

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.
 

Таблица 1.13.


Сигналы порта EPP

Конт.
Сигнал

SPP

Сигнал

ECP

I/OНазначение
1Strobe#HostClkOИспользуется в паре с PeriphAck для передачи в прямом направлении. 
14Auto Feed#HostAckOИндицирует тип команда/данные при передаче в прямом направлении. Используется в паре с PeriphClk для передачи в обратном направлении.
17SLCT IN#-O"1" - признак обмена по IEEE 1284

"0" - обмен по SPP

16INIT#Reverse Request #O"0" - передача в обратном направлении

"1" - передача в прямом направлении

10ACK#PeriphClkIИспользуется в паре с HostAck для передачи в обратном направлении.
11BUSYPeriphAckIИспользуется в паре HostClk с для передачи в обратном направлении. Индицирует тип команда/данные при передаче в обратном направлении.
12PEAck Reverse #IПереводится в "0" в качестве подтверждения Reverse Request #
13SELECTX FlagIФлаг расширяемости
15ERROR#Periph Request #IУстанавливается ПУ в для указания на доступность обратного канала
2...9Data[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).
 


2. ПрограммаLPT_MON

Программа LPT_MON распространяется бесплатно и ее можноскачать.
2.1. Назначение программы и ее возможности

Данная программа позволяет :

  1. Анализировать состояния основных сигналов порта Centronics во времени путем прямого чтения соответствующих регистров контроллера и их отображение в виде осциллограмм, бинарных и шестнадцатеричных чисел;
  2. Редактировать регистры порта;
  3. Формировать короткий импульс STROBE для передачи байта ;
  4. Производить скоростную запись состояния порта на диск до, во время и после строба с возможностью их просмотра в виде осциллограмм;
  5. Передавать управляющие коды принтера и любые наборы данных (строки и числа в десятичной и шестнадцатиричной системе, что позволяет формировать любые управляющие последовательности и наблюдать за их выполнением);
  6. Работать с принтером через INT 17h, что позволяет изучить работу обработчика INT 17h и (или) проверить его работу;
  7. Определять адреса портов
Программа имеет встроенный антивирус, диагностирующий программу при каждом ее запуске и излечивающий ее в случае заражения. Программа имеет контекстную систему помощи, содержащую информацию по всем пунктам программы.

2.2 Главное меню и "осциллограф"

Главное меню представляет собой список опций, любая из которых может быть выбрана маркером и активирована. Желтым цветом выделены сигналы, для которых в стандартном протоколе обмена по порту Centronics активным является "0".

Назначение пунктов меню :
 

Сброс - начинает "развертку" от начала окна

Стоп - остановка / запуск осциллографа, что позволяет "заморозить" изображение

Редактор - вызов окна редактирования регистров порта

Строб - выдача стробирующего импульса на линию STROBE

АРС - анализатор реакции на STROBE - скоростная запись на диск состояния регистров порта до, во время и после строба. Выбор этой опции приводит к переходу в окно анализа записанных данных.

Управление - вызов окна системы передачи управляющих команд и данных

INT 17h - вызов трасировщика прерывания INT 17h

Настройки - вызов окна настроек "осциллографа" , позволяющего задать скорость развертки

Информация - вызов окна с адресами портов

Помощь - вызов справки

Выход - выход из программы


Внизу окна осциллографа приведены состояния всех регистров контроллера порта. Они обновляются постоянно одновременно с осциллограммой.

2.3. Редактирование регистров порта
Для редактирования регистров порта необходимо активировать пункт меню "Редактор" и в появившемся окне изменить значения регистров.По умолчанию предлагаются текущие значения. При нажатии на кнопки "Записать" данные переписываются в регистры порта. Данные вводятся в DEC системе, для ввода в HEX системе введите после числа символ h. Пример: 10h. Для ввода бинарного числа необходимо ввести бинарное число и нажать "/".

2.4. Режим скоростной записи и анализа (АРС)
Имеющийся в главном окне программы "осциллограф" позволяет наблюдать процессы практически в статике (скорость обновления информации не более 18 Гц). Этого недостаточно ввиду того, что многие процессы (например, стандартный обмен по Centronics) имеют длительность порядка 1 мс. Поэтому в программе имеется иной подход к решению данной проблемы - опрос порта ведется с максимально возможной скоростью, а данные записываются на диск. Примерно в середине интервала записи генерируется строб. Это позволяет пронаблюдать реакцию устройства на строб и измерить длительность некоторых сигналов (в частности, Busy) и временные задержки между ними. По окончании цикла записи (он длится примерно секунду) данные записываются на диск для последующего детального анализа и активируется окно просмотра записанных данных в виде осциллограмм. При помощи курсорных клавиш можно переместиться на любой участок осциллограммы, на момент фронта строба или среза строба. Кроме того, имеется возможность повторять цикл записи не теряя позиции в окне просмотра. Предусмотрена возможность изменять масштаб от 1:1 до 1:10, анализировать все биты регистров порта в любой точке "осциллограммы".

На диске данные сохраняются в следующих файлах:
 

lpt_mon.oss - для регистра состояния

lpt_mon.osu - для регистра управления

     
2.5. Передача данных через INT 17h
Эмулятор INT 17h позволяет познакомиться с работой прерывания обслуживания принтера. Входными параметрами для прерывания INT 17h служат регистры :

AH - номер функции (0-2) :

0 - вывести на ПУ номер DX символ с кодом из AL и вернуть байт состояния принтера в регистре AH. Расшифровка битов регистра AH производится автоматически

1 - инициализировать порт принтера DX - сбрасывает порт принтера и возвращает байт состояния принтера в регистре AH.

2 - получить состояние принтера DX в регистр AH

AL - код выводимого символа для функции 0

DX - номер принтера (0 - LPT1, 1- LPT2, 2 - LPT3)

В редакторе регистров имеется контроль корректности введенных значений - если невозможно перейти из строки редактирования состояния регистра к соседним по TAB или курсорным клавишам и при этом компьютер "пикает", значит, введенное значение лежит за пределами допустимого диапазона. После вызова INT 17h программа выводит на экран слово состояния принтера и расшифровку значений каждого бита с комментариями.

2.6. Передача на принтер данных и управляющих кодов
Окно системы передачи данных и команд на принтер вызывается из главного меню активацией пункта "Управление". Данное окно позволяет передать на принтер некоторые управляющие коды, а так же передать любой набор символов и кодов.

Для передачи управляющего кода необходимо выбрать его в меню и нажать Eсостояния линии 010 - принят символ; сброс - чтение регистра приемника

110 - индикатор тайм-аута (4-х кратный интервал времени передачи символа). Генерируется, если в FIFO буфере есть символы

001 - регистр передатчика пуст; сброс - запись в регистр передатчика 

000 - изменение состояния модема; сброс - чтение регистра состояния модема

Регистр управления FIFO (только для записи, только 16550+) - таблица 3.9. Для очистки буферов FIFO необходимо запретить и затем снова разрешить режим FIFO.

Для задания основных параметров адаптера применяется регистр управления линией (табл. 3.10). Бит 7 регистра управления линией называется DLAB и предназначен для определения назначения регистров 0 и 1. Он устанавливается в 1 только на время программирования делителя управления скоростью передачи.

Таблица 3.9.


Регистр управления FIFO

БитЗначение
7,6Уровень заполнения FIFO буфера, при котором генерируется прерывание (00 - 1 байт, 01 - 4 байта, 10 - 8 байт, 11 - 14 байт)
5,4Резерв
3Разрешение операций DMA
2Сброс счетчика FIFO передатчика
1Сброс счетчика FIFO приемника
Разрешение ("1") режима FIFO для передатчика и приемника. При смене режима FIFO буфера очищаются!
Таблица 3.10
Регистр управления линией

 



 
 
 
БитЗначение
7DLAB. Управление доступом к регистрам адаптера интерфейса.

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 бит.

Регистр управления модемом позволяет управлять модемом, назначение битов приведены в табл. 3.11.
 

Таблица 3.11


Регистр управления модемом

БитЗначение
7,6,5=0 - резерв
4"0" - нормальный режим, "1" - режим диагностики 
3OUT2 инверсный (разрешить прерывания от RS-232)
2OUT1 инверсный (используется только в режиме диагностики)
1RTSC - управление выходом RTS 

("1" - активен (-V), "0" - пассивен (+V))

0DTRС - управление выходом DTR 

("1" - активен (-V), "0" - пассивен (+V))

В режиме диагностики выход передатчика переводится в состояние "1", вход приемника отключается, выход сдвигающего регистра передатчика логически соединяется с входом приемника; входы DSR, CTS, RI, DCD отключаются от входных линий и соединяются с DTRС, RTSC, OUT1, OUT2 соответственно, выходы управления модемом переводятся в пассивное состояние. Переданный в таком режиме байт должен немедленно приниматься, что позволяет проверять внутренние каналы данных порта и сдвиговые регистры.
 
 

Таблица 3.12.


Регистр состояния линии

БитЗначение
7*Ошибка принятых данных в режиме FIFO (буфер FIFO содержит хотя бы один символ, принятый с ошибкой).
6Буфер передатчика пуст (символов нет ни в регистре передатчика, ни в сдвиговом регистре, ни в буфер FIFO)
5Сдвиговый регистр передатчика пуст (буфер FIFO передатчика пуст). Может генерировать прерывание.
4BD Индикатор обрыва линии (на входе приемника "0" не менее, чем время посылки одного символа)
3FE Ошибка кадра (Стоп-бит не найден) 
2PE Ошибка контрольного бита
1OE Ошибка переполнения. Означает потерю символа (имеет аналогичный смысл в режиме FIFO)
0DR принятые данные готовы. Сбрасывается при чтении регистра приемника

Регистр состояния линии позволяет определить состояние приемопередатчика (таблица 3.12).

Регистр состояния модема (табл. 3.13) позволяет определить состояние модема. Биты 3-0 вызывают прерывание "Изменение состояние модема". "1" в любом из этих битов свидетельствует о том, что состояние линии изменилось по сравнению с состоянием на момент последнего чтения этого регистра.
 
 

Таблица 3.13.


Регистр состояния модема

БитЗначение
7Состояние линии DSD
6Состояние линии RI
5Состояние линии DSR
4Состояние линии CTS
3Изменение DSD
2Изменение RI
1Изменение DSR
0Изменение STS

3.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 бит/слово

; (см. табл. 3.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 ; Передача
 
 

3.5. Работа с COM портом через INT 14h

BIOS представляет программе пользователя набор стандартных функций для работы с последовательным портом. Данное прерывание может быть перехвачено или замещено программой - драйвером. Вниманию программистов : не все программы, выводящие информацию на ПУ, работают через INT 17h. Кроме того, при перекодировке символов нельзя перекодировать символы, входящие в состав команд языка управления ПУ. Параметры вызова основных функций приведены в таблице 3.14. Байты состояния линии и модема, возвращаемые обработчиком INT 14h, полностью соответствуют регистру состояния линии и регистру состояния модема адаптера порта.

Таблица 3.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= состояние модема

Таблица 3.15.


Параметры инициализации порта

БитыЗначение
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 бит

3.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 ; Конец программы
 

3.7. Эмуляция последовательного порта при помощи параллельного
При решении ряда задач может возникнуть потребность в организации нестандартного последовательного интерфейса. Например, такая проблема возникает при программировании контроллеров фирмы ATMEL, требующих применения синхронного последовательного интерфейса (синхронизируется каждый бит), причем байты данных передаются без старт и стоп-битов пакетами по три байта. В такой ситуации можно эмулировать последовательный интерфейс с использованием аппаратной части параллельного интерфейса. При этом программно эмулируется сдвиговый регистр и тактовый генератор.

Пример процедуры для синхронной передачи байта:

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".
 


Список литературы

  1. Е.П. Бененсон, И.М. Витенберг, В.В. Мельников и д.р. Печатающие устройства персональных для ЭВМ: Справочник /: Под ред. И.М. Витенберга. - М.: Радио и связь, 1992.-208 с.
  2. Гук М. Аппаратные средства IBM PC. Энциклопедия - СПб: Питер Ком, 1999. - 816 с.
  3. Р. Браун, Дж. Кайл. Справочник по прерываниям IBM PC: В 2-х томах: Т.1. Пер. с англ. -М.: Мир , 1994.-558
  4. Данкан Р. Профессиональная работа в MS-DOS: Пер. с англ. -М.: Мир, 1993.-509 с., ил.
  5. В.Н. Пильщиков. Программирование на языке ассемблера IBM PC.- M.: Диалог - МИФИ, 1997.-288 с.
Приложение
4Выход: "термина готов к передаче данных"DSR66Вход сигнала готовности от аппаратуры передачи данныхDCD81Вход сигнала обнаружения несущей удаленного модемаRI229Вход индикатора вызова (звонка)

3.2.3. Управление потоком данных.

Для управления потоком данных могут использоваться два вида протоколов - аппаратный и программный. Не следует путать термин "управление потоком" с термином "квитирование". Квитирование - посылка уведомления о получении элемента, в то время как управление потоком предполагает посылку уведомления о временной невозможности последующего приема данных.

Аппаратный протокол управления RTS/CTS. Использует сигнал CTS, который позволяет остановить передачу данных, если приемник не готов к работе. Передача данных по этому протоколу показана на рис. 3.3 а. Байт, передаваемый на момент прихода CTS, будет передан, однако с момента окончания его передачи передатчик переходит к ожиданию готовности приемника (т.е. снятия CTS). Обеспечивает самую быструю реакцию передатчика на состояние приемника, позволяет организовать обмен, не прибегая к буферизации. Часто используется в принтерах и для соединения компьютеров. В случае с принтером линия CTS ПК должна соединяться с линией RTS принтера, при соединении двух ПК необходимо перекрестное соединение CTS-RTS. Если аппаратный протокол обмена не используется, то на линию CTS ПК необходимо подать сигнал "включено", что обычно достигается соединением CTS ПК с его же RTS перемычкой на разъеме. Аппаратный обмен невозможен через минимальный нуль-модемный кабель.


Рис. 3.3

Аппаратный протокол DTR/DSR. Аналогичен RTS/CTS, но использует другую пару сигналов (в данном случае "готовность приемника").

Программный протокол XON/XOFF. Предполагает наличие двунаправленного канала обмена. Временные диаграммы обмена показаны на рис. 3.3 б. Предполагает наличие у приемника буфера, так как время реакции передатчика tp может оказаться достаточно большим. Когда буфер приемника заполняется до определенного уровня (обычно 80-90%), он передает на приемник команду XOFF (байт с кодом 13h). Приняв эту команду, передатчик прекращает передачу и переходит в состояние ожидания до прихода команды XON (байт с кодом 11h), по которому передатчик возобновляет передачу.
Распайки кабелей для подключения принтера по протоколам XON/ XOFF и RTS/CTS приведены в приложении 1.

Программный протокол ACK. При обмене по этому протоколу для получения очередного байта приемник посылает передатчику команду ACK (байт с кодом 6h). В ответ передатчик посылает приемнику один байт (или пакет байт определенного размера).
 


3.3. Работа с COM портом на низком уровне

3.3.1. Микросхемы асинхронных приемопередатчиков и особенности работы с ними.

Преобразование параллельного кода в последовательный при передаче и последовательного в параллельный при приме, контроль ошибок, формирование запросов прерывания и ряд других сервисных функций осуществляется специализированной микросхемой, называемой UART (Universal Asynchronous Receiver -Transmitter) или УАПП (Универсальный Асинхронный Приемопередатчик). COM порты IBP PC базируются на микросхемах, совместимых на уровне регистров с UART i8250 - 8250/16450/16450A. Каждая из перечисленных микросхем совместима с предыдущей, но не наоборот. Это следует учитывать при составлении программы управления - если программа ориентирована на i8250, то она будет работать со всеми последующими модификациями УАПП. В ряде отечественных ЭВМ применялись микросхем КР580ВВ51 - аналог i8251, т.н. УСАПП (USART) - универсальный синхронно-асинхронный приемопередатчик. Эта микросхема не совместима на уровне регистров с i8250, однако в современных ПК она не применяется (подробнее см. [4]).
Сравнительные характеристики УАПП, совместимых с i8250 приведена в таблице 3.4. Все микросхемы серии 8250 обладают низким быстродействием и не допускают обращения к своим регистрам в смежных циклах процессора - для корректной работы между обращениями организуют программные задержки (команда типа JMP $+2)
 

Таблица 3.4.


Характеристики 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 бит/сек и более без потери данных. 
С 16550А совместимо подавляющее большинство микросхем - контроллеров COM парта современных ПК. Особенностью 16550 и 16550А является то, что они имеют дополнительные, по сравнению с 8250, регистры. Многие биты, считающиеся в 8250 резервом, в 16550 задействованы для управления его новыми функциями. Однако, все регистры 8250 совпадают с соответствующими регистрами 16550, что обеспечивает совместимость. Внимание: если программа, нормально работающая с 8250, некорректно работает с 16550, то необходимо проверить, как используются резервные (в спецификации 8250) биты некоторых регистров - часто в них записывается неопределенная информация, что и приводит к сбоям (должны записываться нули).
3.3.2. Структура регистров УАПП 16550A
У контроллера последовательного интерфейса имеется 8 регистров, занимающих смежные адреса в пространстве устройств ввода-вывода (таблица 3.5). Следует обратить особое внимание на то, что регистров реально больше: при чтении регистра 0 байт читается из регистра приемника, при записи байт запишется в регистр передатчика. Кроме того, регистры 0 и 1 мультиплексируются битом 7 регистра управления (3). Когда этот бит равен 0 (нормальное рабочее состояние), регистр 0 является регистром приемопередатчика, а регистр 1 задает маску прерываний. Когда этот бит равен 1, то регистры 0 и 1 применяются для чтения/записи старшего и младшего байтов делителя, определяющего скорость обмена. Значение делителя определяется по формуле:

,

где V - скорость передачи в бит/с. Входная частота синхронизации 1.8432 МГц делится адаптером на К и получается 16-ти кратная частота передачи.

Базовый адрес COM порта определяется путем чтения переменных BIOS, адреса которых приведены в таблице 3.5. Стандартным адресом порта COM является 3F8h, COM2 - 2F8h. Перед работой с портом рекомендуется определить его адрес путем чтения переменной BIOS, а не брать стандартное значение. Назначение регистров UART и их адреса относительно базового приведены в таблице 3.6.
 

Таблица 3.5.


Адреса переменных BIOS для COM портов.

Имя портаАдрес в BIOSТип переменнойОписание
COM10040:0000hWordБазовый адрес порта COM1. Если переменная равна 0, то порт не найден
COM20040:0002hWord--//--
COM30040:0004hWord--//--
COM40040:0006hWord--//--
Таблица 3.6.
Регистры UART 16550A
СмещениеDLABR/W8250Значение
0
1

0

0

R/W

WO

RO

+-

++

++

Регистр скорости обмена (LO) (табл. 3.7)

Регистр передатчика

Регистр приемника

1
1

0

R/W

R/W

+-

+-

Регистр скорости обмена (HI) (табл. 3.8)

Регистр маски разрешения прерываний (табл. 3.9)

2
x

x

RO

WO

+-

-

Регистр идентификации прерываний 

Регистр управления FIFO

3
x

x

R/W+Регистр управления линией (настройка параметров канала (табл. 3.11)
4xR/W*+Регистр управления модемом (табл. 3.12)
5xR/W*+Регистр состояния линии (табл. 3.13)
6xR/W+Регистр состояния модема (табл. 3.14)
7xR/W-Рабочий регистр для временного хранения данных

Примечания:

1. * - некоторые биты допускают только чтение

2. "8250" - столбец, содержащий признак степени совместимости с 8250 (+ полная, '+-' - частичная, '-' - отсутствует в 8250).

  1. DLAB - состояние бита 7 регистра управления линией
  2. При помещении байта в буфер передатчика он немедленно передается.

  3. 3.3.3. Описание регистров УАПП 16550A

В таблицах значком * отмечены биты, не используемые в 8250.

Регистр разрешения прерываний. Единичное значение бита соответствует разрешению прерывания, назначение битов приведено в таблице 3.7. Если работа с портом идет без использования прерываний, то их следует запретить путем записи 0 в этот регистр.

     
    Таблица 3.7.


    Регистр разрешения прерываний

    БитЗначение
    7,6,5,4=0, не используются
    3по изменении статуса модема (STS, DSR, RI, RLSD )
    2по ошибке приема данных
    1по завершению передачи
    0по приему символа ( в режиме FIFO - по тайм-ауту)

    Регистр идентификации прерываний. Ввиду того, что контроллер обслуживается одним прерыванием, а возникать оно может, в общем случае, в 4-х различных ситуациях, процедуре обработки прерывания необходимо выяснить, по какой причине произошло прерывание.
     
     

    Таблица 3.8.


    Регистр идентификации прерываний

    БитЗначение
    7,6*Признак режима FIFO:

    11 - FIFO 16550А, 10 - FIFO 16550, 00 - обычный

    5, 4не используются
    3*прерывание по тайм-ауту (не в режиме FIFO)
    2,100 - прерывание от приемника; 01 - есть данные в приемнике

    10 - буфер передатчика пуст; 11 - изменение статуса модема

    01 - нет запроса прерывания, 0 - есть запрос

    В режиме FIFO биты 3-0 имеют иной смысл:
     
    2,1,0*011 - обрыв ошибка/обрыв линии; сброс - чтение регистра состояния линии 010 - принят символ; сброс - чтение регистра приемника110 - индикатор тайм-аута (4-х кратный интервал времени передачи символа). Генерируется, если в FIFO буфере есть символы

    001 - регистр передатчика пуст; сброс - запись в регистр передатчика 

    000 - изменение состояния модема; сброс - чтение регистра состояния модема

    Регистр управления FIFO (только для записи, только 16550+) - таблица 3.9. Для очистки буферов FIFO необходимо запретить и затем снова разрешить режим FIFO.

    Для задания основных параметров адаптера применяется регистр управления линией (табл. 3.10). Бит 7 регистра управления линией называется DLAB и предназначен для определения назначения регистров 0 и 1. Он устанавливается в 1 только на время программирования делителя управления скоростью передачи.

    Таблица 3.9.


    Регистр управления FIFO

    БитЗначение
    7,6Уровень заполнения FIFO буфера, при котором генерируется прерывание (00 - 1 байт, 01 - 4 байта, 10 - 8 байт, 11 - 14 байт)
    5,4Резерв
    3Разрешение операций DMA
    2Сброс счетчика FIFO передатчика
    1Сброс счетчика FIFO приемника
    Разрешение ("1") режима FIFO для передатчика и приемника. При смене режима FIFO буфера очищаются!
    Таблица 3.10
    Регистр управления линией

     



     
     
     
    БитЗначение
    7DLAB. Управление доступом к регистрам адаптера интерфейса.

    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 бит.

    Регистр управления модемом позволяет управлять модемом, назначение битов приведены в табл. 3.11.
     

    Таблица 3.11


    Регистр управления модемом

    БитЗначение
    7,6,5=0 - резерв
    4"0" - нормальный режим, "1" - режим диагностики 
    3OUT2 инверсный (разрешить прерывания от RS-232)
    2OUT1 инверсный (используется только в режиме диагностики)
    1RTSC - управление выходом RTS 

    ("1" - активен (-V), "0" - пассивен (+V))

    0DTRС - управление выходом DTR 

    ("1" - активен (-V), "0" - пассивен (+V))

    В режиме диагностики выход передатчика переводится в состояние "1", вход приемника отключается, выход сдвигающего регистра передатчика логически соединяется с входом приемника; входы DSR, CTS, RI, DCD отключаются от входных линий и соединяются с DTRС, RTSC, OUT1, OUT2 соответственно, выходы управления модемом переводятся в пассивное состояние. Переданный в таком режиме байт должен немедленно приниматься, что позволяет проверять внутренние каналы данных порта и сдвиговые регистры.
     
     

    Таблица 3.12.


    Регистр состояния линии

    БитЗначение
    7*Ошибка принятых данных в режиме FIFO (буфер FIFO содержит хотя бы один символ, принятый с ошибкой).
    6Буфер передатчика пуст (символов нет ни в регистре передатчика, ни в сдвиговом регистре, ни в буфер FIFO)
    5Сдвиговый регистр передатчика пуст (буфер FIFO передатчика пуст). Может генерировать прерывание.
    4BD Индикатор обрыва линии (на входе приемника "0" не менее, чем время посылки одного символа)
    3FE Ошибка кадра (Стоп-бит не найден) 
    2PE Ошибка контрольного бита
    1OE Ошибка переполнения. Означает потерю символа (имеет аналогичный смысл в режиме FIFO)
    0DR принятые данные готовы. Сбрасывается при чтении регистра приемника

    Регистр состояния линии позволяет определить состояние приемопередатчика (таблица 3.12).

    Регистр состояния модема (табл. 3.13) позволяет определить состояние модема. Биты 3-0 вызывают прерывание "Изменение состояние модема". "1" в любом из этих битов свидетельствует о том, что состояние линии изменилось по сравнению с состоянием на момент последнего чтения этого регистра.
     
     

    Таблица 3.13.


    Регистр состояния модема

    БитЗначение
    7Состояние линии DSD
    6Состояние линии RI
    5Состояние линии DSR
    4Состояние линии CTS
    3Изменение DSD
    2Изменение RI
    1Изменение DSR
    0Изменение STS

    3.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 бит/слово

    ; (см. табл. 3.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 ; Передача
     
     

    3.5. Работа с COM портом через INT 14h

    BIOS представляет программе пользователя набор стандартных функций для работы с последовательным портом. Данное прерывание может быть перехвачено или замещено программой - драйвером. Вниманию программистов : не все программы, выводящие информацию на ПУ, работают через INT 17h. Кроме того, при перекодировке символов нельзя перекодировать символы, входящие в состав команд языка управления ПУ. Параметры вызова основных функций приведены в таблице 3.14. Байты состояния линии и модема, возвращаемые обработчиком INT 14h, полностью соответствуют регистру состояния линии и регистру состояния модема адаптера порта.

    Таблица 3.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= состояние модема

    Таблица 3.15.


    Параметры инициализации порта

    БитыЗначение
    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 бит

    3.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 ; Конец программы
     

3.7. Эмуляция последовательного порта при помощи параллельного
При решении ряда задач может возникнуть потребность в организации нестандартного последовательного интерфейса. Например, такая проблема возникает при программировании контроллеров фирмы ATMEL, требующих применения синхронного последовательного интерфейса (синхронизируется каждый бит), причем байты данных передаются без старт и стоп-битов пакетами по три байта. В такой ситуации можно эмулировать последовательный интерфейс с использованием аппаратной части параллельного интерфейса. При этом программно эмулируется сдвиговый регистр и тактовый генератор.

Пример процедуры для синхронной передачи байта:

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".
 


Список литературы

  1. Е.П. Бененсон, И.М. Витенберг, В.В. Мельников и д.р. Печатающие устройства персональных для ЭВМ: Справочник /: Под ред. И.М. Витенберга. - М.: Радио и связь, 1992.-208 с.
  2. Гук М. Аппаратные средства IBM PC. Энциклопедия - СПб: Питер Ком, 1999. - 816 с.
  3. Р. Браун, Дж. Кайл. Справочник по прерываниям IBM PC: В 2-х томах: Т.1. Пер. с англ. -М.: Мир , 1994.-558
  4. Данкан Р. Профессиональная работа в MS-DOS: Пер. с англ. -М.: Мир, 1993.-509 с., ил.
  5. В.Н. Пильщиков. Программирование на языке ассемблера IBM PC.- M.: Диалог - МИФИ, 1997.-288 с.
Приложение