КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Программирование параллельного порта
5.4.1. Доступ к пространству ввода-вывода в различных операционных системах Операционные системы, используемые в настоящее время, отличаются друг от друга в предоставлении программам доступа к портам ввода-вывода. Управление параллельным портом осуществляется через три порта ввода-вывода, следовательно, и программирование параллельного порта в разных операционных системах (ОС) будет отличаться. 1. Операционные системы MS-DOS. Эти ОС предоставляют программам полную свободу доступа к портам, не осуществляя никакого контроля. Однако это потенциально может привести к проблемам, например, если две программы будут работать с одним и тем же портом. 2. Операционные системы на платформе Windows 95 (Windows 95/98/Millenium). Эти ОС разработаны с расчетом на программную совместимость с MS-DOS, поэтому также дают программам прямой доступ к портам. Однако в них реализован и более совершенный механизм (рис. 5.4), при котором доступ к порту ввода-вывода осуществляется через специальную программу – драйвер. В этом случае программа обращается к драйверу с «просьбой» записать или прочитать данные, а драйвер уже сам выполняет необходимые действия. Этот механизм позволяет исключить сбои операционной системы, если две программы обратятся к одному порту; в этом случае драйвер просто откажется выполнять запросы одной из программ; также некорректно работающая с портом программа не сможет вызвать сбой – драйвер просто не сможет выполнить некорректные инструкции. 3. Операционные системы на платформе Windows NT (Windows NT/2000/XP). Эти ОС запрещают программам прямой доступ к портам. Доступ предоставляется только через драйвер. При выборе способа доступа к портам следует ориентироваться на операционную систему, в которой будет работать программа. Наиболее простой для программирования способ – прямой доступ к портам, но он будет работать не на любом компьютере (зависит от ОС). Доступ через драйвер – наиболее универсальный способ, однако он требует наличия драйвера, которого может и не быть в наличии. Примечание: драйвер может быть написан разработчиком, однако это требует высокой квалификации программиста; разработка драйвера здесь не рассматривается. Рис. 5.4. Доступ к портам ввода-вывода в разных операционных системах 5.4.2. Операции с битами Операции записи/чтения портов происходят побайтно, т.е. записывается или читается сразу байт (8 бит) информации. Между тем часто надо узнать или изменить состояние только одного бита из 8-ми. Таким образом, необходимо знать (и уметь запрограммировать) следующие операции: 1. Перевод из двоичной системы счисления в десятичную. (5.1) Например: 255=11111111, 0=00000000, 78=01001110, 165=10100101 2. Перевод в десятичную систему одного (i-го) бита: (5.2) Например: 00100000=25=32, 00000100=22=4, 00000001=20=1 3. Установить один бит в 1 (не трогая остальные). Для этого необходимо сначала прочитать содержимое порта (обозначим буквой A). Затем с помощью логической операции «или» (OR) получаем новое значение, но уже с установленным битом. Например, необходимо изменить 2-й бит числа Х.
На языке Pascal данный пример записывается так: Y: = A OR 4; 4. Сбросить один бит в 0 (не трогая остальные). Для этого необходимо сначала прочитать содержимое порта (обозначим буквой A). Затем с помощью логической операции «исключающее или» (XOR) получаем новое значение, но уже со сброшенным битом. Например, необходимо изменить 4-й бит числа Х.
На языке Pascal данный пример записывается так: Y: = A XOR 16;
5.4.3. Прямой доступ к портам ввода-вывода
Работоспособен в операционных системах MS-DOS и на платформе Windows 95. Рассматриваемые здесь примеры могут быть использованы при разработке программ в средах Turbo Pascal, Borland Pascal (для MS-DOS) и в Borland Delphi (для Windows 95). Цель: прочитать содержимое определенного порта ввода-вывода или записать байт в порт. Решение: наиболее простой и понятный способ – включить в программу т.н. ассемблерную вставку, то есть фрагмент программы на языке ассемблер. Язык Pascal допускает это. Средства: ассемблерная вставка заключается в операторные скобки asm... end;. Используются следующие команды ассемблера: MOV регистр, число; - запись числа в регистр процессора; MOV регистр, переменная; - запись в регистр содержимого переменной. Если регистр 8-разрядный (регистры al, ah, bl, bh, cl, ch, dl, dh), то переменная должна быть типа Byte. Если регистр 16-разрядный (регистры ax, bx, cx, dx), то тип переменной должен быть Word; OUT регистр1, регистр2; - вывод байта, записанного в 8-разрядном регистр2 в порт с адресом, записанным в 16-разрядном регистр1; IN регистр2, регистр1; - чтение байта из порта с адресом в 16-разрядном регистр1 и помещение его в 8-разрядный регистр2. Например, для записи числа 255 в порт 378h необходимо использовать следующий фрагмент:
asm mov al, 255; mov dx, $378; out dx, al; end;
Для записи произвольного байта в пор 378h можно использовать следующую процедуру:
Procedure WritePort(DataByte: Byte); begin asm mov al, DataByte; mov dx, $378; out dx, al; end; end; Для чтения байта из порта 379h можно использовать следующую функцию: Function ReadPort:Byte; var DataByte:Byte; begin asm mov dx, $379; in al, dx; mov DataByte, al; end; ReadPort:=DataByte; end;
5.4.4. Доступ к портам через драйвер В данном разделе приводится описание использования драйвера параллельного порта Lptwdmio.sys и модуля Lptio.pas для работы с ним. Драйвер и модуль разработаны В. Ковтуном. Согласно условиям распространения, поставляемым вместе с драйвером, и драйвер и модуль могут использоваться, модифицироваться, распространятся совершенно свободно. Для того чтобы использовать драйвер, его необходимо установить. Установка производится обычным способом как установка нестандартного устройства. Для ОС Windows 95/98/Millenium: «Панель управления» ® «Установка оборудования» ® «Выбор из списка» ® «Другие устройства» ® «Установить с диска» ® «Указать файл lptwdmio.inf». Установка драйвера на ОС Windows NT/2000/XP осуществляется аналогично, но при этом пользователь должен обладать административными полномочиями. 5.4.4.1. Модуль Lptio Модуль разработан для использования в среде Delphi; он дает возможность в удобной форме пользоваться драйвером lptwdmio. Для того чтобы воспользоваться модулем Lptio, его необходимо подключить к своей программе в разделе Uses: Uses …, …, …, Lptio; Однако при этом необходимо позаботится, чтобы при компиляции программы Delphi нашла файлы Lptio.pas и Lptio.dcu. Лучше всего скопировать их в каталог с файлами разрабатываемого проекта. В модуле Lptio определен класс TLptPortConnection. В программе необходимо создать объект этого класса и работать уже с ним. Пример создания такого объекта (ниже приведено начало обычного модуля формы):
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Lptio; type TForm1 = class(TForm) private Lpt: TLptPortConnection; public end; .....
Объект класса TlptPortConnection предоставляет в распоряжение пользователя ряд функций и констант.
5.4.4.2. Нумерация портов и регистров
Обращения к регистрам портов производятся по их логическим номерам. Номер составляется из номера порта и номера регистра, соединяемых операцией OR. Логический номер имеет размер 1 байт. В модуле LPTIO.pas определены следующие константы:
Номера портов: LPT1: byte = $10; - база $3BC LPT2: byte = $20; - $378 LPT3: byte = $30; - $278 Смещения регистров порта LPT_DATA_REG: byte = 0; Регистр данных LPT_STATE_REG: byte = 1; Регистр состояния LPT_CONTROL_REG: byte = 2; Регистр управления LPT_EPP_ADDRESS: byte = 3; Регистр адреса EPP LPT_EPP_DATA: byte = 4; // Регистр данных EPP Например, логический номер регистра управления порта LPT2: (LPT2 or LPT_CONTOL_REG) при этом обращение будет выполняться по адресу $378+2 = $37A.
5.4.4.3. Нумерация отдельных бит регистров Побитная раскладка регистров порта LPT определена в виде двух наборов констант - для регистров управления и для регистров состояния: Битовый расклад регистра управления: STROBE: byte = $01; AUTOFEED: byte = $02; INIT: byte = $04; SELECTIN: byte = $08; IRQE: byte = $10; DIRECTION: byte = $20; Битовый расклад регистра состояния: IRQS: byte = $04; ERROR: byte = $08; SELECT: byte = $10; PAPEREND: byte = $20; ACK: byte = $40; BUSY: byte = $80; Эти значения могут быть использованы, например для управления состоянием отдельных линий. Например, вот так можно установить бит INIT в регистре управления порта LPT1: Lpt.WritePort (LPT1, LPT_CONTROL_REG, (INIT or Lpt.ReadPort (LPT1,LPT_CONTROL_REG))); 5.4.4.4. Функции тестирования порта function Ready: boolean; Возвращает признак готовности (true) или неготовности (false). function IsNtPlatform: boolean; Функцияя возвращает true, если работаем на платформе NT. Иначе - false. function IsPortPresent(LptNumber: byte): boolean; Функция тестирования наличия порта. Возвратит true, если порт присутствует. function IsPortBidirectional(LptNumber: byte): boolean; Функция тестирования порта на двунаправленность. Если порт двунаправленный, возвратит true. Если функция Ready сразу после создания объекта возвращает false, это значит, что объект не смог связаться с драйвером. При работе под ОС Windows 95/98/Me такой ситуации не возникает, т.к. если драйвер не установлен, объект класса TLptConnection будет использовать прямые обращения к регистрам портов. Примечание: нет никакой необходимости создавать несколько экземпляров объектов класса TLptConnection.
5.4.4.5. Функции для вывода данных Этих функций две: WritePorts() и WritePort(). WritePorts() предназначена для вывода пакета данных (множество значений). Определена следующим образом: function WritePorts(PairArray: PADRDATASTRUCT; PairCount: cardinal): boolean;
PairArray должен указывать на массив структур типа ADRDATASTRUCT: ADRDATASTRUCT = record Adr: byte; { адрес == <Номер порта> or <Смещение регистра> } Data: byte; { данные для вывода или место для прочитанного байта } end; Массив передаётся в драйвер полностью, цикл по структурам происходит внутри самого драйвера. Для каждой структуры выполняется вывод данных в регистр порта. Это позволяет выдавать данные в порты с максимальной скоростью, причём акт выдачи такого блока данных не может быть прерван до его завершения другими пользовательскими приложениями, что весьма удобно для реализации протоколов передачи, критичных ко времени. Параметр PairCount - должен содержать количество структур в массиве PairArray. WritePort() предназначена для вывода одиночного байта в указанный порт. procedure WritePort (LptNumber: byte; RegOffset: byte; Value: byte); Здесь LptNumber - одна из констант LPT1..LPT3, определяет номер порта, RegOffset - одна из констант LPT_DATA_REG, LPT_STATE_REG, LPT_CONROL_REG, определяет номер регистра порта. Value - значение, которое будет выведено в указанный регистр.
5.4.4.6. Функции для ввода данных
Для ввода данных предназначены функции ReadPorts() и ReadPort(). function ReadPorts (PairArray: PADRDATASTRUCT; PairCount: cardinal): boolean; Параметры задаются аналогично WritePorts(), отличие в том, что при выполнении этой процедуры в поля Data каждой структуры ADRDATASTRUCT будут записаны значения, прочитанные из регистров портов, номера которых (<порт> or <регистр>) были указаны в полях Adr. Функция возвращает false, если объект TLptConnection не готов к работе или если произошла ошибка в драйвере.
function ReadPort (LptNumber: byte; RegOffset: byte): byte;
Параметры задаются аналогично WritePort(). Возвращаемое значение - результат чтения регистра порта.
Дата добавления: 2015-04-29; Просмотров: 2019; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |