Jak "zaświecić" konkretne bity na LPT

0

Witam. Mam problem, potrzebuję programu, który bedzie wykonywał mi taka funkcję:

Mam okienko edit, label i dwa przyciski. Jeżeli w okienku edit wpiszę liczbę dziesiętną (0-255) i kliknę jeden z przycisków, to na wyjściu LPT zaświecą mi się odpowiednie bity (ta sama liczba binarnie), a jeżeli nacisnę drugi przycisk, to z LPT zostanie zczytana wartość binarna, a w okienku label pojawi mi się wartość dziesiętna.

0

I w czym problem? Wysyłasz tą liczbę na bazowy adres portu LPT, albo odczytujesz liczbę z owego adresu...

0

I w tym właśnie problem. Ani nie chce mi wysłąć, ani odczytać. Coś namieszałem i nie mam pojęcia co. Jeżeli to jest takie proste, to może mógłbyś mi nasmarować taką procedurkę, byłbym bardzo wdzięczny.

0

Używasz Windowsa XP, zdradź więc, jak wygląda to Twoje "wysyłanie"...

0

testowales to na innym systemie?

0

Odpaliłem to na 98 i coś mi zaczyna chodzić. Mam taka procedurę:

unit WinLpt;

interface

procedure LptWrite(nr:byte; d:boolean);
function  LptRead(nr:byte):boolean;
function  WhatLptWrite(nr:byte):boolean;

var
  AddrLPT: Word;

const
  yes=true;
  no=false;

implementation

var
   v : array[1..12] of boolean;
   i : integer;

function PortReadByte(Addr:Word) : Byte; assembler; register;
asm
  MOV	DX,AX
  IN	AL,DX
end;
procedure PortWriteByte(Addr:Word; Value:Byte); assembler; register;
asm
  XCHG	AX,DX
  OUT 	DX,AL
end;

procedure LptWrite(nr:byte; d:boolean);
var
  a,b : byte;
begin
  v[nr]:=d;

  if v[1] then a:=1 else a:=0;
  if v[2] then a:=a+2;
  if v[3] then a:=a+4;
  if v[4] then a:=a+8;
  if v[5] then a:=a+16;
  if v[6] then a:=a+32;
  if v[7] then a:=a+64;
  if v[8] then a:=a+128;

  PortWriteByte(AddrLPT, a);
  {----------------}

  if v[9]  then a:=1 else a:=0;
  if v[10] then a:=a+4;
  if v[11] then a:=a+8;
  PortWriteByte(AddrLPT+2, a);
end;

function WhatLptWrite(nr:byte):boolean;
begin
  WhatLptWrite:=v[nr];
end;

function LptRead(nr:byte):boolean;
var
  a: byte;
begin

  a:=PortReadByte(AddrLPT+1);


  a:=a div 2;
  a:=a div 2;
  a:=a div 2;

  if nr=5 then begin LptRead:=not ((a mod 2)=1); exit end;
  a:=a div 2;
  if nr=4 then begin LptRead:=not ((a mod 2)=1); exit end;
  a:=a div 2;
  if nr=3 then begin LptRead:=not ((a mod 2)=1); exit end;
  a:=a div 2;
  if nr=1 then begin LptRead:=not ((a mod 2)=1); exit end;
  a:=a div 2;
  if nr=2 then begin LptRead:=(a mod 2)=1; exit end;
  LptRead:=false;
end;

initialization
  AddrLPT:=$378;

  for i:=1 to 11 do
    v[i]:=false;

  LptWrite(12,false);
end.

----------------------------------------------------------------------

i w drugim formularzu odpalam program: 

---------------------------------------------------------


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, WinLpt, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Text1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Text1Change(Sender: TObject);
    procedure Label2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  a,b:integer;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
WinLpt.LptRead(b)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
WinLpt.LptWrite(a,yes);
end;

procedure TForm1.Text1Change(Sender: TObject);
begin
a:=StrToInt(Text1.Text);

end;

procedure TForm1.Label2Click(Sender: TObject);
begin
Label2.Caption:=IntToStr(b)
end;

end.

Wysyła mi to dane, ale nie chce czytać

0

Ręce opadają :(
Na systemach z rodziny NT (4.x, 2000, XP, 2003) programy w trybie ring3 nie mogą uzywać instrukcji operujących bezpośrednio na sprzęcie, takich jak, m.in.

in 

i out

0

Czy mógłby ktos skomentować tą pierwszą część programu (Unit WinLpt).
Po co jest ten tekst z asemblera ?
Można go zastąpić procedurami z Delphi ?
Co robi procedura -- procedure LptWrite(nr:byte; d:boolean); ---?
Do czego służy -- if nr=5 then begin LptRead:=not ((a mod 2)=1); exit end;
a:=a div 2; --?

0
Liu_Kang napisał(a)

Czy mógłby ktos skomentować tą pierwszą część programu (Unit WinLpt).

Nie chce mi się, bo rzecz jest zawiła i na pierwszy rzut oka napisana zbyt skomplikowanie i nieprzejrzyście. Tylko niech sie autor nie rzuca, że nie czytałem dokładnie kodu i marudzę - napisałem w życiu sporo kodu obsługującego LPT w różnych językach i systemach i po po prostu widzę...

Liu_Kang napisał(a)

Po co jest ten tekst z asemblera ?
Można go zastąpić procedurami z Delphi ?

Delphi nie ma procedur odwołujących się bezpośrednio do portów hardware'owych. Dlatego konieczne jest uzycie asemblerowych instrukcji in i out. Które zresztą (jak to już zauważył Qyon) nie będą działać na współczesnych sytemach. Polecam użycie biblioteki inpout32.dll http://www.logix4u.net/inpout32.htm przy pomocy której właśnie niedawno napisałem spory program między innymi zaświecający i odczytujący bity z LPT.
Wspomniana biblioteka udostępnia funkcje Inp32 i Out32 dające dostęp do portów hardwareowych pod Windows typu 98 i typu NT.

0

system xp nt i chyba win2000 potrzebuja userport. progra,mik "otwiera" bezposredni dostep. stad wlasnie na win98 wszystko Ci smiga. zassaj userport. userport.sys skopiuj do windows/system32/driver a plik exe gdziekolwiek. odpal uruchom i zapomnij, ze to kiedys nie smigalo ;)

0

A po co jakieś dodatkowe pliki czy drivery? Winapi: CreateFile z nazwą 'LPT1' i obsługa jak przy plikach - wystarczy zerknąć do dokumentacji. Żadne operacje bezpośrednie czy gotowce nie są potrzebne.

0

Tak dodam jeszcze, żeby upewnić się czy port LPT który posiadasz jest dwukierunkowy. Starsze miały tylko opcje wysyłania danych jeśli się nie mylę...

1 użytkowników online, w tym zalogowanych: 0, gości: 1