Работа с параллельным портом
(LPT)
Отдельное спасибо Дмитрию
Петрову, г.Борисоглебск 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-порт
Private Sub
Command1_Click()
Out
&H378, 15
End Sub
Чтобы наглядно убедиться в работоспособности программы соберите для удобства вот такую схему.
После нажатия кнопки Command1 на контактах 2-5 появиться уровень
логической 1 (+5В) значит первые (сверху по схеме) 4 светодиода загорятся
(1 + 2 + 4 + 8 = 15).
Команда:
Out
&H378,
0 - погасит все светодиоды
Команда:
Out
&H378,
255 - заставит все светодиоды светиться (
1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255)
В таблице, расположенной внизу, можно увидеть основные сигналы при работе параллельного порта в режиме 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
а теперь посадите этот же резистор на +5В (от отдельного источника питания), выполните код и Вы увидите совсем другой результат.