Работа с параллельным портом (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
Прерывание. Происходит на переднем положительном фронте импульса
In
Ожидание. Используется для подтверждения связи. EPP цикл может быть начат, когда уровень низкий, и закончен когда высокий.
11
Wait
Функция Низкий уровень сигнала - запись, высокий уровень сигнала - чтение Данные
12
Не используется в EPP
13
Не используется в EPP
14
-Data Strobe
Out
Когда уровень низкий, сообщает о передаче данных Не используется в EPP
15 16
Reset
Out
17
-Address Strobe
Out
18-25
Ground
GND
Reset- активный уровень низкий Когда уровень низкий сообщает о передаче адреса Корпус
Теперь немного о командах, которые помогут Вам управлять Вашими устройствами. Минус впереди названия сигнала (напр. - 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 D4 D5 D6 1 0 1 1 1 0 0 0 1 1
2 1 0 1 1 1 1 0 0 1
4 0 0 1 0 0 1 0 1 1
8 1 1 1 0 0 1 1 1 0
D7
16 32 64 128
D0
D1
D2
D3
-WRITE
-DATA STROBE
RESET
-ADDRESS STROBE
Прием данных из 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В (от отдельного источника питания), выполните код и Вы увидите совсем другой результат.