Другая жизнь lpt порта (часть 1)

Учимся работать с LPT портом

Доброго времени суток кодеры, и остальные маньяки компьютерной индустрии. Сегодня я расскажу тебе как можно управлять LPT портом и использовать его в своих целях. Так что запасайся сникерсами и терпением. В конце я покажу интересный пример его использования.

LPT порт имеет 25 контактов на которых может быть установлено 0 или +5В (0 или 1). Устанавливать значения можно программным путем или с помощью внешнего устройства. Давайте рассмотрим следующий рисунок который поможет нам в работе.
(Сразу признаюсь, рисунок не мой, он взят с сайта www.pcports.ru, где есть много информации на данную тему).

Как мы видим, выводы порта можно разделить на четыре группы. Восемь крастных выводов относятся к регистру Data. Чтобы к нему обращаться, надо знать его адресс: 378h – в 16-ричной системе или 888 – в 10-ричной.

Биты этого регистра могут быть установлены (или сброшены) как программно, так и внешним устройством. Выводы обозначенные черным цветом являются земляными.

Все они соединены между собой и для наших целей мы можем использовать любой.

Зеленым цветом обозначены контакты, устанавливать значение которых можно только через внешнее устройство. То есть программно мы их изменить не можем. Мы можем только считывать их состояние. Они относятся к регистру Status, который имеет адрес 379h в 16-ричной или 889 в 10-ричной системе.

И регистр Control, выводы которого обозначены синим цветом. Он как и регистр Status однонаправленный, но тут его состояние изменять можно только программно.
Ну что, надо бы и на практике закрепить. Давай вспомним старый, добрый Ассемблер. Для работы с портами он предоставляем нам две команды: in и out. Команда in загружает данные в аккумулятор из порта устройства ввода/выводы. Пример:

n аккумулятор, порт.

В этом случае можно выводить из портов с адресами до 255. Нам этого недостаточно. Используя регистровую адресацию можно выводить из портов до 65536. Вот пример:

in аккумулятор, dx.

То есть адрес порта должен быть заранее помещен в регистр dx. Команда out наоборот – помещает в порт данные из аккумулятора. Пример: out dx, аккумулятор. Здесь также используется регистровая адресация, что бы можно было работать с портами, адреса которых до 65536.

Теперь запускаем наш любимый Делфи, ставим на форму кнопку и по событию ее нажатия пишем следующий ассемблерный код (это называется ассемблерная вставка (примечание Soffrick'а – Inline assembler) и она записывается между ключевыми словами asm и end):
(этот пример не будет работать в Windows NT.

Потом расскажу как это побороть)

procedure TForm1.Button1Click(Sender: TObject);
asm //обозначает, что дальше пойдет ассемблерный код mov dx,888 //засылаем в регистр dx адрес нашего порта в 10-чной системе mov al,00000001b //в аккумулятор засылаем “маску” в двоичной сис. out dx,al //выводим в порт (а точнее в регистр Data знач. 00000001
end;

Теперь обьясню чего мы добились. Давай посмотрим на наш рисунок, а точнее на красные разьемы которые соответствуют битам от D0 до D7 регистра Data. А теперь угадай какой из них мы установили в 1. Правильно, бит D0, а следовательно и контакт №2 установлен в 1.

А это значит, что на этом контакте сейчас находится +5 Вольт. Проверяется легко. Нужно взять светодиод и его “+” засунуть во второй контакт, а его “-” в 25-й (тоесть заземлить).

Вот тут я должен тебя предупредить, что подключение к LPT порту всяких самодельных устройств (сделанных не грамотно) может обернутся выходом из строя материнской платы. Обычно длинный усик светодиода – это “+” (лучше проверить это с помощью батарейки).

Наш светодиод должен загореться. Но вот не задача. Наша программа при нажатии на кнопку ругается. Дай угадаю, у тебя винда не 9х.

Дело в том, что ОС Windows NT (2000, XP) с целью обеспечения безопасности использования совместных аппаратных ресурсов компьютера, запрещает к ним прямой доступ из программ пользовательского режима. И чтобы обратиться к порту, необходимо все операции проводить через драйвер. Я предлагаю использовать библиотеку Inpout32.dll.

Скачать ее можно здесь http://www.pcports.ru/files/inpout32.rar. Эта библиотека, при работе с NT, обращения к ней конвертирует в запросы к стандартному драйверу ОС, через который и идет обмен данными с портом. Узнать больше об этой библиотеке и ее авторе можно здесь: http://www.logix4u.net/inpout32.htm.

Эта библиотека содержит две следующие функции которые нам пригодятся. Вот их описание:

Inp32(PortAdr: word): byte.

Ей передается адрес порта, а она возвращает значение которое в нем установлено. Внимание, значение передает в десятичной системе. Следующая функция:

Out32(PortAdr: word; Data: byte): byte.

Из описания видно что она тоже может возвращать какой то результат, но нам это не понадобится. Она отсылает в указанный порт указанное значение (тоже в 10-чной сис.).

Снова открываем наш отчаянно закрытый после первой попытки Делфи и делаем следующее. Нам необходимо объявить функции из библиотеки.

Для этого в нашем исходнике после перечня модулей и перед объявлением типов пишем следующее:

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, jpeg;
  function Inp32(PortAdr: word): byte; stdcall; external 'inpout32.dll'; function Out32(PortAdr: word; Data: byte): byte; stdcall; external 'inpout32.dll';
 
type TForm1 = class(TForm)


Здесь мы объявили две функции. Указали, что вызываться они будут стандартным способом (написав stdcall), а также мы указали, что процедура внешняя и находится в библиотеке (external 'inpout32.dll').Кстати, эта библиотека должна находиться в папке вместе с исполняемым файлом. Далее кидаем на форму кнопку и по ее нажатию пишем:

Out32(888,1);

Компилируем, запускаем и о чудо, загорелся наш светодиод. А теперь давай вспомним “маску” (00000001) из предыдущего примера. Наша единица, которая передается во втором параметре в порт 888 (регистр Data) в 10-чной сис. равносильна 00000001 в 2-чной.

То есть, если взять еще два светодиода, и “+” одного засунуть в 3-й контакт LPT порта, а “+” другого, например в пятый, а ихние минусы конечно заземлить подключив к 25-му выводу, то для того что бы их все зажечь, надо во втором параметре функции Out32 отправить на порт 11: Out32(888,11), потому что 11, в двоичной системе будет выглядеть так 00001011. Непонятно? Попробуй эти нолики и единички визуально наложить на рисунок, начиная с девятого контакта и до 2-го. Теперь не сложно догадаться, что на контактах 5,3 и 2 будет установлено напряжение +5В и наши светодиоды, которые мы туда засунули, будут гореть. Теперь мы можем сделать что-нибудь по интереснее, например мигалку. Используя таймер это не сложно сделать. Попробуй сам.

Ну вот вроде бы и все, что я хотел тебе рассказать сегодня. В следующей статье я расскажу как сделать так, что бы радиоуправляемая машинка управлялась не с пульта, а с клавиатуры. Удачной компиляции.

Written by: Kastor

Источник: http://www.vr-online.ru/content/uchimsja-rabotat-s-lpt-portom-1034

LPT мигает светодиодом

Эту статью я написал года четыре назад. А сейчас внезапно нашёл её, и решил выложить в блог. Довольно забавно 🙂 Предупреждаю, я не несу ответственности за то, что может произойти с вашей техникой в результате применения данной информации.

В последнее время довольно долгое время меня мучила мысль о том, что неплохо бы как-нибудь своими силами связать компьютер с внешним миром.

Плюс ко всему впустую простаивающий параллельный порт принтера меня угнетал, ибо у меня принтер подключён через USB.

Я просмотрел несколько статей, описаний и прочей литературы, и то что у меня вышло в результате экспериментов назвать оригинальным язык не поворачивается, но, тем не менее, это может показаться кому-то интересным.

Задача стоит весьма тривиальная: научиться управлять мерцанием светодиода, подключённого к ПК через LPT-порт. Почему именно LPT? Потому что он довольно прост и в меру интересен.
Поехали!

Подготовка

Итак, что нам нужно для воплощения этого ужаса в реальное существо:

  • ПК
  • Компилятор какого-нибудь языка программирования (Assembler, С, С++, Pascal, etc…).
  • Некоторый программный инструментарий
  • Светодиод на 5В
  • LPT-шнур

Шнур у меня был только разрезанный, но вы можете использовать любой, главное всё правильно соединять. Вот мой шнур, с уже выведенными контактами для подключения светодиода (об этом речь пойдёт далее):

Вот, собственно, светодиод, купленный на ближайшем базаре за несколько денег. Он который будет светиться ярким синим светом:

Железо

Прежде чем приступить к практике, немного теории.

Как работаете LPT-порт? Об этом достаточно много написано, однако я всё-таки кратко расскажу как обстаят дела.

Параллельный порт ПК обычно используется для подключения принтеров, но на этом его возможности не ограничиваются. К нему можно подключать любое внешнее, самодельное устройство. LPT-порт имеет 25 пинов, но не все 25 необходимы. В нашем примере, например, нужно только 2. Рассматривать предназначение всех не будем.

Подключать светодиод будем плюсом к 2 пину, а минусом – к пину 18. Смотрите, не перепутайте, в противном случае светодиод может сгореть. Лучше предварительно проверить где у него плюс, где минус на маломощной батарейке.

Если у вас шнур папа-мама, то есть при подключении к компьютеру, на вашем конце шнура остаются входы, дело простое – просто воткнуть в нужные пины диод. Следует быть осторожным, неправильно подключив, можно повредить LPT-порт.

Лично я, раскурочив шнур, определил, какой относится к D0, какой к земле, и у меня всё выглядит примерно так, как показано на следующем рисунке. Я сидел с пробником, и вычислял, какая линия относится к D0. Очень занимательно! Вы можете найти более удочное решение.

В мерах предосторожности можно последовательно к диоду припаять сопротивление. Рекомендуют 470 Ом. На счёт заземления: кто-то заземляет не на пин GRD, а на корпус коннектора, но я предпочитаю пин.

На этом этапе вы должны представлять себе, как можно подключить светодиод к LPT-порту.

Программная часть

Подключить светодиод к компьютеру мы готовы, но вот, дальше-то что? А дальше самое интересное: управление им с бортового пульта. С одним светодиодом много не сделаешь: только включать/выключать его можно.

Но зато можно менять частоту мигания, можно подключить ещё 7 светодиодов к остальным пинам D1-D8, и сделать светомузыку.

Или приобрести яркие белые светодиоды, и сделать настольную лампу, питающуюся от LPT-порта, которая включается, когда вы начинаете печатать, чтобы подсветить вам клавиатуру.

Можно вывести зелёненький светодиод куда-нибудь на видное место и написать программу, мигающую им, когда вам на E-mail приходит письмо. Сколько всего можно сделать только лишь с использованием светодиода! А подковав себя в электронике, можно собирать полноценные внешние устройства, но это, к сожалению, выходит за рамки данной скромной статьи.

Управление LPT-портом зависит от ОС. В былые времена, операционные системы DOS и Windows 95/98 разрешали пользовательским программам напрямую иметь доступ к железу.

С появлением Windows NT/2000/XP всё изменилось, теперь общение с портами напрямую пользовательским программам запрещено, а разрешено только коду, выполняющемуся в режиме ядра.

Всё это сделано в целях защиты и в других нужных и полезных целях, однако всё это одновременно и усложняет нашу задачу по подмигиванию светодиодом. Нам пришлось бы писать специальный драйвер устройства, разбираться в HAL (Hardware Abstraction Layer) и прочих премудростях.

Вы можете заняться этим, почитав материалы по Microsoft DDK (Device Driver Kit). Но существует несколько обходных путей, позволяющих напрямую общаться с нашим LPT. Вообще, так делать не рекомендуется, но всё же, мы сделаем именно так, ибо так проще и нагляднее.

Другими словами, напрямую получить доступ к регистрам LPT-порта просто так не удастся. Вы можете работать с драйвером устройства LPT как с обычным файлом при помощи функций CreateFile, ReadFile, WriteFile, а так же получать некоторую информацию о состоянии устройства функцией DeviceIoContol. Но работать с регистром, например, D0, который включает наш светодиод, не получится.

В ОС Linux всё обстоит по-иному. Там можно делать всё просто, имея на то специальные права. Необходимо только узнать по какому адресу находится ваш LPT. Обычно он находится по адресу 0378h. Узнать адрес в вашей системе можно, просмотрев файл /proc/ioports. Хотя, проще работать с файлом устройства /dev/lp0.

Разберём, как справиться с ОС Windows, потому что это немного сложнее.

Перед тем, как перейти непосредственно к программированию своими силами, проверим, работает ли всё это дело, собранное в прошлой части статьи. Для этого я использую чудесную программу мониторинга параллельного порта, так и названную: Parallel Port Monitor by Neil Fraser.

Как делаю я: запускаю программу, выключаю в ней все пины с 2 до 9, затем подключаю светодиод к LPT-порту (в нашем случае во второй пин, в D0). После этого в Parallel Port Monitor подаю единицу на D0. Светодиод должен загореться. Если ничего не произошло, возможно, вы неправильно его подключили или же в программе выбрали не тот LPT-порт. Попробуйте LPT1, LPT2, LPT3, если у вас их несколько.

Светодиод мигает? Отлично. Теперь можно побаловаться с ним своим программным кодом. Как было сказано ранее, это делать мы будем обходным путём. Если вы используете Windows 95/98/ME, можете сразу перейти к написанию программы, обходные пути вам не нужны, эти версии ОС Windows позволяют напрямую обращаться к портам.

1) Использование драйвера UserPort

Программа UserPort (автор Tomas Franzon), это системный драйвер режима ядра для Windows NT/2000/XP, который позволяет обращаться к портам ввода-вывода напрямую. Как раз то, что нам необходимо. Найти её в любом поисковике не составит труда. Скачав, настроив, согласно документации и запустив, мы получаем возможность мигать светодиодом из наших программ.

Сперва определим адреса портов в Device Manager. Видим, LPT1 по адресу 0378-037F. Именно туда мы и будем писать биты управления светодиодом. Пишем 1 – на контакты светодиода подаётся напряжение +5В, он загорается, пишем бит 0 – светодиод гаснет.

Напишем тестовую программу, мигающую светодиодом раз в секунду. Исходный текст приведён ниже. Здесь я использовал С++ со вставками ассемблерного кода и компилятор Visual C++. Вы можете использовать свой любимый язык программирования и компилятор, суть не меняется.

#include #include void doLight(bool on) { __asm { mov DX,0378h mov AL,on out DX,AL } } int main() { while(1) { doLight(true); std::cout

Источник: https://bitsofmind.wordpress.com/2008/08/07/led-and-lpt-port/

LPT-порт в схемах на микроконтроллере

Компьютер обрабатывает сигналы параллельными потоками, поэтому ему легче «общаться» с параллельными, а не с последовательными внешними портами. В 1984 г. в составе IBM PC впервые появился параллельный порт. Задуман он был как средство подключения матричных принтеров, отсюда и название LPT — Line PrinTer или Line Printer Terminal.

В дальнейшем для принтеров стали использовать быстродействующий интерфейс USB, а LPT-порт начал постепенно вытесняться из компьютерных спецификаций. Остряки сравнивают LPT с чемоданом без ручки — и выбросить жалко, и тащить невозможно. Тем не менее, «ветеран» ещё на многое способен, если, конечно, он присутствует в конкретном компьютере.

Разъём LPT-порта имеет 25 контактов. Нормой «де-факто» считается розетка DB-25F в компьютере и вилка DB-25M в ответном кабеле (Табл. 4.2). Нумерация контактов вилок и розеток зеркальная (Рис. 4.7, а, б).

Таблица 4.2. Раскладка сигналов в 25-контактном разъёме LPT-порта

DB-25 Цепь Расшифровка Функция Направление
1 STROBE Strobe Строб Вход/выход
2…9 D0…D7 Data Bit Данные Вход/выход
10 ACK Acknowledge Подтверждение Вход
11 BUSY Busy Готовность Вход
12 РЕ Paper End Нет бумаги Вход
13 SEL Select Выбор Вход
14 AUTOFD Autofeed_____ Автоперенос Вход/выход
15 ERROR Error Ошибка Вход
16 INIT Initialize Инициализация Вход/выход
17 SELIN Select In Выбор входа Вход/выход
18…25 GND Ground «Земля» Общий

Рис. 4.7. Внешний вид спереди 25-контактных разъёмов LPT-порта: а) розетка DB-25F в компьютере; б) вилка DB-25M в соединительном кабеле.

Первоначально линии LPT-порта были однонаправленными SPP (Standard Parallel Port).

Часть из них работала только на вход, часть — только на выход, что по набору сигналов и протоколу обмена соответствовало принтерному интерфейсу «Centronics». В 1994 г.

был утверждён новый стандарт параллельного интерфейса IEEE 1284, предусматривающий двунаправленные линии и три режима работы: SPP, EPP (Enhanced Parallel Port), ECP (Extended Capabilities Port).

Уровни электрических сигналов LPT-порта совпадают с обычными «пятивольтовыми» логическими микросхемами. Раньше в компьютерах применялись буферные TTJl-микросхемы серии 74LSxx, позднее — КМОП-микросхемы и БИС, примерно эквивалентные серии 74ACxx. В последнем случае можно ориентировочно считать, что НИЗКИЙ уровень равен 0.1..0.2 В, а ВЫСОКИЙ — 4.5…4.9 В.

Стандартом регламентируется нагрузка 14 мА по каждому выходу при сохранении напряжения не менее +2.4 В ВЫСОКОГО и не более +0.4 В НИЗКОГО уровня. Однако в разных материнских платах выходные буферы LPT-порта могут иметь разную нагрузочную способность, в том числе и ниже стандарта («слабый» порт).

Требования к соединительным кабелям, подключаемым к LPT-порту:

•                 сигнальные провода должны быть свиты в пары с общим проводом GND;

•                 каждая пара должна иметь импеданс 56…68 Ом в диапазоне частот 4… 16 M Гц;

•                 если применяется плоский ленточный кабель, то сигнальные провода должны физически чередоваться с общим проводом GND (локальные экраны);

•                 уровень перекрёстных помех между сигналами не более 10%;

•                 кабель должен иметь экран, покрывающий не менее 85% внешней поверхности. На концах кабеля экран должен быть окольцован и соединён с «земляным» контактом разъёма;

•                 в разъёме кабеля можно запаять на контакты 1…17 последовательные резисторы C2-23 (OMJIT-O.125) сопротивлением 100…300 Ом (Рис. 4.8). Это позволит защитить компьютер от случайных коротких замыканий в нагрузке и уменьшить высокочастотный «звон» на фронтах сигналов.

Рис. 4.8. Электрическая схема LPT-кабеля с «антизвонными» резисторами.

Схемы соединения MK с LPT-портом можно разделить на три группы:

•                 приём сигналов от компьютера (Рис. 4.9, а…з);

•                 передача сигналов в компьютер (Рис. 4.10, а…д);

•                 приём/передача сигналов одновременно (Рис. 4.11, a…e).

В схемах приняты некоторые упрощения. В качестве входного сигнала указывается в основном «DO», а в качестве выходного — «АСК», хотя могут быть и другие, перечисленные в Табл. 4.2. На каждом конкретном компьютере работоспособность самодельных схем необходимо проверять экспериментально, что связано с наличием «сильных» и «слабых» LPT-портов по нагрузочной способности.

Рис. 4.9. Схемы ввода сигналов из LPT-порта в MK (начало):

а) резистор R1 ограничивает входной ток. Элементы R2, C1 могут отсутствовать, но они уменьшают «звон» на фронтах сигналов при длинном кабеле;

б) буферный транзистор VT1 инвертирует сигнал. Диод VD1 не обязателен, но он защищает транзистор от ошибочной подачи большого отрицательного напряжения. Если не ставить резистор R2, то схема останется работоспособной, однако при отстыковке кабеля от LPT-порта возможны ложные срабатывания транзистора VT1 от внешних помех и наводок;

в) диод VD1 отсекает помехи и повышает порог срабатывания транзистора VT1. Резистор R1 надёжно закрываеттранзистор VT1 при НИЗКОМ уровне с LPT-порта;

г) буферный логический элемент DD1 имеет выход с открытым коллектором. Фронты сигналов формируются элементами R1, C1. Можно вместо инвертора DD1 поставить повторитель К155ЛП9, сделав соответствующие изменения в программе MK и компьютера;

д) триггер Шмитта DD1 (замена — К555ТЛ2) повышает помехоустойчивость. Чем меньше сопротивление резисторов R1, R2, тем больше крутизна фронтов сигнала. При отключённом кабеле от LPT-порта резистор R1 не даёт входу микросхемы DD1 «висеть в воздухе»;

е) последовательное включение двух логических элементов DD11, /)/)/.2увеличивает (восстанавливает) крутизну фронтов сигнала. Резистор R1 устраняет выбросы, «звон»;

 Рис. 4.9. Схемы ввода сигналов из LPT-порта в MK (окончание):

ж) данные, поступающие от LPT-порта, предварительно помещаются в промежуточный регистр DD1. Запись производится при ВЫСОКОМ уровне на входе «С» микросхемы DD1, хранение — при НИЗКОМ.

Такое решение устраняет помехи, поскольку в LPT-порт в зависимости от установленных в компьютере драйверов периодически могут выводиться случайные данные.

Их устраняют программно, например, путём многократного считывания входного сигнала с линий MK;

з) буферизация LPT-порта мощными транзисторными ключами, находящимися в микросхеме DA1 фирмы Texas Instruments. Резисторы R1…R8 могут иметь в 10… 15 раз более низкие сопротивления, что позволяет подключить параллельно выходам микросхемы А4/другие узлы устройства.

Рис. 4.10. Схемы вывода сигналов из MK в LPT-порт (начало):

а) непосредственное подключение выхода MK без буферных элементов. Резисторы R1, R2 уменьшают отражение сигналов в линии. Кроме того, резистор R2 защищает выход MK от случайного короткого замыкания с цепью GND в проводах соединительного кабеля;

б) триггер Шмитта DD1 служит защитным буфером для MK при аварийной ситуации на выходе (короткое замыкание или подача большого напряжения);

в) микросхема DD1 имеет выход с открытым коллектором, что защищает её от короткого замыкания в проводах и разъёмах соединительного кабеля;

г) подача двух противофазных сигналов в компьютер. Цель — программная необходимость или организация дублирующего (контрольного) канала передачи данных;

д) опторазвязка на элементах HL1, BL1, которые применяются в компьютерных механических «мышах». Транзистор КГ/усиливает и инвертирует сигнал. Для нормальной работы устройства компьютер должен выставить ВЫСОКИЙ уровень на линии «D8».

Рис. 4.11. Комбинированные схемы ввода/вывода сигналов между MK и LPT-портом (начало):

а) если компьютер выставляет на линии «DO» ВЫСОКИЙ уровень, то MK в режиме выхода может генерировать сигнал «АСК» через резистор R1. Если MK переводится в режим входа, то компьютер может передавать ему данные по линии «DO» через диод VD1 при этом внутренний « pull-up» резистор MK формирует ВЫСОКИЙ уровень;

б) сигнал от LPT-порта вводится в MK через инвертор на транзисторе VT1 при этом компьютер должен выставить ВЫСОКИЙ уровень на линии «D2». Информация в MK вводится с линии «DO» через резистор R1 Высокое сопротивление резистора R1 физически развязывает входной и выходной каналы;

 Рис. 4.11. Комбинированные схемы ввода/вывода сигналов между MK и LPT-портом (окончание):

б)         сигнал от LPT-порта вводится в MK через инвертор на транзисторе VT1, при этом компьютер должен выставить НИЗКИЙ уровень на линии «DO». Информация в МК  вводится через элементы R1, R3, VT2;

г)         сигнал от LPT-порта вводится в MK через повторитель на транзисторе VT1, при этом компьютер должен выставить ВЫСОКИЙ уровень на линии «DO». Информация в MK вводится через повторитель на микросхеме DD1

ж)        сигналы «D0»…«D3» вводятся в MK при НИЗКОМ уровне на линии «INIT», при этом компьютер должен настроить линии «D4»…«D7» как входы.

В настройках BIOS компьютера надо установить двунаправленный режим EPP или ЕСР для LPT-порта. Информация в компьютер из МК  передаётся по линиям «D4»…«D7» при ВЫСОКОМ уровне на линии «INIT».

Резистор R1 переводит выходы микросхемы DD1 в Z-состояние при отключённом кабеле от LPT-порта;

e)              сигнал от MK в LPT-порт вводится через повторитель DD1.2, при этом компьютер должен выставить ВЫСОКИЙ уровень на линии «D2» и НИЗКИЙ уровень на линии «D5». Информация в MK вводится через повторитель DD1.1 при НИЗКОМ уровне налинии «D2». Стробирование сигналов по входам «Е1», «Е2» микросхемы DD1 повышает достоверность передачи данных.

Источник: Рюмик, С. М., 1000 и одна микроконтроллерная схема. Вып. 2 / С. М. Рюмик. — М.:ЛР Додэка-ХХ1, 2011. — 400 с.: ил. + CD. — (Серия «Программируемые системы»).

Источник: http://nauchebe.net/2014/03/lpt-port-v-sxemax-na-mikrokontrollere/

Другая жизнь LPT порта (часть 1)

Другая жизнь LPT порта (часть 1)

Не ждал, что моя 1-ая статья вызовет таковой энтузиазм посреди программистов и электронщиков, т. к. я получил массу писем с вопросами и продолжаю их получать до сего времени, хотя прошло уже практически три года с момента написания статьи.

Не считая того в первой статье был допущен ряд некорректностей.

Это все и побудило меня на написание более подробной статьи на данную тему, в какой я постараюсь ответить на большая часть вопросов почетаемых читателей и поправить те некорректности, которые были допущены в первой статье.

Пусть не дуются на меня читатели первой статьи, но мы опять разглядим тщательно каждый контактик и битик нашего LPT порта. В первой части статьи будет рассмотрена теория, во 2-ой и следующих (если они будут) мы будем рассматривать электрические устройства, которые можно «подцепить» к этому порту.

В тексте вы встретитесь с принятой аббревиатурой записывания чисел. К примеру, 10102 — двойка в нижнем индексе показывает, что число 5 представлено в двоичном исчислении, 12410 – 10-ка в нижнем индексе, гласит о том, что число 124 десятичное. Это так… на всякий случай

Как показала практика, все программки, верно написанные и дополненные надлежащими библиотеками (vbio32.dll, inpout32.dll, dlportio. dll и т. д.) работают на большинстве компов с операционными системами семейства Windows. Я инспектировал работу всех собственных программ (Visual Basic5.0, 6.

0) на Win95, 98, Me, 2000, XP HE, XP Prof и даже в DOS6.22 (QBasic) – все работает отлично. В DOS-е вообщем никаких библиотек не нужно, там все и так работает. Сходу оговорюсь, что vbio32.dll и inpout32.

dll НЕ БУДУТ РАБОТАТЬ ПОД Win2000, но совсем тихо будут работать под Win95, 98, Me.

Кстати, взять всякую из этих библиотек вы сможете тут. Мне захотелось испытать dlportio. dll и на этот момент я работаю с этой библиотекой. Ну и последнее, перед написанием программ нужно верно объявить библиотеку, которую вы используете.

Для inpout32.dll

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)

Для dlportio. dll

Private Declare Function DlPortReadPortUchar Lib «dlportio. dll» (ByVal Port As Long) As Byte

Private Declare Sub DlPortWritePortUchar Lib «dlportio. dll» (ByVal Port As Long, ByVal Value As Byte)

Чем отличается Private от Public я писать не буду.

Параллельный порт для связи с принтером (либо другим устройством) имеет базисный адресок &H378 (LPT1), &H278 (LPT2), &H3BC (LPT3). В данной статье мы будем рассматривать только LPT1. Адресное место данного порта занимает спектр &H378-&H37F.

· Адресок &H378 именуется базисным и служит для записи (чтения, но об этом попозже) данных в порт, на полосы D0-D7.

· Адресок &H379 (базисный+1) предназначен для чтения битов состояния с устройства, присоединенного к LPT-порту (принтер, сканер и т. д)

· Адресок &H37A (базисный+2) служит для записи битов управления устройства, присоединенного к LPT-порту (принтер, сканер и т. д.).

На приведенных ниже таблицах «расшифрованы» контакты и сигналы каждого из адресов

Контакты 18-25 – «земля» (общий, GND, GROUND и т. д.)

Разглядим программирование каждого из адресов.

· Базовый адресок &H378 (LPT1) позволяет записывать данные в порт на полосы D0-D7 в спектре от 0 до 255.

· Записываем в порт число 69

Код последующий. Для тех, кто употребляет

Inpout32.dll

Dlportio. dll

DOS

Out &H378, 69

DlPortWritePortUchar &H378, 69

OUT &H378, 69

· Адресок &H379 служит для чтения битов состояния.

· Читаем состояние порта по адресу &H379

При чтении адреса &H379 нужно держать в голове, что 1-ые три бита – не употребляются и всегда имеют значение лог. «1», а 7-й бит – инверсный.

В итоге если все контакты 15, 13, 12, 10, 11 высадить на «землю», то при чтении инфы вы получите на первых 3-х битах (которые не употребляются) 1+2+4 и на 7-м бите (контакт 11-инверсный, означает, при замыкании на землю будет лог.

«1») +128 итого 135. Об этом не нужно забывать. Во 2-ой части статьи мы остановимся на этом более тщательно.

Код последующий. Для тех, кто употребляет

Inpout32.dll

Dlportio. dll

DOS

Dim A as Integer A = Inp(&H379) Dim A as Integer DlPortReadPortUchar(&H379) DEFINT A-Z

A=INP(&H379)

· Адресок &H37A служит для записи битов управления.

· Записываем сигнал — STROBE (бит управления 0)

Код последующий. Для тех, кто употребляет

Inpout32.dll

Dlportio. dll

DOS

Out &H37A, 10 DlPortWritePortUchar &H37A, 10 OUT &H37A, 10

Почему 10? Давайте поглядим в табличку.

(-STROBE) 20

(-AUTO) 21

(INIT) 22

(-SELECT IN) 23

(Сигналы) биты

Контакт 1

Контакт 14

Контакт 16

Контакт 17

1

1

01012

2

8

0+2+0+8=10

Сигналы STROBE, AUTO, SELECT IN – инверсные, означает, чтоб на выходе контактов разъема 1, 14, 17 получить логическую «1» нужно подать на эти биты логический «0», т. е. подали одно – получили обратное. Сигнал INIT прямой (не инверсный), потому логическая «1» на контакте 16 появится тогда, когда мы подадим на этот бит логическую «1», т. е. что подали, то и получили.

Попытаемся получить на контактах 1,17 – малый уровень сигнала «0», а на контактах 14 и 16 высочайший уровень сигнала «1», т. е. на выходе контактов 1,14,16,17 будет находиться 0 1 1 0 (610).

На нулевой бит (-STROBE) подаем «1» (на контакте 1 будет «0»), на 1-ый бит (-AUTO) подаем «0» (на контакте 14 будет «1»), на 2-ой бит (INIT) подаем «1» (на контакте 1 будет «1») и, в конце концов, на 3-ий бит (-SELECT IN) подаем «1» (на контакте 17 будет «0»), т. е. мы записали по адресу &H37A число 10112,-это 1310. Означает, чтоб на выходе получить 6 нужно подать 13.

Для удобства привожу таблицу со всеми вероятными комбинациями чисел от 0 до 15

Подаваемый сигнал

Получаемый сигнал

Десятичное число

(-STROBE) 2

(-AUTO) 21

(INIT) 22

(-SELECT IN) 23

Контакт 1

Контакт 14

Контакт 16

Контакт 17

Десятичное число

1

2

4

8

1

2

4

8

1

1

1

11

1

1

1

1

10

2

1

1

1

9

3

1

1

1

8

4

1

1

1

1

1

15

5

1

1

1

1

1

14

6

1

1

1

1

1

13

7

1

1

1

1

1

12

8

1

1

1

3

9

1

1

1

2

10

1

1

1

1

11

1

1

1

12

1

1

1

1

1

7

13

1

1

1

1

1

6

14

1

1

1

1

1

5

15

1

1

1

1

1

4

Ну и, в конце концов, последнее в этой части статьи.

Если ваш компьютер поддерживает эталон EPP, то четвертым битом по адресу &H37A вы можете разрешить прерывание (для LPT1 это IRQ7) от принтера, только не спрашивайте меня что же все-таки это такое, я все равно ничего не знаю про прерывания.

А вот пятым битом 1101012 , к примеру, подав число 4310, вы устанавливаете шину D0-D7 в режим ПРИЕМА данных. При всем этом все разряды (контакты 2-9) принимают значение логической «1».

Чтоб подать на подходящий контакт логический «0» нужно замкнуть его через сопротивление 240 – 360 Ом на «землю». Таким макаром, через LPT порт компьютера мы получаем в стандартном виде устройство с 12-ю выходными сигналами и 5-ю входными, а при е порта в режим EPP мы получаем 4 выходных сигнала и 13 входных сигналов.

Режим SPP (12 выходов и 5 входов)

Режим EPP (4 входа и 13 выходов)

Сигнал

Направление

Сигнал

Направление

D0

Выход

D0

Вход

D1

Выход

D1

Вход

D2

Выход

D2

Вход

D3

Выход

D3

Вход

D4

Выход

D4

Вход

D5

Выход

D5

Вход

D6

Выход

D6

Вход

D7

Выход

D7

Вход

ERROR

Вход

ERROR

Вход

SELECT

Вход

SELECT

Вход

PAPER END

Вход

PAPER END

Вход

ACK

Вход

ACK

Вход

BUSY

Вход

BUSY

Вход

STROBE

Выход

-STROBE

Выход

-AUTO

Выход

AUTO

Выход

INIT

Выход

INIT

Выход

-SELECT IN

Выход

-SELECT IN

Выход

Конец первой части.

Во 2-ой части статьи мы будем подключать к порту разные электрические штуки.

Статью прислал Клюшников Алексей, г. Иваново.

LPT

Источник: http://bloggoda.ru/2017/10/18/drugaya-zhizn-lpt-porta-chast-1/

Изучаем программирование – Упровление: LTP,COM портом

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}
");let k=document.querySelector(".flat_pm_modal[data-id-modal=\""+a.ID+"\"]");if(-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(k,d):jQuery(k).html(b+d),"px"==a.how.popup.px_s)e.bind(h,()=>{e.scrollTop()>a.how.popup.after&&(e.unbind(h),f.unbind(i),j())}),void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{e.unbind(h),f.unbind(i),j()});else{let b=setTimeout(()=>{f.unbind(i),j()},1e3*a.how.popup.after);void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{clearTimeout(b),f.unbind(i),j()})}f.on("click",".flat_pm_modal .flat_pm_crs",()=>{jQuery.arcticmodal("close")})}if(void 0!==a.how.outgoing){let b,c="0"==a.how.outgoing.indent?"":" style=\"bottom:"+a.how.outgoing.indent+"px\"",e="true"==a.how.outgoing.cross?"":"",f=jQuery(window),g="scroll.out"+a.ID,h=void 0===flatPM_getCookie("flat_out_"+a.ID+"_mb")||"false"!=flatPM_getCookie("flat_out_"+a.ID+"_mb"),i=document.createElement("div"),j=jQuery("body"),k=()=>{void 0!==a.how.outgoing.cookie&&"false"==a.how.outgoing.cookie&&h&&(jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show"),j.on("click",".flat_pm_out[data-id-out=\""+a.ID+"\"] .flat_pm_crs",function(){flatPM_setCookie("flat_out_"+a.ID+"_mb",!1)})),(void 0===a.how.outgoing.cookie||"false"!=a.how.outgoing.cookie)&&jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show")};switch(a.how.outgoing.whence){case"1":b="top";break;case"2":b="bottom";break;case"3":b="left";break;case"4":b="right";}jQuery("body > *").eq(0).before("
"+e+"
");let m=document.querySelector(".flat_pm_out[data-id-out=\""+a.ID+"\"]");-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(m,d):jQuery(m).html(e+d),"px"==a.how.outgoing.px_s?f.bind(g,()=>{f.scrollTop()>a.how.outgoing.after&&(f.unbind(g),k())}):setTimeout(()=>{k()},1e3*a.how.outgoing.after),j.on("click",".flat_pm_out .flat_pm_crs",function(){jQuery(this).parent().removeClass("show").addClass("closed")})}countMode&&(flat_count["block_"+a.ID]={},flat_count["block_"+a.ID].count=1,flat_count["block_"+a.ID].click=0,flat_count["block_"+a.ID].id=a.ID)}catch(a){console.warn(a)}}function flatPM_start(){let a=flat_pm_arr.length;if(0==a)return flat_pm_arr=[],void jQuery(".flat_pm_start, .flat_pm_end").remove();flat_body=flat_body||jQuery("body"),!flat_counter&&countMode&&(flat_counter=!0,flat_body.on("click","[data-flat-id]",function(){let a=jQuery(this),b=a.attr("data-flat-id");flat_count["block_"+b].click++}),flat_body.on("mouseenter","[data-flat-id] iframe",function(){let a=jQuery(this),b=a.closest("[data-flat-id]").attr("data-flat-id");flat_iframe=b}).on("mouseleave","[data-flat-id] iframe",function(){flat_iframe=-1}),jQuery(window).on("beforeunload",()=>{jQuery.isEmptyObject(flat_count)||jQuery.ajax({async:!1,type:"POST",url:ajaxUrlFlatPM,dataType:"json",data:{action:"flat_pm_ajax",data_me:{method:"flat_pm_block_counter",arr:flat_count}}})}).on("blur",()=>{-1!=flat_iframe&&flat_count["block_"+flat_iframe].click++})),flat_userVars.init();for(let b=0;bflat_userVars.textlen||void 0!==a.chapter_sub&&a.chapter_subflat_userVars.titlelen||void 0!==a.title_sub&&a.title_subc&&cc&&c>d&&(b=flatPM_addDays(b,-1)),b>e||cd||c-1!=flat_userVars.referer.indexOf(a))||void 0!==a.referer.referer_disabled&&-1!=a.referer.referer_disabled.findIndex(a=>-1!=flat_userVars.referer.indexOf(a)))&&(c=!0),c||void 0===a.browser||(void 0===a.browser.browser_enabled||-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser))&&(void 0===a.browser.browser_disabled||-1==a.browser.browser_disabled.indexOf(flat_userVars.browser)))){if(c&&void 0!==a.browser&&void 0!==a.browser.browser_enabled&&-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser)&&(c=!1),!c&&(void 0!==a.geo||void 0!==a.role)&&(""==flat_userVars.ccode||""==flat_userVars.country||""==flat_userVars.city||""==flat_userVars.role)){flat_pm_then.push(a),flatPM_setWrap(a),flat_body.hasClass("flat_pm_block_geo_role")||(flat_body.addClass("flat_pm_block_geo_role"),flatPM_ajax("flat_pm_block_geo_role")),c=!0}c||(flatPM_setWrap(a),flatPM_next(a))}}}let b=jQuery(".flatPM_sticky");b.each(function(){let a=jQuery(this),b=a.data("height")||350,c=a.data("top");a.wrap("
");let d=a.parent()[0];flatPM_sticky(this,d,c)}),debugMode||countMode||jQuery("[data-flat-id]:not([data-id-out]):not([data-id-modal])").contents().unwrap(),flat_pm_arr=[],jQuery(".flat_pm_start, .flat_pm_end").remove()}

LPT-ПОРТ

Следует учитывать, что USB-Lpt адаптеры к принтерам реализуют только часть функций “аппаратного” Lpt порта, существуют сложности адресации, к управлению внешними устройствами они, как правило – непригодны. Программа для экспериментов с Lpt портом: lpt.zip.

Выводы порта можно разделить на четыре группы: это 'земля' (8 выводов, обозначены черным цветом) – контакты 18-25. Красным цветом обозначены 8 выводов двунаправленного регистра Data (контакты 2-9), программируемого и возможна установка логических уровней (0-5в) извне.

Адрес: 0x378 – в 16-ричной системе или 888 в десятичной (на рис. написано &H378 – это тоже самое что и 0x378, первое обозначение присуще языку Pasсal и ему подобным). Осталось еще два регистра. Однонаправленный регистр Status (контакты 10-13, 15).

Управлять им можно только извне, через внешнее устройство (имеется в виду изменять данные на нем, читать можно из любого регистра в любую сторону). Он имеет адрес 0x379 – в 16-ричной системе или 889 в десятичной. И регистр Control (контакты 1, 14, 16-17).

Он имеет всего 4 контакта и может управляться только программой. Его адрес: 890 в десятичной системе.

Работа из под Delphi. Регистрируем библиотеку inpout32.dll.

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; function Inp32(PortAdr: word): byte; stdcall; external 'inpout32.

dll'; function Out32(PortAdr: word; Data: byte): byte; stdcall; external 'inpout32.dll'; var Port: word; Data: Byte; Посылка данных из окошек: Data:= StrToInt(Edit1.Text); Port:= StrToInt(Edit2.

Text); Out32(Port, Data); Аналогично делаем для чтения данных.

Port:= StrToInt(Edit3.Text); Data:= Inp32(Port); MessageDlg('Value: '+ IntToStr(Data), mtInformation, [mbOK], 0);

Допустим, на выводе регистра Data под номером 3 (3 – это номера вывода LPT порта) нужно установить логическую 1 (т.е. чтоб между ножкой и землей было +5 В) и на остальных выводах этого регистра (2,4-9 выводы порта) были нули. В операционных системах, позволяющих получить прямой доступ к регистру, пишем код (опираясь на функцию Out32 библиотеки inpout32.dll):

int Address=888; int data=2;

Out32(Address, data);

Ниже размещен пример вывода кода 245:

Считать данные из порта (Inp32 это функция для чтения данных из порта библиотеки inpout32.dll):

int Address=888; int data;

data = Inp32(Address);

На выводах порта 2,4,6-9 сейчас +5 В а на выводах 3,5 0 В. (см. рис. выше). Как уже упомянуто выше, в регистр Data данные записать может и внешнее устройство.

Исходно, на всех выводах регистра Status (10-13, 15) находится высокий уровень напряжения +5 В. Заземлением можно менять уровень до нуля (подача данных извне). Он имеет инвертированные выводы и рабочими являются биты под номерами 4-7, а 0-3 не используются. Чтение:

int Address=889; //адрес регистра Status int data;

data = Inp32(Address);

После первого замыкания выводов Status, начинают мигать выводы Data и Control. Это связано с тем, что порт LPT предназначен для подключения принтера, а выводы Status он использует, для того, чтобы сообщить компьютеру служебную информацию. Изменения на выводах Status регистрирует драйвер операционной системы.

Он же проводит и ответные действия, для нас наблюдаемые в виде периодического изменения состояния других выводов. Тут уж ни чего не поделаешь. Обычно, в начале работы с портом далается замыкание какой-нибудь линии регистра Status на землю, примерно через минуту драйвер утихомирится.

После этого порт свободен, и новые операции над регистром Status не приводят к неконтролируемым процессам в порту.

Особенности ввода информации в компьютер через стандартные порты обсуждаются также здесь: http://www.pcports.ru/, Com-Lpt-Win32.

COM-ПОРТ, ТИПОВЫЕ СХЕМЫ

COM-порт, контакты.

1 DCD Data Terminal Ready

5 GND == System Ground

6 DSR Request to Send

8 CTS<\p>

Источник: http://vol-alchevsk.ucoz.net/index/uprovlenie_ltp_com_portom/0-56

Советы / Программирование портов ввода/вывода (LPT и ISA)

Данный материал взят с:

Данный материал основан на моём (его) личном опыте работы с материнской платой неизвестного (нет, не солдата) производителя. Чипсет – SIS.

Если вдруг в Вашем случае дело будет обстоять другим образом, напишите мне. Также хочу сразу предупредить – я не профессиональный программист!!! Поэтому не ругайте меня за отсутствие проф.

терминов, может быть кривых объяснений или ещё каких недочётов, которые я имею право не знать.

В повседневной практике я использую язык программирования “Паскаль”, поэтому дальнейшие примеры буду давать на нём. Согласен, для написания “драйверов” лучше знать СИ и Ассемблер. Последний я на данный момент изучаю. Для моих устройств пока что хватает и Паскаля.

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

Обычно этот порт имеет базовый адрес 378h (LPT1), 278h (LPT2), 3BCh (LPT3). Окончание “h” свидетельствует о шестнадцатиричной системе счисления, так уж принято записывать адреса.

Порт занимает три адреса, первый из них называется базовым. Так, для LPT1 диапазон занимаемых им адресов: 378h-37Ah. Базовый адрес служит для посылки/чтения байта на/из линии d0-d7 (пины 2-9 разъёма DB-25). Посылка не инвертируется.

Приведу фрагмент программы, посылающей в порт число 170.

{начало программы} … begin Port[$378]:=170 end.

{конец программы}

При запуске её на линиях d0-d7 появится число 170 в двоичном виде, что соответсвует 10101010. Т.е. единичный сигнал будет присутствовать на выводах d1, d3, d5, d7 (обозначени выводов начинается с d0!).

Число 170 останется на выводах разъёма до тех пор, пока Вы не перешлёте туда же другое число (это может сделать и другая программа) или не выключите компьютер. Заметьте, что адрес порта в команде задан в шестнадцатиричном виде, а посылка – в десятиричном.

Если вместо команды Port[$378]:=170; Вы примените d:=Port[$378];

где d – некоторая переменная, то переменная примет значение последнего посланного в порт байта или, при переходе в режим приёма, значение байта, поданного на порт внешним устройством.

Базовый+1 адрес (379h для LPT1) служит для чтения состояний принтера, поступающих на входы ACK, -BUSY, PE, SLCT, ERROR. Сигнал -BUSY – инвертированныё, т.е. при подаче на него +5В компьютер будет считывать “0”. Для опроса линий используются только старшие 5 битов. “1” в третьем бите соответствует высокому уровню сигнала на входе ERROR.

В четвёртом бите она индицирует о высоком уровне сигнала на входе SLCT, в пятом – на входе PE. Единица в шестом бите соответствует высокому уровню сигнала на ACK, а ноль в седьмом – выскому уровню на -BUSY.

Если ваш компьютер имеет однонаправленный порт передачи данных, то эти пять линий предоставляют единственную возможность в опросе состояний внешних датчиков.

Ниже – пример программы, опрашивающей входные линии порта: begin d:=Port[$379]

end.

В переменной d после выполнения программы будет отображено состояние порта. Допустим, переменная вернула значение 126. В двоичном виде оно выглядит как 01111110. Младшие (правые) три бита (нулевой, первый и второй) не используются, и всегда равны 1, 1 и 0. Третий бит – 1, значит на ERROR высокий уровень. Та же ситуация на SLCT, PE, ACK и BUSY.

Базовый+2 адрес (37Ah) служит для записи битов на линии -STROBE, -AUTO FD, INIT, -SLCT IN. Нулевой бит посылает сигнал на -STROBE, первый – на -AUTO FD, второй – на INIT, и четвёртый – на -SLCT IN.

Принцип записи – тот же, что и по базовому адресу. Нам же очень интересны следующие биты: Пятый бит служит для разрешения/запрещения прерывания от внешнего устройства.

Это полезно, если Вы умеете писать обработчики прерываний.

Шестой бит служит для перевода линий d0-d7 в режим приёма!!! Но перед этим необходимо убедиться, что в BIOS в типе порта поставлено SPP/EPP. Вот пример программы, которая считывает бит с линий данных: begin Port[$37A]:=32; {32 “зажигает” единицу в шестом бите} d:=Port[$378];

end.

Не забудьте, что если Вы собрали устройство, которое через порт принтера опрашивает, допустим, один датчик, подключенный к d0 (pin 2), а остальные линии просто оставили “висеть” на воздухе, то в случае, когда на втором контакте порта будет единица, принимаемый байт будет не “1” а 255, т.к. неподключенные контакты имеют высокий уровень.

Программирование ISA устройств.

Программирование портов ISA практически не отличается от программирование порта LPT, т.к. по сути дела сам порт принтера является ISA устройством.

Отличие состоит только в том, что при работе с параллельним портом можно было обходится без прерываний (хотя при разработке устройств, обрабатывающих данные в “real time” без них не обойтись).

Если Вы решили собирать ISA устройство, то очевидно, что Вам как раз и нужна обработка в реальном времени или быстрый (по сравнению с LPT) обмен данными. К сожалению, я пока что не имел опыта разработки драйверов, используюих прервания, поэтому на данный момент не смогу Вам объяснить методы написания таковых.

Возъмём простейший случай, когда Вы решили использовать шину ISA только для достижения 16-разрядного обмена. Если адрес LPT порта (в общем случае) является уже заданным, то Ваше устройство может использовать любые адреса (естественно, не занятые другими устройствами). Могу дать несколько советов при выборе адреса, который будет занимать устройство:

  • Тщательно проверьте, не будет ли оно конфликтовать с другими устройствами. Это может быть не только видеокарта, модем или звуковая карта, но и что-либо из внутренних устройств на материнской плате. Поиск свободных адресов можно осуществить в простейшем случае из Windows (Свойства: система -> Устройства. Двойной щелчок по пиктограмме “Компьютер” высветит меню, в котором можно будет просмотреть адреса).
  • Для подстраховки и удобства переноса устрйства на другой компьютер лучше сделать возможность выбора разных адресов джамперами (если Вы сможете организовать Plug&Play, тогда преклоняю свои колени..).
  • Старайтесь не занимать верхних адресов, т.к. они могут попросту не выводится на шину. Держитесь в окресностях адресного пространства, которое занимают другие ISA устройства.
  • Не забывайте выводить старшие линии адресов на своё устройство, т.к. может оказаться, что оно будет совпадать с другими устройствами младшими битами адреса.
  • Если Вы сделали выборку адресов джамперами, то программируя на Паскале трудно будет программно изменить адрес устройства (поправьте, если я не прав). Будет гораздо проще применить Ассемблер-вставку в Вашу программу:mov dx, amov al, d

    out dx, al

    Здесь в регистр dx мы кладём адрес порта, а в al – байт для отправки. Переменные a и d мы может спокойно передавать вставке из программы.

    Источник: http://www.qrz.ru/schemes/contribute/icenet/SO/so000030.shtml