-
Кто нибудь при работе с LPT-портом использовал драйвер DLPortIO? Написал на заказ программу - простенькую по управлению некоторым оборудованием через LPT (там всего лишь на некоторых ножках порта выставляется высокий или низкий уровень). У меня все работает, а у заказчика (который в другом городе) такая проблема: если запустить мою программу - ничего не работает. Если перед этим запустить другую программу, которая работает с LPT тоже при помощи этого драйвера, выйти из нее, а потом опять запустить мою - то все работает. Как такое может быть?
-
> Как такое может быть?
Да как обычно - ошибка у тебя в программе)
-
> Да как обычно - ошибка у тебя в программе)
Это понятно... ))) Не понятно где? И как такое может быть в принципе - ну если вообще не работало - тут ясно, а так...
-
> Не понятно где?
Известно где - в 17-й строке)
> как такое может быть в принципе
А оч просто - за тобой вообще-то замечена дурная привычка не анализировать рез-ты вызовов API-функций. Она, думаю, как раз и играет с тобой "злую шутку")
-
ошибка в 17 строке
-
Собственно нет там 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
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); 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;
14: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT1);
16: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT2;
17: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT3); else
end
end else
begin
case Pin of
1: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT0; 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);
14: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT1;
16: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] and (not BIT2);
17: Lpt.Port[LPTBase+2] := Lpt.Port[LPTBase+2] or BIT3; else
end
end;
end;
-
> Alex_C (26.11.09 09:13) [5]
ну уже что-то чем совсем ничего)
Ну так и что не работает ?
-
> Alex_C (26.11.09 08:23)
> Если перед этим запустить другую программу, которая работает > с LPT тоже при помощи этого драйвера, выйти из нее, а потом > опять запустить мою - то все работает. Как такое может быть? >
Как вариант, та программа настраивает порт на нужный режим работы (ECP,EPP,SPP....).
-
> та программа настраивает порт на нужный режим работы
Оч даже себе вариант.
При этом отсутствие аналогичной ф-ти в программе автора топика как раз и м.б. ошибкой в 17-й строке)
-
Ну приветик Alex_C, теперь тебе здесь! )))))))) только что отписал тебе по ком-портам в ветке, а ты тут уж про LPT, замутил?! )))))) Придется тебе пиво высылать виртуальной бандеролью! ) А твоя проблема, голубчик в том, что та прога в отличие от твоей УМЕЕТ РЕГИСТИРОВАТЬ В СИСТЕМЕ доайвер и активировать его в .... кажись менеджер драйверов или служда называется.... У меня 1:1 это пройдено и именно с этим драйвером! Когда ты пускаешь свою прогу она пользуется "чужими трудами" :) вернее результатами. Система уже имеет подгруженный драйвер и расшатенные вещи, а твоя лишь юзает оные!
-
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;
-
теги блин слетели.... ну ниче копи-паст а там красивее... Вообще гдето так. Надеюсь разберешься!
-
ваава
-
Какой выдающийся поток сознания !..
-
Нет ребят! Не надо драйвер в системе регистрировать :) Все и так работает - подсказали уже: кстати ОЧЕНЬ важная информация для тех, кто хочет работать с 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);
Кстати, может кто знает а почему так?
-
> Alex_C (27.11.09 08:41) [14]
С точки зрения интерфейса центроникс - 1 пин разъема параллельного порта (LPT) - это сигнал Strobe. Обмен данными с принтером завязан естественно с сигналом строб. Но например для зажигания лампочек цветомузыки значения может и не иметь. Так что просто надо знать протокол обмена на уровне интерфейса с тем железом, которым ты управляешь через порт. И указывать нужный режим работы порта в программе (см [7]) - тоже будет правильно. А то так возможно и будет у разных клиентов работать по разному.
|