Звук
  Свет
  Радио
  Питание
  PC & GSM
  PIC и AVR
  Разное
  Справка
  Верстак
  Техника


  ФОРУМ

 

 

 

схемы электронных устройств

 

 

все темы форума одной страницей

 

 

DIY Projects

Чтение информации с LPT порта  
Автор: ZPS   Добавлено: 16.01.2003


NB! Материал по LPT был написан мной в самом начале рабты с LPT и вобще с программированием, поэтому стиль статей и термины могут вызывать удивление или даже возмущение. Не смотря на это, материал уже помог нескольким людям начать работу с LPT и собрать собственные схемы. Дополнять материал по LPT я скорее всего уже не буду, на очереди COM и USB, но для них пока не достаточно опыта.


Чтение информации с LPT порта
Предыдущие статьи:
"Что такое LPT-порт ?", "Примеры схем для LPT" и "Основы программирования LPT."

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

Для ввода информации я использовал 5 стандартных входов - выводы 10, 11, 12, 13 и 15.
Первоначальное состояние выводов - log1, т.е. на них напряжение 5V.
Мой тестер сказал, что там не 5, а 4.7V, может тестер не точно показывает, может блок питания в компе слабоват, а может так и надо - не важно.
Следовательно, замкнув вывод порта на землю (выводы 18-25), мы переведем его в состояние Log0. Замыкать вывод прямо на землю я не рискнул и соединил его с землей через резистор в 470 ом. Можно обойтись и без резистора - всё отлично работает, но лучше не рисковать.
Для дальнейших экспериментов я собрал себе панельку из 5 кнопочек по приведенной выше схеме и достал с архивного диска компилятор Turbo Pascal 7.1 (то же что и Pascal 7.0).

Тем, кто не умеет работать с портами, советую прочитать предыдущую статью "Основы программирования LPT", тк. сейчас я уже не буду подробно описывать как и почему.
Как я уже говорил, считать значение на выходах порта можно одной строчкой: data := port[$378], где $378 - базовый адрес порта. Это выходы, ими управлять мы уже умеем. А входы нахотятся по адресу "базовый+1", те. $379 пробуем считать:

Uses Dos;

Var
   data:byte; {переменная DATA типа byte}
   
Begin
   data := Port[$379]; {читаем значение порта в data}
   writeln(data);      {выводим значение на экран}
End.
В результате на экране останется число 120 (у меня так :)). Нажимаем одну из кнопок, запускаем программу ещё раз - число изменилось. Чтобы не мучиться с запуском программы и её закрытием, а просто жать на кнопки и смотреть, я немного доработал программу:
Uses dos, crt;

var data : byte;

BEGIN
  clrscr;
  while not keypressed do {пока не нажата кнопка на клавиатуре...}
  begin                   {повторяем код от сюда.....}
    data := port[$379];   {читаем значение порта в data}
    gotoxy(1,1);          {ставим курсор в позицию 1,1 на экране}
    write('   ');         {пишем пробелы чтобы замазать текст}
    gotoxy(1,1);          {возвращаем курсор назад в позицию 1,1}
    write(data);          {выводим значение на экран}
    delay(100);           {задержка в 100мс.(не точно!)}
  end;                    {.....до сюда}

END.
Для тех кто работает в Delphi, маленькая вставочка на ассемблере, тк. я не знаю как в дельфи правильно работать с портами:
asm
  MOV DX,379h;
  IN AL,DX
  MOV data,AL
end;
Эта программа будет делать следущее: выведет значение порта на экран, подождет 100мс, вернет курсор в начало строки и заменит старое значение на новое и так до тех пор, пока не нажата кнопка на клавиатуре.
Теперь можно запустить программу, убрать клавиатуру с мышкой в сторону и наблюдать за изменениями.
Вот теперь начинается головоломка... Методом тыка я нашел, что каждой кнопке соответствует своё значение (свой бит), значения присвоены очень странно, может позже я разберусь почему, но пока просто выложу их:
выводзначение
1064
11128
1232
1316
158

Я не случайно выделил 11 вывод жирным, он отличается от других - он логически инвертирован, те. если все наши кнопки система считает отжатыми, то эту она считает замкнутой. А если её замкнуть, то система будет думать что кнопка отжата.
Теперь как это всё влияет на общее число которое мы считали (120):
Если нажать на одну из наших кнопочек, то от общего числа отнимется значение этой кнопочки (см. таблицу).
Например, мы нажимаем кнопку подключеную к выводу 10 и число сразу уменьшается на 64 (см. прогу), отпустим и значение снова увеличится на 64. А теперь, нажмем кнопку на выводе 15 - значение уменьшилось на 8, отпустили и оно опять увеличилось.
А что будет если нажать особенную 11 кнопку? Нажимаем - значение не уменьшилось, а возрасло, отпустили и оно опять уменьшилось. Вот чем эта кнопка отличается от остальных 4.

А теперь по русски, как узнать программе что нажато? Я делал так:
Запоминаю что сейчас в порте, при изменении значения сравниваю что было и что получилось, если отличается на 64, значит нажата 10кнопка, если отличается на 32, значит 12 кнопка и тд. Чтобы определить нажата или отпущена, нужно учитывать увеличилось число или уменьшилось.
То есть, если число стало меньше на 32, то нажата кнопка 12, а если число увеличилось на 32, значит кнопку 12 отпустили. НО! тут нужно учитывать, что кнопка со значением 128 (11вывод) работает наоборот.
Вот то же самое, только на программерском:
Uses Dos;

uses dos, crt;

var bylo,stalo : word;
    razn : integer ;

BEGIN
  clrscr;
  bylo := port[$379];

  while not keypressed do
  begin
    stalo := port[$379];
    razn := stalo - bylo;
    case  razn of
        -64 : writeln('нажата кнопка 10 !');
         64 : writeln('отпущена кнопка 10 !');

        -32 : writeln('нажата кнопка 12 !');
         32 : writeln('отпущена кнопка 12 !');

         128 : writeln('нажата кнопка 11 !');
        -128 : writeln('отпущена кнопка 11 !');
    end;

    bylo := stalo;

  end;

END.
Надеюсь, что этого кода достаточно для начала, дальше уже можно самостоятельно разобраться или спросить помощи на форуме

Теперь снова об электронике...
В простейшем варианте можно использовать кнопочки или переключатели как в экспериментальной панельке, можно поставить геркон, тк. это тоже кнопочка, только магнитная, можно контакты реле... Но тут нужно помнить про такую нехорошую вешь, как "дребезг" контактов - расшатаный или просто некачественный выключатель обязательно будет давать повторные срабатывания в программе. Если точность не нужна, то можно просто увеличить задержку с 100 мс до, например, 1 секунды и тогда программа просто не обработает повторные нажатия. А если нужна точность, то нужно что-то придумывать.
Теоретически, связать порт можно с любым низковольтным устройством через транзистор, те. замыкать контакты не кнопкой, а транзистором. Например, у нас есть схема, в которой светодиод загорается когда кто-то проходит рядом с устройством, если светодиод подключен прямо к выводу микросхемы, просто подпиваем к ножке микросхемы вместо светодиода резистор, а резистор к базе транзистора эмиттер с коллектором которого подключены вместо выключателя к ножке. Ух, во сказал, аж сам не понял. Просто лень рисовать схему, а примерчик этот из моей практики...

На этом всё. Если остались вопросы, задавайте их на форуме, обязательно ответим!







Комментарии посетителей:
<ilus>
Спасибо за статью! В ближайшее время напишу аналоги программы на Си и на Ассемблер. Если получится, скину исходники. Если не против, конечно.
<Андрей>
Понравилась мне ваша тематика, приму и я в ней участие. Надо будет прогу хорошую написать.

Kordall@yandex.ru
ZPS
<Андрей>
Писать желательно "опен сурс" [img]images/smiles/icon_wink.gif[/img]
igorminus
Хорошая статья.
А по поводу log1=4,7V что за сомнения? Ведь не на релюхах же комп собран. На открытом транзисторе, будь он хоть CMOP, тоже что-то падает. Даже rail-to-rail схемы полное напряжение питания не выдают. А когда нагрузите, будет ещё меньше.
igorminus
Есть ссылки по теме, и сама статья любопытна. www.how-to.ru/linux/howto/Coffee-HOWTO-6.html
ZPS
igorminus
Спасибо!
Guest_Alex
По моему у тебя в програмке ошибочка.
После mov DX, 379h точка с запятой не нужна.
Мне кажется лучше приводить примеры ни Си. Этот язык более оптимизирован под программирование. на низком уровне.
ZPS
Alex
точно, не нужна. Видимо по привычке ляпнул и не заметил smile.gif

Насчет C не согласен - ASM приспособлен лучше. А Паскаль более понятен новичкам.
Drakon
Информация отличная, давно искал. Может еще про COM-порт напишешь?
Renegade
Есть хорошая программулина-справочник, называет Techhelp 6.0, там не только расписано про LPT, но и про все что нужно настоящему разработчику, примеры на ASM и вообще классная весч, помогла не плохо. Если кому надо, то пишите Renegadeslider@mail.ru
Остальные комментарии(16) можно прочитать на форуме
Добавить комментарий Перейти к обсуждению на форуме


DIY Projects