On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru


Широкий выбор винилового сайдинга по доступным ценам от ведущих производителей.





 

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

А. Новожилов

В статье будут рассмотрены примеры чтения и записи данных в 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В (от отдельного источника питания), выполните код и Вы увидите совсем другой результат.



Литература по Basic