Форум РадиоКот https://radiokot.ru/forum/ |
|
LPT nibble mode https://radiokot.ru/forum/viewtopic.php?f=24&t=57036 |
Страница 1 из 3 |
Автор: | Kvasshtain [ Пн окт 24, 2011 09:50:44 ] |
Заголовок сообщения: | LPT nibble mode |
Кошаны ![]() ![]() |
Автор: | Avarges [ Пн окт 24, 2011 18:21:25 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Просто так обращаться к LPT на современных компах не получится, драйвер надо использовать. К примеру, в программаторе uniprof используется LPTWDMIO.SYS |
Автор: | Kvasshtain [ Ср окт 26, 2011 12:39:27 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Да я это все знаю ![]() ![]() ![]() |
Автор: | МитяРа [ Ср окт 26, 2011 12:43:06 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Kvasshtain писал(а): Там очевидно загвоздка в правильности подачи сигналов квитирования. Не факт.. Может ты просто не с того регистра читаешь..
|
Автор: | Kvasshtain [ Ср окт 26, 2011 16:12:16 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Это как? В смысле не понял какой регистр? Вот собственно код: Код: unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Windows; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } const IOCTL_PAR_SET_WRITE_ADDRESS = $16001C; IOCTL_IEEE1284_NEGOTIATE = $160018; IOCTL_IEEE1284_GET_MODE = $160014; type PARCLASS_NEGOTIATION_MASK = record usReadMask: word; usWriteMask: word; end; PPARCLASS_NEGOTIATION_MASK = ^PARCLASS_NEGOTIATION_MASK; var hLpt: THandle; ret: DWORD; Address: byte; Data: byte; // данные для чтения ReqMode, LptMode: PARCLASS_NEGOTIATION_MASK; lpOverlapped: POverlapped; procedure TForm1.FormCreate(Sender: TObject); begin // Открыть порт для синхронного доступа hLpt := CreateFile('LPT1', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); ReqMode. usReadMask:= $0010; // Режим BYTE_BIDIR (только для чтения) ReqMode. usWriteMask:= $0000; // Режим NONE (только для записи), т.е. не пишем вообще // Задаем режим DeviceIoControl(hLpt, IOCTL_IEEE1284_NEGOTIATE, @ReqMode, sizeof(PARCLASS_NEGOTIATION_MASK), @LptMode, sizeof(PARCLASS_NEGOTIATION_MASK), ret, lpOverlapped); end; procedure TForm1.Button1Click(Sender: TObject); begin ReadFile(hLPT, Data, 1, ret, nil); Edit1.Caption:=IntToStr(Data); end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin // Закрыть устройство CloseHandle(hLpt); end; end. Приложение работает, но при нажатии на кнопку “прочитать”, просто виснет, чего то ожидая. Вот как раз что оно ждет? |
Автор: | МитяРа [ Ср окт 26, 2011 16:20:12 ] |
Заголовок сообщения: | Re: LPT nibble mode |
В Сях и прочих не Ассемблерах - не силён.. ![]() |
Автор: | Kvasshtain [ Ср окт 26, 2011 16:37:56 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Вот тут http://www.zntu.edu.ua/base/lection/rpf ... pr/lpt.htm написано про этот самый Nibble mode. Так вот там обмен сигналами следующий: Прием байта данных в полубайтном режиме состоит из следующих фаз: 1. Хост сигнализирует о готовности приема данных установкой низкого уровня на линии HostBusy. 2. ПУ в ответ помещает тетраду на входные линии состояния. 3. ПУ сигнализирует о действительности тетрады установкой низкого уровня на линии PtrClk. 4. Хост устанавливает высокий уровень на линии HostBusy, указывая на заня-тость приемом и обработкой тетрады. 5. ПУ отвечает установкой высокого уровня на линии PtrClk. 6. Шаги 1-5 повторяются для второй тетрады. Вопрос: Каким образом можно тупо, без всяких там схемотехнических ухищрений принять байт, состоящий из двух одинаковых половинок по 4-ре бита, например 01100110 или 11001100, установив соответствующие переключатели на соответствующих сигнальных линиях LPT порта? Т.е. просто проверять наличие соответствующих сигналов? ![]() |
Автор: | МитяРа [ Ср окт 26, 2011 16:40:55 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Попробуй просто соединить сигналы HostBusy с PtrClk... |
Автор: | Kvasshtain [ Ср окт 26, 2011 16:49:24 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Да ![]() ![]() |
Автор: | МитяРа [ Ср окт 26, 2011 16:56:05 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Нет.. |
Автор: | Kvasshtain [ Пт окт 28, 2011 13:03:46 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Ни фига ни чего не получилось. ![]() |
Автор: | Мастер Ломастер [ Пт окт 28, 2011 13:09:37 ] |
Заголовок сообщения: | Re: LPT nibble mode |
для винды LPT прочно ассоциируется с принтером, поэтому работа через функции ввода-вывода возможна только при наличии следующих условий: 1. нет сигнала Paper End 2. нет сигнала Busy оба эти сигнала заводятся на пины LPT-порта и как раз-таки соединены (аппаратно-програмно) с битами в том самом регистре, который вы надеетесь прочитать. выходит, либо вы должны пожертвовать 2-я из 5-и битов, либо все-таки использовать библиотечку доступа к портам напрямую без WinAPI. кстати, я далеко не уверен, что при помощи WinAPI вообще можно достучаться до каких-то регистров, кроме регистра данных LPT... |
Автор: | Kvasshtain [ Пт окт 28, 2011 14:13:28 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Что касается 1. нет сигнала Paper End 2. нет сигнала Busy Всмысле я должен подать на эти ножки ноль и все? Или я что-то не понял? Вот здесь (правда очень витиевато) http://citforum.ru/operating_systems/windows/parp_win/ написано про запись и чтение LPT. Как я понял, автор там читает в режиме nibble mode, т.к. в коде он ни чего не перенастраивает, а как он сам сказал «Сразу после того, как порт открыт, он устанавливается в режим CENTRONICS по записи и NIBBLE по чтению». Да, и кстати, я руководствуясь этой статьей написал вполне рабочую программу – бегущий огонь. Вот код: Код: unit Unit1;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, Windows; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; direction: boolean; // переменная задающая направление движения бегущего огня // true - влево, false - вправо Data: byte; hLpt: THandle; ret: DWORD; const IOCTL_PAR_SET_WRITE_ADDRESS = $16001C; IOCTL_IEEE1284_NEGOTIATE = $160018; const IOCTL_IEEE1284_GET_MODE = $160014; type PARCLASS_NEGOTIATION_MASK = record usReadMask: word; usWriteMask: word; end; PPARCLASS_NEGOTIATION_MASK = ^PARCLASS_NEGOTIATION_MASK; var ReqMode, LptMode: PARCLASS_NEGOTIATION_MASK; lpOverlapped: POverlapped; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); // кнопка "налево" begin Timer1.Enabled:=true; // запускаем таймер direction:=true; // задаем направление end; procedure TForm1.Button2Click(Sender: TObject); // кнопка "направо" begin Timer1.Enabled:=true; // запускаем таймер direction:=false; // задаем направление end; procedure TForm1.Button3Click(Sender: TObject); // кнопка "СТОП" begin Timer1.Enabled:=false; // останавливаем таймер end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin Data:=0; // в конце потушим диод WriteFile(hLpt, Data, 1, ret, nil); // Закрыть устройство CloseHandle(hLpt); end; procedure TForm1.FormCreate(Sender: TObject); begin // Открыть порт для синхронного доступа hLpt := CreateFile('LPT1', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); ReqMode. usReadMask:= $0010; // Режим BYTE_BIDIR (только для чтения) ReqMode. usWriteMask:= $0002; // Режим IEEE_COMPATIBILITY (только для записи) // Задаем режим DeviceIoControl(hLpt, IOCTL_IEEE1284_NEGOTIATE, @ReqMode, sizeof(PARCLASS_NEGOTIATION_MASK), @LptMode, sizeof(PARCLASS_NEGOTIATION_MASK), ret, lpOverlapped); Data:=$80; // в начале будет гореть крайний левый диод end; procedure TForm1.Timer1Timer(Sender: TObject); begin if direction = true then Begin Data:=Data shl 1; If Data = 0 then Data:=1; // если дошли до конца, то начнем с другого конца end else Begin Data:=Data shr 1; If Data = 0 then Data:=$80; // если дошли до конца, то начнем с другого конца end; WriteFile(hLpt, Data, 1, ret, nil); end; end. |
Автор: | Мастер Ломастер [ Пт окт 28, 2011 14:17:28 ] |
Заголовок сообщения: | Re: LPT nibble mode |
одно дело работать с LPT на запись - тут вообще можно пользоваться паскалевской функцией write даже без WinAPI. и совсем иное дело работать с LPT на чтение. тем более на чтение не из регистра данных, а из служебных регистров. |
Автор: | Kvasshtain [ Пт окт 28, 2011 14:19:37 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Оу, забыл сказать, недавно обнаружил, что некоторые программы для работы с LPT портом наворачивают нормальную работу сего кода. Вот здесь http://www.freepascal.ru/forum/viewtopi ... =13&t=7500 я спрашивал об этом у знающих людей. |
Автор: | Kvasshtain [ Пт окт 28, 2011 14:22:51 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Да вот хорошо бы найти все-таки рабочий примерчик, или инфу хоть какую-нибудь про чтение в этом режиме. Это же очень удобно, например, для считывания состояния концевых выключателей в каком-нибудь самодельном станке. |
Автор: | Lavr [ Чт ноя 17, 2011 02:19:56 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Kvass, я пошустрил по разным источникам, и в одном сурьёзном прочитал: Цитата: ' Примечание. Данные из параллельного порта нельзя прочитать с помощью функции ReadFile. Вот оригинальная ссылка: http://support.microsoft.com/kb/823179 Посмотри исходник - они на вывод поступают, как и ты: Код: ' Запись данных в порт LPT1. ' Примечание. Данные из параллельного порта нельзя прочитать с помощью функции ReadFile. Console.WriteLine("Запись следующих данных в порт LPT1: тест") Success = WriteFile(hParallelPort, Buffer, Buffer.Length, BytesWritten, IntPtr.Zero) If Success = False Then Throw New CommException("Не удается записать данные в порт LPT1") End If А как же всёж читать? Читать в других источниках советуют так: Цитата: А вот чтобы читать из микроконтроллера, придётся через DeviceIoControl опрашивать статусные линии и по ним принимать информацию в nibble mode. Код: const char lpt[] = "LPT1"; HANDLE hLpt = 0; UCHAR ParInfo; // сюда примем состояние статусных входов LPT DWORD ret; hLpt = CreateFile( lpt, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); // ну, само собой проверки DeviceIoControl(hLpt, IOCTL_PAR_QUERY_INFORMATION, NULL, 0, &ParInfo, sizeof(ParInfo), &ret, NULL); // Назначение бит в байте ret (как это определено в <ntddpar.h>) #define PARALLEL_INIT 0x01 #define PARALLEL_AUTOFEED 0x02 #define PARALLEL_PAPER_EMPTY 0x04 #define PARALLEL_OFF_LINE 0x08 #define PARALLEL_POWER_OFF 0x10 #define PARALLEL_NOT_CONNECTED 0x20 #define PARALLEL_BUSY 0x40 #define PARALLEL_SELECTED 0x80 Источник: http://electronix.ru/forum/lofiversion/index.php/t68687.html Хороший пример работы файловыми функциями с LPT приведён, на мой взгляд, здесь: http://asm.shadrinsk.net/arh/res1.php?par5=129764&par4=0&n=30 |
Автор: | kolobok0 [ Пт ноя 18, 2011 12:29:28 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Kvasshtain писал(а): ... nibble mode у LPT... ну во первых изначально LPT читать (регистр данных) нельзя было. только писать. Но начиная с 286 машин, некоторые контроллеры могли читать из регистра данных. Обычно нужно было разрешить в биосе(если был такой флажок там) и собственно сам контроллер LPT умеющий читать. но у порта всегда было 5 линий состояний. вот по ним, по 4 бита плюс строб и передавались данные. как это делать под форточками - надо вкуривать WinAPI. если нет реальных 5 бит состояния порта - то никак...только дрова писать свои либо юзать те которые позволяют управлять этими пинами. удачи вам (круглый) ЗЫ Тест можно сделать сделав заглушку данные=пины состояния. Кстати нечто похожее делала программа chekit |
Автор: | Ntrud [ Пн ноя 21, 2011 18:50:00 ] |
Заголовок сообщения: | Re: LPT nibble mode |
Попробуйте протестить LPT компа рабочей программой, написанной на VIZUAL BASIC 6. Программа Test.ехе , код программы и библиотека DLL прилагаю. Библиотека подключается сама при запуске ехе файла, расположенного в той же папке. |
Автор: | Ntrud [ Пн ноя 21, 2011 18:53:41 ] | ||
Заголовок сообщения: | Re: LPT nibble mode | ||
Попробуйте протестить LPT компа рабочей программой, написанной на VIZUAL BASIC 6. Программа Test.ехе , код программы и библиотека DLL прилагаю. Библиотека подключается сама при запуске ехе файла, расположенного в той же папке.
|
Страница 1 из 3 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |