Отдельное спасибо Дмитрию
Петрову, г.Борисоглебск bbc@vmail.ru за помощь в написании статьи
В статье будут
рассмотрены примеры чтения и записи данных в LPT порт, а также работа с некоторыми
управляющими сигналами. Если Вы хотите что-либо считывать с порта, то Вам
необходимо переключить режим работы порта компьютера в режим
EPP (Enhanced
Parallel Port – режим двунаправленной передачи данных). Это делается в
BIOS. Во время загрузки
компьютера когда появится надпись Press DEL to enter
setup, нажмите
DEL, чтобы
попасть в меню BIOS.
Затем выберите раздел INTEGRATED PERIPHERALS и там выберите строку PARALLEL
PORT MODE: измените режим работы Вашего порта
на EPP или
SPP/EPP. Сохраните сделанные изменения. Если же на
Вашем компьютере нет режима EPP, то Вы сможете только
передавать данные
Параллельный порт для
связи с принтером (или другим устройством) имеет базовый адрес
&H378 (LPT1),
&H278 (LPT2),
&H3BC (LPT3). В
данной статье мы будем рассматривать только LPT1. Адресное пространство порта занимает
диапазон &H378-&H37F. Адрес &H378 называется базовым и служит для передачи
или чтения данных, через контакты 2-9 разъема LPT-порта. Адрес &H37A служит для передачи
управляющих сигналов к устройству, подключенного к этому порту (принтер,
сканер и т.д.). И, наконец, адрес &H379 предназначен для приема
управляющих сигналов с устройства, подключенного к этому порту (принтер,
сканер и т.д.). Рассмотрим конкретные примеры для каждого из адресов. Для
написания статьи я использовал VB5 и библиотеку Inpout32.dll. В принципе
подойдет любая другая, которая имеет возможность общаться с
LPT портом.
Начало
программы.
В самом начале
программы необходимо указать с какой библиотекой мы будем работать:
Option
Explicit
Private Declare Function
Inp Lib "inpout32.dll" _
Alias "Inp32"
(ByVal PortAddress As Integer) As
Integer
Private Declare Sub
Out Lib "inpout32.dll" _
Alias "Out32" (ByVal PortAddress
As Integer, ByVal Value As
Integer)
Передача числа 15 в LPT-порт адрес
&H378
Private Sub
Command1_Click()
Out
&H378, 15
End Sub
Чтобы
наглядно убедиться в работоспособности программы соберите для удобства вот
такую схему.
После нажатия кнопки Command1 на контактах 2-5 появиться уровень
логической 1 (+5В) значит первые (сверху по схеме) 4 светодиода загорятся
(1 + 2 + 4 + 8 = 15).
В таблице,
расположенной внизу, можно увидеть основные сигналы при работе
параллельного порта в режиме EPP.
In – входящий
сигнал, Out –
исходящий сигнал. Например, когда на 14 контакте (Data Strobe – стробирование данных) появляется
уровень логического 0, то принтер «понимает», что сейчас можно принимать
данные.
№ контакта
EPP Signal
IN/OUT
Функция
1
-Write
Out
Низкий
уровень сигнала - запись, высокий уровень сигнала - чтение
2-9
Data 0-7
In-Out
Данные
10
Interrupt
In
Прерывание. Происходит
на переднем положительном фронте импульса
11
Wait
In
Ожидание. Используется
для подтверждения связи. EPP цикл может быть начат, когда уровень
низкий, и закончен когда высокий.
12
Не используется в
EPP
13
Не используется в
EPP
14
-Data Strobe
Out
Когда уровень низкий,
сообщает о передаче данных
15
Не используется в
EPP
16
Reset
Out
Reset- активный
уровень низкий
17
-Address Strobe
Out
Когда уровень низкий
сообщает о передаче адреса
18-25
Ground
GND
Корпус
Теперь
немного о командах, которые помогут Вам управлять Вашими
устройствами.
Минус
впереди названия сигнала (напр. – Write)
означает, что сигнал инверсный (обратный). Что это такое? Когда мы
зажигали светодиоды (передавали данные), мы отправляли логическую единицу
(высокий уровень) в том или ином бите, чтобы светодиод загорелся. Для
того, чтобы «зажечь» светодиод подключенный к контакту 1
(-Write) мы
должны подать на этот контакт уровень логического нуля. Контроллер
проинвертирует этот сигнал, т.е. изменит на противоположный (на лог.1) и
зажгет светодиод. Подали 0 получили 1, подали 1 получили 0.
Схема
вот такая
«Зажигаем» сигнал
–Writeадрес
&H37A
Private Sub Command1_Click()
Out
&H37A, 10
End Sub
Сразу возникает
вопрос, почему передаем 10 (0 + 2 + 0 + 8 = 10) . В самом младшем бите
D0 уровень лог.0. Сигнал –Write инверсный, значит на выходе будет
лог.1 (светодиод горит), во втором бите D1 уровень лог.1, сигнал -Data
Strobe инверсный, значит на
выходе будет лог.0 (светодиод не горит), в третьем бите D2 лог.0, сигнал Reset обычный, значит на выходе будет
лог.0 (светодиод не горит), в четвертом бите D3 уровень лог.1, сигнал -Address
Strobe инверсный, значит на
выходе будет лог.0 (светодиод не горит). Вот и весь секрет J. В таблице показаны некоторые
комбинации «зажигания» светодиодов на контактах –Write, -Data Strobe, Reset, -Address Strobe
Разряды
D0
D1
D2
D3
D0
D1
D2
D3
D4
D5
D6
D7
-WRITE
-DATA STROBE
RESET
-ADDRESS STROBE
1
2
4
8
16
32
64
128
0
1
0
1
1
0
0
1
1
1
1
1
1
1
0
0
0
1
0
0
0
1
1
1
0
0
0
1
1
0
1
1
1
1
1
0
Прием данных из
LPT-портаАдрес
&H378 или
&H37B-&H37F
Во время экспериментов я пришел к следующему
результату. Можно принимать данные либо по адресу &H378 либо в диапазоне адресов,
начиная с &H37B - &H37F (по любому из них). В первом
случае я подавал сначала команду, переводящую порт в режим приема, а потом
считывал данные по адресу &H378
Private Sub Command1_Click()
Out
&H37A, 32
Text1.Text = Inp(&H378)
End Sub
Во втором случае я просто читал данные по
адресу &H37F, без всякой подготовки
порта
Private Sub Command1_Click()
Text1.Text = Inp(&H37F)
End Sub
Какой способ лучше
или правильнее я не знаю – это решать Вам для каждого конкретного случая.
Но то что оба примера работают – это совершенно точно.
Для
наглядности работы программы соберите такую схему.
При всех разомкнутых кнопках на разрядах
D0-D7 присутствует уровень логической
единицы и если выполнить такую
команду,
Private Sub Command1_Click()
Text1.Text = Inp(&H37F)
End Sub
то
в TextBox появится
число 255 (1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255). Если
же замкнуть, например, нижнюю по схеме кнопку, на разряде D7
и
выполнить команду,
Private Sub Command1_Click()
Text1.Text = Inp(&H37F)
End Sub
то
в TextBox появится
число 127 (1 + 2 + 4 + 8 + 16 + 32 + 64 = 127). Если Вы
замкнете все кнопки, то прочитаете 0 (ноль)
Как принять команду со своего
устройства адрес &H379
Из самой первой таблицы можно взять два
сигнала, которые могут только принимать команды от Вашего устройства, это
контакт 10 (Interrupt –
прерывание) и контакт 11 (Wait – ожидание).
Код программы
такой:
Private Sub Command1_Click()
Text1.Text = Inp(&H379)
End Sub
Попробуйте
соединить контакт 11 через резистор 10 кОм на землю и выполните
код,
а теперь посадите этот же резистор на +5В (от отдельного источника
питания), выполните код и Вы увидите совсем другой
результат.