Программирование портов ввода/вывода 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, a
    mov al, d
    out dx, al

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

Источник: http://students.soros.karelia.ru/


Обсудить на форуме

Комментарии

Добавить комментарий
    • bowtiesmilelaughingblushsmileyrelaxedsmirk
      heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
      winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
      worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
      expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
      disappointedconfoundedfearfulcold_sweatperseverecrysob
      joyastonishedscreamtired_faceangryragetriumph
      sleepyyummasksunglassesdizzy_faceimpsmiling_imp
      neutral_faceno_mouthinnocent

    Стандартный параллельный интерфейс на PC

      Основным назначением интерфейса Centronics (аналог-ИРПР-М) является подключение к компьютеру принтеров различных типов.

    РАСШИРИТЕЛЬ ИНТЕРФЕЙСА ПК

      Одно из наиболее распространенных направлений использования ПЭВМ - сбор и обработка информации о состоянии датчиков, управление различными механизмами и технологическими системами.

    Протокол ARP

      В этом разделе мы рассмотрим то, как при посылке IP-пакета определяется Ethernet-адрес назначения. Для отображения IP-адресов в Ethernet адреса используется протокол ARP...

    Программатор PIC контроллеров (DOS)

      Это очень дешевый и простой программатор PIC контроллеров типа PIC16C84 /83, PIC16F84 /83, PIC16CE625 /624/623.

    Как устранить неисправность GE Fanuc IC697CPX772

      Это руководство по устранению неполадок для процессора 90-70, номер детали IC697CPX772 . Не беспокойтесь о письмах ревизии, этот тест будет одинаковым для всех из них.

    Протокол UDP

    Документ содержит русский перевод спецификации протокола UDP(User Datagram Protocol) - одного из основных транспортных протоколов стека IP,применяемого в международной компьютерной сетиInternet.