Студопедия

КАТЕГОРИИ:


Архитектура-(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-й бит числа Х.

A                
OR                
               
результат                

На языке Pascal данный пример записывается так:

Y: = A OR 4;

4. Сбросить один бит в 0 (не трогая остальные). Для этого необходимо сначала прочитать содержимое порта (обозначим буквой A). Затем с помощью логической операции «исключающее или» (XOR) получаем новое значение, но уже со сброшенным битом.

Например, необходимо изменить 4-й бит числа Х.

A                
XOR                
               
результат                

 

На языке 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; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.009 сек.