![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с LPT-портом [D7, WinXP]
Alex_C © (2009-11-26 08:23:00)Кто нибудь при работе с LPT-портом использовал драйвер DLPortIO? Написал на заказ программу - простенькую по управлению некоторым оборудованием через LPT (там всего лишь на некоторых ножках порта выставляется высокий или низкий уровень). У меня все работает, а у заказчика (который в другом городе) такая проблема: если запустить мою программу - ничего не работает. Если перед этим запустить другую программу, которая работает с LPT тоже при помощи этого драйвера, выйти из нее, а потом опять запустить мою - то все работает. Как такое может быть?
Вариант (2009-11-30 06:03:00) [1]
> Alex_C (27.11.09 08:41) [14]
С точки зрения интерфейса центроникс - 1 пин разъема параллельного порта (LPT) - это сигнал Strobe. Обмен данными с принтером завязан естественно с сигналом строб.
Но например для зажигания лампочек цветомузыки значения может и не иметь. Так что просто надо знать протокол обмена на уровне интерфейса с тем железом, которым ты управляешь через порт. И указывать нужный режим работы порта в программе (см [7]) - тоже будет правильно. А то так возможно и будет у разных клиентов работать по разному.
Alex_C (2009-11-27 08:41:00) [2]Нет ребят!
Не надо драйвер в системе регистрировать :)
Все и так работает - подсказали уже: кстати ОЧЕНЬ важная информация для тех, кто хочет работать с LTP портом: оказывется перед началом работы на 1-й ножке порта нужно выставить 0 - и все начинает работать. На мой вопрос - а зачем? Ответиль не смогли - просто чисто опытным путем выяснили. Но факт - инициализация порта должна выглядеть так:
Lpt := TDLPortIO.Create(nil);
Lpt.DriverPath := ExtractFileDir(ParamStr(0));
Lpt.DLLPath := ExtractFileDir(ParamStr(0));
Lpt.OpenDriver;
if not Lpt.ActiveHW then
begin
FreeAndNil(Lpt);
raise Exception.Create('Error LPT port for CW/PTT');
end;
LPTPinOn(1, False);
Кстати, может кто знает а почему так?
Сергей М. (2009-11-26 21:40:00) [3]Какой выдающийся поток сознания !..
vens (2009-11-26 15:59:00) [4]ваава
vastani (2009-11-26 15:57:00) [5]теги блин слетели.... ну ниче копи-паст а там красивее...
Вообще гдето так. Надеюсь разберешься!
vastani (2009-11-26 15:54:00) [6]
const
DISPLAY_NAME : PChar = 'DriverLINX Port I/O Driver';
DRV = 'DLPortIO';
NmLIB = DRV + '.DLL';
FNmDRV = 'DRIVERS\' + DRV + '.SYS';
{ Имя символuческой связи }
NmDRV_LINK : PChar = '\\.\'+ DRV;
NmDRV : PChar = DRV;
procedure TForm1.KOLForm1Close(Sender: PObj; var Accept: Boolean);
begin
if hDRV <> INVALID_HANDLE_VALUE then CloseHandle( hDRV );
// if UnregService and winnt then
begin // разрегистрировать сервис
if hDLL <> 0 then
begin
hSCMan := OpenSCManager_( nil, nil, SC_MANAGER_ALL_ACCESS ); // Связаться с менеджером сервисов
if 0 <> hSCMan then
begin
hService := OpenService_( hSCMan, NmDRV, SERVICE_ALL_ACCESS); // Получить хэндл сервиса lptwdmio
if hService <> 0 then
begin
DeleteService_( hService ); // Пометить сервис как подлежащий удалению. Драйвер останется в памяти до ближайшей перезагрузки.
CloseServiceHandle_( hService ); // Освобождаем хэндл
end;
CloseServiceHandle_( hSCMan ); // Высвободить хэндл менеджера сервисов
end;
FreeLibrary( hDLL ); // Высвободить хэндл библиотеки AdvApi32.dll
end;
end;
end;
///////////////////////
var
SysName : AnsiString; // Имя файла драйвера
ServiceArg : PChar; // Вспомогательная переменная для вызова StartService
CreateService_ : PCreateService; // -//- CreateService
StartService_ : PStartService; // -//- StartService
procedure ConnectDRV;
begin
SetLastError( NO_ERROR );
hDRV := CreateFile( NmDRV_LINK,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
end;
begin
// Первичная инициализация
hDRV := INVALID_HANDLE_VALUE;
// UnregService := False;
hDLL := 0;
// Попытка связаться с драйвером
ConnectDRV;
if hDRV = INVALID_HANDLE_VALUE then
// if winnt then // Не удалось связаться с драйвером. Он не был установлен вручную.
begin
// Windows NT -- пробуем запустить драйвер через менеджер управления сервисами
hDLL := LoadLibrary(PChar('ADVAPI32.DLL')); // Получим указатели на ф-и менеджера сервисов.
if hDLL <> 0 then
begin
// Re: чтобы программа работала и на NT, и на 9x, используем динамическую загрузку AdvApi32.dll
// Получим указатели на ф-и в AdvApi32.dll
OpenSCManager_ := POpenSCManager(GetProcAddress( hDLL, PChar('OpenSCManagerA')));
CloseServiceHandle_ := PCloseServiceHandle(GetProcAddress( hDLL, PChar('CloseServiceHandle')));
CreateService_ := PCreateService(GetProcAddress( hDLL, PChar('CreateServiceA')));
StartService_ := PStartService (GetProcAddress( hDLL, PChar('StartServiceA' )));
OpenService_ := POpenService (GetProcAddress( hDLL, PChar('OpenServiceA' )));
DeleteService_ := PDeleteService(GetProcAddress( hDLL, PChar('DeleteService' )));
// Свяжемся с менеджером сервисов
hSCMan := OpenSCManager_( nil, nil, SC_MANAGER_ALL_ACCESS );
if 0 <> hSCMan then
begin // Связались успешно
SysName := GetWorkDir + 'DLPortIO.SYS'; // имя бинарника sys в рабочей папке
if not FileExists( SysName ) then
SysName := GetSystemDir + FNmDRV; // имя бинарника sys в SYSTEM32
// Попытка создания сервиса
hService:= CreateService_( hSCMan,
NmDRV, // имя сервиса
DISPLAY_NAME, // отображаемое имя
SERVICE_ALL_ACCESS, // права доступа
1, // SERVICE_KERNEL_DRIVER
3, // SERVICE_DEMAND_START
1, // SERVICE_ERROR_NORMAL
PChar( SysName ),
nil, nil, nil, nil, nil);
if 0 = hService then
begin // Возможно, сервис был создан ранее
hService := OpenService_( hSCMan, NmDRV, SERVICE_ALL_ACCESS ); // откроем его
end;
if 0 <> hService then
begin // ОК, запускаем сервис
ServiceArg := nil;
StartService_( hService, 0, ServiceArg ); // Наш драйвер должен загрузиться...
// UnregService := True; // При разрушении объекта не забыть пометить сервис для удаления
CloseServiceHandle_( hService ); // Освобождаем хэндл
end;
CloseServiceHandle_( hSCMan ); // Освобождаем хэндл
end;
end;
// Вторично пытаемся связаться с драйвером
ConnectDRV;
end;
vastani (2009-11-26 15:48:00) [7]Ну приветик Alex_C, теперь тебе здесь! ))))))))
только что отписал тебе по ком-портам в ветке, а ты тут уж про LPT, замутил?! ))))))
Придется тебе пиво высылать виртуальной бандеролью! )
А твоя проблема, голубчик в том, что та прога в отличие от твоей УМЕЕТ РЕГИСТИРОВАТЬ В СИСТЕМЕ доайвер и активировать его в .... кажись менеджер драйверов или служда называется....
У меня 1:1 это пройдено и именно с этим драйвером!
Когда ты пускаешь свою прогу она пользуется "чужими трудами" :) вернее результатами. Система уже имеет подгруженный драйвер и расшатенные вещи, а твоя лишь юзает оные!
Сергей М. (2009-11-26 11:32:00) [8]
> та программа настраивает порт на нужный режим работы
Оч даже себе вариант.
При этом отсутствие аналогичной ф-ти в программе автора топика как раз и м.б. ошибкой в 17-й строке)
Вариант (2009-11-26 10:46:00) [9]
> Alex_C (26.11.09 08:23)
> Если перед этим запустить другую программу, которая работает
> с LPT тоже при помощи этого драйвера, выйти из нее, а потом
> опять запустить мою - то все работает. Как такое может быть?
>
Как вариант, та программа настраивает порт на нужный режим работы (ECP,EPP,SPP....).
Сергей М. (2009-11-26 09:59:00) [10]
> Alex_C (26.11.09 09:13) [5]
ну уже что-то чем совсем ничего)
Ну так и что не работает ?
Alex_C (2009-11-26 09:13:00) [11]Собственно нет там 17 строки...
Их существенно меньше )))
Lpt := TDLPortIO.Create(nil);
Lpt.DriverPath := ExtractFileDir(ParamStr(0));
Lpt.DLLPath := ExtractFileDir(ParamStr(0));
Lpt.OpenDriver;
if not Lpt.ActiveHW then
begin
FreeAndNil(Lpt);
raise Exception.Create('Error LPT port for CW/PTT');
end;
а далее уже пишем в порт. Pin - номер вывода на котором устанавливаем уровень сигнала, LPTBase - адрес порта.
procedure LPTPinOn(Pin: integer; State: Boolean);
const
// Masks
BIT0 : Byte = $01;
BIT1 : Byte = $02;
BIT2 : Byte = $04;
BIT3 : Byte = $08;
BIT4 : Byte = $10;
BIT5 : Byte = $20;
BIT6 : Byte = $40;
BIT7 : Byte = $80;
begin
if Lpt = nil then
begin
Application.MessageBox('LTP port not open!', 'Error!', MB_OK);
Exit;
end;
if (State) then
begin
case Pin of
1: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT0); // Inverted
2: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT0;
3: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT1;
4: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT2;
5: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT3;
6: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT4;
7: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT5;
8: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT6;
9: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] or BIT7;
(*
10: Port[FLPTBase+1] := Port[FLPTBase+1] or BIT6;
11: Port[FLPTBase+1] := Port[FLPTBase+1] and (not BIT7); // Inverted
12: Port[FLPTBase+1] := Port[FLPTBase+1] or BIT5;
13: Port[FLPTBase+1] := Port[FLPTBase+1] or BIT4;
*)
14: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT1); // Inverted
(*
15: Port[FLPTBase+1] := Port[FLPTBase+1] or BIT3;
*)
16: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT2;
17: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT3); // Inverted
else
// pins 18-25 (GND), and other invalid pins
end
end else
begin
case Pin of
1: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT0; // Inverted
2: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT0);
3: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT1);
4: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT2);
5: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT3);
6: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT4);
7: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT5);
8: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT6);
9: Lpt.Port[LPTBase] := Lpt.Port[LPTBase] and (not BIT7);
(*
10: Port[FLPTBase+1] := Port[FLPTBase+1] and (not BIT6);
11: Port[FLPTBase+1] := Port[FLPTBase+1] or BIT7; // Inverted
12: Port[FLPTBase+1] := Port[FLPTBase+1] and (not BIT5);
13: Port[FLPTBase+1] := Port[FLPTBase+1] and (not BIT4);
*)
14: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT1; // Inverted
(*
15: Port[FLPTBase+1] := Port[FLPTBase+1] and (not BIT3);
*)
16: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT2);
17: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT3; // Inverted
else
// pins 18-25 (GND), and other invalid pins
end
end;
end;
Сергей М. (2009-11-26 09:06:00) [12]
> Не понятно где?
Известно где - в 17-й строке)
> как такое может быть в принципе
А оч просто - за тобой вообще-то замечена дурная привычка не анализировать рез-ты вызовов API-функций. Она, думаю, как раз и играет с тобой "злую шутку")
miek (2009-11-26 09:06:00) [13]ошибка в 17 строке
Alex_C (2009-11-26 08:58:00) [14]
> Да как обычно - ошибка у тебя в программе)
Это понятно... )))
Не понятно где? И как такое может быть в принципе - ну если вообще не работало - тут ясно, а так...
Сергей М. (2009-11-26 08:25:00) [15]
> Как такое может быть?
Да как обычно - ошибка у тебя в программе)