Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизРабота с LPT-портом Найти похожие ветки
← →
Alex_C (2009-11-26 08:23) [0]Кто нибудь при работе с LPT-портом использовал драйвер DLPortIO? Написал на заказ программу - простенькую по управлению некоторым оборудованием через LPT (там всего лишь на некоторых ножках порта выставляется высокий или низкий уровень). У меня все работает, а у заказчика (который в другом городе) такая проблема: если запустить мою программу - ничего не работает. Если перед этим запустить другую программу, которая работает с LPT тоже при помощи этого драйвера, выйти из нее, а потом опять запустить мою - то все работает. Как такое может быть?
← →
Сергей М. © (2009-11-26 08:25) [1]
> Как такое может быть?
Да как обычно - ошибка у тебя в программе)
← →
Alex_C (2009-11-26 08:58) [2]
> Да как обычно - ошибка у тебя в программе)
Это понятно... )))
Не понятно где? И как такое может быть в принципе - ну если вообще не работало - тут ясно, а так...
← →
Сергей М. © (2009-11-26 09:06) [3]
> Не понятно где?
Известно где - в 17-й строке)
> как такое может быть в принципе
А оч просто - за тобой вообще-то замечена дурная привычка не анализировать рез-ты вызовов API-функций. Она, думаю, как раз и играет с тобой "злую шутку")
← →
miek (2009-11-26 09:06) [4]ошибка в 17 строке
← →
Alex_C (2009-11-26 09:13) [5]Собственно нет там 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:59) [6]
> Alex_C (26.11.09 09:13) [5]
ну уже что-то чем совсем ничего)
Ну так и что не работает ?
← →
Вариант (2009-11-26 10:46) [7]
> Alex_C (26.11.09 08:23)
> Если перед этим запустить другую программу, которая работает
> с LPT тоже при помощи этого драйвера, выйти из нее, а потом
> опять запустить мою - то все работает. Как такое может быть?
>
Как вариант, та программа настраивает порт на нужный режим работы (ECP,EPP,SPP....).
← →
Сергей М. © (2009-11-26 11:32) [8]
> та программа настраивает порт на нужный режим работы
Оч даже себе вариант.
При этом отсутствие аналогичной ф-ти в программе автора топика как раз и м.б. ошибкой в 17-й строке)
← →
vastani (2009-11-26 15:48) [9]Ну приветик Alex_C, теперь тебе здесь! ))))))))
только что отписал тебе по ком-портам в ветке, а ты тут уж про LPT, замутил?! ))))))
Придется тебе пиво высылать виртуальной бандеролью! )
А твоя проблема, голубчик в том, что та прога в отличие от твоей УМЕЕТ РЕГИСТИРОВАТЬ В СИСТЕМЕ доайвер и активировать его в .... кажись менеджер драйверов или служда называется....
У меня 1:1 это пройдено и именно с этим драйвером!
Когда ты пускаешь свою прогу она пользуется "чужими трудами" :) вернее результатами. Система уже имеет подгруженный драйвер и расшатенные вещи, а твоя лишь юзает оные!
← →
vastani (2009-11-26 15:54) [10]
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:57) [11]теги блин слетели.... ну ниче копи-паст а там красивее...
Вообще гдето так. Надеюсь разберешься!
← →
vens © (2009-11-26 15:59) [12]ваава
← →
Сергей М. © (2009-11-26 21:40) [13]Какой выдающийся поток сознания !..
← →
Alex_C (2009-11-27 08:41) [14]Нет ребят!
Не надо драйвер в системе регистрировать :)
Все и так работает - подсказали уже: кстати ОЧЕНЬ важная информация для тех, кто хочет работать с 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-30 06:03) [15]
> Alex_C (27.11.09 08:41) [14]
С точки зрения интерфейса центроникс - 1 пин разъема параллельного порта (LPT) - это сигнал Strobe. Обмен данными с принтером завязан естественно с сигналом строб.
Но например для зажигания лампочек цветомузыки значения может и не иметь. Так что просто надо знать протокол обмена на уровне интерфейса с тем железом, которым ты управляешь через порт. И указывать нужный режим работы порта в программе (см [7]) - тоже будет правильно. А то так возможно и будет у разных клиентов работать по разному.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.08 c