Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Программирование параллельного порта

Поиск

 

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(). Возвращаемое значение - результат чтения регистра порта.

 

КОНТРОЛЛЕРЫ СЕРИИ ALPHA



Поделиться:


Последнее изменение этой страницы: 2016-08-16; просмотров: 1009; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.105.101 (0.007 с.)