Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Работа с 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 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.055 c
2-1344183836
Wadimka
2012-08-05 20:23
2013.03.22
Помогите с Internet Explorer_server


15-1350908665
Grimm375
2012-10-22 16:24
2013.03.22
перевести на английский


2-1340868561
начинающий41
2012-06-28 11:29
2013.03.22
формат даты


15-1348514300
Дмитрий С
2012-09-24 23:18
2013.03.22
Маленькая игра для уничтожения клавиатуры :)


15-1352356266
Niel
2012-11-08 10:31
2013.03.22
SQL