Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > LPT-Порт


Автор: Bogus 5.7.2005, 17:02
Нужен пример работы с LPT портом. Планируется получать информацию (сигнализайию) от внешего самодельного устройства
в виде двоичного (8- разрядного) кода с дальнейшей обработкой. Можно ли это сделать и если можно, то как?
Ссылки на котовый проект (пример) особо приетствуются.

В качестве одного из примеров, могу привести ключи-заглушки на порты (в качестве лицензионного ключа) для программ карта москвы и др.

Автор: Snowy 6.7.2005, 11:51
Код

var
  h: THandle;
begin
  h:=0;
  try
    h:=CreateFile('LPT1:',GENERIC_READ OR GENERIC_WRITE,0,nil,
                  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  except h:=0;
  end;
  if h=INVALID_HANDLE_VALUE then h:=0;

  // .......

  // Теперь читаем из порта:
var
  r:  dword;
  ch: char;
begin
  if ReadFile(h,ch,1,r,nil) then 
    if r>0 then begin
      // работаем с байтиком, который у нас в ch
    end;

  // .......

  // И в конце концов закрываем порт
  if h<>0 then CloseHandle(h);

Автор: Snowy 6.7.2005, 12:04
Примерно должно получиться что-то в таком роде:
Код

unit lptport;

interface

uses Windows;

type
  TLptPort=class(TObject)
    protected
      h: THandle;
      b: ^char;
      public
      Port: byte;
      constructor Create;
      destructor Destroy; override;
      function  Connect: Boolean;
      procedure Disconnect;
      function  Connected: Boolean;
      procedure SendString(str:string);
      function  GetChar(var ch: char):boolean;
    published
  end;

implementation

constructor TLptPort.Create;
begin
  Port:=1; h:=0;
end;

destructor TLptPort.Destroy;
begin
  Disconnect;
  inherited Destroy;
end;

function TLptPort.Connected: Boolean;
begin
  Result:=h>0;
end;

procedure TLptPort.Disconnect;
begin
  if Connected then
    CloseHandle(h);
  h:=0;
end;

function TLptPort.Connect: Boolean;
var
  LptName: string;
begin
  Result:=Connected;
  if Connected then Exit;
  LptName:='LPT'+chr(48+Port);
  try
    h:=CreateFile(PChar(LptName),GENERIC_READ OR GENERIC_WRITE,0,nil,
                  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  except 
    h:=0 
  end;
  if h=INVALID_HANDLE_VALUE then h:=0;
  Result:=Connected;
end;

procedure TLptPort.SendString(str:string);
var
  buf: PChar;
  btw,bwt : DWORD;
begin
  if not Connected then exit;
  btw:=Length(str); buf:=PChar(str);
  WriteFile(h, buf, btw, bwt,nil);
end;

function TLptPort.GetChar(ch: char): boolean;
var
  r:  dword;
begin
  result:=false;
  if not Connected then exit;
  if ReadFile(h,ch,1,r,nil) then
    if r>0 then result:=true;
end;

end.


Код

program Test;

{$APPTYPE CONSOLE}

uses
  Windows,
  lptport in 'lptport.pas';

Var
  lpt: TComPort;
  ch: char;
begin
  lpt:=TComPort.Create;
  lpt.Port:=1;
  if lpt.Connect then
    WriteLn('Connected')
  else
    WriteLn('Can''t connect');
  if lpt.Connected then
    while true do begin
      if lpt.GetChar(ch) then Write(ord(ch));
      Sleep(100);
    end;
  lpt.Disconnect;
  lpt.Free;

Автор: Snowy 6.7.2005, 12:21
Также для информации почитай DRKB раздел "Порты".
В принципе работа с COM и LPT похожа.
Ну, кроме установки параметров порта.
Хотя установка порта требуется далеко не всегда.
Я например использую стандартные параметры, выставленные в системе.
Это избавляет меня от необходимости делать лишнюю работу.
Не нужно писать лишний код для настройки порта и интерфейс для пользователя.
Пользователь может использовать настройки в системе.

Не гарантирую, что вышеприведенный код 100% рабочий, т.к. писал его для COM порта. Я его лишь немного модифицировал под LPT. Но по идее проблем возникнуть не должно. Должен заработать без вопросов.

Автор: Bogus 6.7.2005, 14:25
По сути мне нужно анализировать различные варианты коммутации контактов LPT порта. Сечас пойду разбираться в том, что написали. Всем спаисибо. Если у кого есть еще советы или (и) готовые примеры, буду благодарен. smile
Добавлено @ 14:29
Ни черта не понял. Аткрыть, закрыть порт я смогу, но как проанализировать коммутацию контактов?!!!

Автор: Bogus 6.7.2005, 15:04
http://khrameev.narod.ru/Marriage/Chto_nado.jpg

Автор: Snowy 6.7.2005, 17:11
Цитата(Bogus @ 6.7.2005, 14:25)
Ни черта не понял. Аткрыть, закрыть порт я смогу, но как проанализировать коммутацию контактов?!!!

Для этого ты должен передать сигнал в порт.
Программа получает сигнал в виде одного байта.
По приведенному выше коду, ты получаешь char от функции GetChar.
Переводишь его в число при помощи ord(ch).
А число уже представляй в бинарном виде.
Как перевести число в бинарный вид, на форуме уже не раз обсуждалось в "Общих вопросах", так же есть в FAQ и DRKB.
Смотришь бинарное представление. Где еденички - там есть сигнал, где нолики - нет сигнала.

Автор: asp708 10.12.2006, 22:46
можно ли где нибудь откльчить напряжение на LPT при загрузке 
т.е. при включении PC  он не скакало и оставалось на 0 пока сами его программно не изменим

Автор: Snowy 11.12.2006, 10:47
Нет.
При загрузке винда производит тестирование устройств.
И этого ей никак не запретишь.

Автор: Mr.Floppy 13.3.2007, 02:11
Snowy, у меня не работает Ваш код  smile
Открывать/закрывать порт получается (открывает корректно, хендл>0), но читать и записывать не получается:
При чтении: GetChar возвращает false, ord(ch)=0
При записи программа просто зависает (может ждет ответа устройства?)

В примере несколько опечаток:

unit lptport;
20: function  GetChar(var ch: char):boolean;
но
76: function TLptPort.GetChar(ch: char): boolean;

program Test;
10: lpt: TComPort;
13: lpt:=TComPort.Create;
а надо TLptPort


А через драйвер lptwdmio все работает.
Turbo Delphi, WinXP Pro, запускаю от администратора

Автор: Albinos_x 13.3.2007, 10:46
вот рабочий примерс драйвером

Автор: Mr.Floppy 13.3.2007, 16:41
Albinos_x, через lptwdmio у меня работает, не получается через CreateFile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)