4th
Июн

Работа с LPT портом в Дельфи или компьютер в роли управляющего контроллера. Часть 1

Posted by bullvinkle under Журнал, Статьи

Большинство пользователей персонального компьютера привыкли к тому, что весь результат деятельности на компьютере в той или иной степени все равно отражается в самом компьютере. В крайнем случае, отправляется на принтер или в Интернет, или же запись информации происходит на внешние носители (диски, флеш-память и т.п.). И уж мало кто задумывается, что с помощью простого РС – компьютера можно управлять различными внешними физическими устройствами.

Рис. 1. «Рабочая лошадка LPT еще даст о себе знать»

Рис. 1. «Рабочая лошадка LPT еще даст о себе знать»

Владимир Дегтярь

by DeKot degvv@mail.ru

Тем не менее, на форуме http://www.programmersforum.ru (да и на других также) часто появляются вопросы: «Как с компьютера зажечь светодиод?», «Как управлять освещением?» или «Можно ли компьютером закрывать шторы на окне?». Ответ:  «…однозначно да». С помощью современного персонального компьютера можно создавать, воспроизводить, управлять, хранить, моделировать, обучать и еще реализовать много и много других функций.

Введение

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

Думаю что уже достаточно теории. Перейдем к практической реализации – управлению реальными устройствами с помощью компьютера. Более всего для этого подходит «параллельный» порт LPT. Более подробно смотрим о LPT http://ru.wikipedia.org/wiki/IEEE_1284.

Параллельный порт LPT

Итак, почему параллельный, а не перпендикулярный? А какие еще бывают? Параллельный, потому что информация через такое устройство передается параллельным способом. А еще может передаваться последовательным – тогда устройство (порт) называется последовательным (последовательные порты компьютера: COM-порт, USB- порт). Наглядно это можно увидеть на рисунке 2:

Рис. 2. Методы вывода информации

Рис. 2. Методы вывода информации

Рис. 3. Распиновка LPT

Аналогично ввод информации также может быть параллельным или последовательным. Порты (устройства) через которые можно вводить и выводить информацию называют двунаправленными устройствами или устройствами ввода/вывода. Таким и есть параллельный порт LPT, имеющийся в большинстве компьютеров. Посмотрим, что из себя представляет этот порт (см. рисунок 3):

Табл. 1. Распределение выводов LPT по регистрам

где С0…С3 – регистры контроля, S3…S7 – регистры статуса, D0…D7 – регистры данных

Как видите, это такой разъем с 25-ю выводами на задней стенке системного блока компьютера. Итак, имеем физический порт LPT, который фактически состоит из трех регистров. Состав регистров и распределение по контактам разъема приведены в таблице 1:

Табл. 1. Распределение выводов LPT по регистрам

Табл. 1. Распределение выводов LPT по регистрам

Каждый из регистров может содержать байт информации (256 состояний). Часть битов не используется или используется только во внутренней архитектуре компьютера для организации прерываний при работе с принтером или для переключения режимов ввод/вывод регистра «Data».

Регистр данных «Data», номер регистра в шестнадцатеричной системе счисления $378 (в десятичной 888) – двунаправленный, восьмибитный. Данные через этот регистр можно как вводить, так и выводить с компьютера, программно устанавливая уровни на выходе порта или же вводить в компьютер, также программно считывая уровни, устанавливаемые внешними устройствами.

Регистр управления «Control» $37A (890). Через него можно только выводить информацию из компьютера. На разъем LPT выводятся четыре младших байта.

Регистр статуса «Status» $379 (889). Через порт можно только считывать уровни, установленные внешними устройствами. На разъем LPT выведены пять старших байтов.

Таким образом, на разъеме LPT задействовано 17 сигнальных контактов (8 двунаправленных – регистр 888, четыре только на вывод информации – регистр 890 и пять только на ввод информации – регистр 889).

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

Следует отметить, что в некоторых компьютерах может быть до трех портов LPT: LPT1, LPT2, LPT3 (в  современных компьютерах LPT порты зачастую вообще отсутствуют). Адрес самого LPT порта соответствует адресу регистра «Data» и может быть $278, $378 или $3BC. Регистры в соответствующих портах имеют адресацию +1 и +2.

Следующие таблицы (см. таблицы 2, 3) показывают эти особенности данного порта. Для регистра $378 (888) соблюдается полное соответствие между уровнями напряжения на контактах и логическим кодом. А вот с регистрами $379 (889) и $37A (890) все обстоит по-другому:

Табл. 2. Порт $37A (890) «Control»

Табл. 2. Порт $37A (890) «Control»

Табл. 3. Порт $379 (889) «Status»

Табл. 3. Порт $379 (889) «Status»

Управление регистрами

В компьютерах с операционными системами MS-DOS, Windows 9x возможен доступ к портам непосредственно из самой операционной системы, тогда как в системах с NT такой прямой доступ невозможен. Для этих целей используются драйвера в виде библиотек (Inpout32.dll, WinIO, Giveo). Подключив соответствующие библиотеки к средам программирования, получаем возможность программно работать с портами (считывание состояния порта или установка выводов порта в необходимое состояние).

* Автор отдает предпочтение библиотеке <inpout32.dll> для работы в среде Дельфи. Библиотека

<inpout32.dll> свободно распространяется в Интернете (см. ресурсы к статье).

Итак, во-первых – помещаем <inpout32.dll> в папке с проектом. Далее в коде модуля Unit после раздела uses размещаем объявления необходимых нам функций из библиотеки:

// импорт функций inpout32.dll
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,StdCtrls, ExtCtrls, ComCtrls;

function Inp32(PortAdr: word): byte; stdcall; external 'inpout32.dll';
function Out32(PortAdr: word; Data: byte): byte; stdcall; external 'inpout32.dll';

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

var val1, val2: byte;

val1:= Inp32($378);      // значение регистра «data» запишется в переменную val1
val2:= 54;
Out32($378,val2);         // в регистр «data» запишется число 54 (b 0 0 1 1 0 1 1 0)

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

// weight (для byte(8 разр.)) = 128, j = 7; weight( для word (16 разр.)) = 32 768, j = 15 ;

function Dec_Bin(N_dec: integer; weight: integer; _bit: byte): byte;
var i ,j : byte;
mas_bin: array[0..j] of byte;
N_dec: integer;
begin
for i:= 0 to j do
begin
mas_bin:= N_dec div weight;
if mas_bin = 1 then N_dec:= N_dec - weight;
weight:= weight div 2;
end;
Result:= mas_bin[_bit];            // возвращает значение бита (0 или 1) двоичного числа,
// соответствующего N_dec
end;

function Bin_Dec(weight: integer): integer;
var i , j: byte;
mas_bin: array[0..j] of byte;
N_dec: integer;

begin
N_dec:= 0;
for i:= 0 to j do
begin
N_dec:= N_dec + mas_bin * weight;
weight:= weight div 2;
end;
Result:= N_dec;           // возвращает десятичное число, соответствующее двоичному
// в виде массива битов mas_bin [ 0 .. j ]
end;

Пример применения функций:

var bit : byte;
bit := Dec_Bin(Inp32($378))[3]; // переменная bit принимает значение 3-го бита регистра «data»

** Переключение регистра «data» ($378) c «выхода» на « вход»

Возможность использования регистра «data» ($378) в качестве порта ввода определяется в настройках

BIOS для параллельного порта. Следует установить Parallel Port в EPP. Переключение регистра на «вход»

осуществляется программно, путем установки 5-го бита регистра «control» ($37A) в «1» (при этом все биты

регистра «data» устанавливаются в «1»). Следует отметить, что данная процедура возможна не на каждом

компьютере и определяется, кроме настроек, еще и конструктивными особенностями порта LPT или

материнской платы.

Вариант тестовой утилиты управления и считывания состояния регистров LPT представлен на рисунке 4 и приведен в ресурсах к статье [1]:

Рис. 4. Утилита считывания и контроля состояний регистров LPT порта

Рис. 4. Утилита считывания и контроля состояний регистров LPT порта

Заключение

Продолжение смотрите в следующем выпуске журнала «ПРОграммист»…

Ресурсы

. Модули и проекты, использованные в статье http://programmersclub.ru/pro/pro3.zip

. Сайт Валерия Ковтуна с множеством интересных программ для работы с LPT портом

http://valery-us4leh.narod.ru/main.html

Это статья из третьего номера журнала “ПРОграммист”.
Скачать его можно по ссылке.
Ознакомиться со всеми номерами журнала.

Обсудить на форуме – Работа с LPT портом в Дельфи или компьютер в роли управляющего контроллера. Часть 1

Похожие статьи