Работа с параллельным портом (LPT)

А. Новожилов, Азбука Visual Basic


Отдельное спасибо Дмитрию Петрову, г.Борисоглебск 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).

Команда: 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 

Попробуйте соединить контакт 11 через резистор 10 кОм на землю и выполните код,

 а теперь посадите этот же резистор на +5В (от отдельного источника питания), выполните код и Вы увидите совсем другой результат.

Hosted by uCoz