AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hardware Portansteuerung

Ein Thema von jwhm · begonnen am 3. Feb 2003 · letzter Beitrag vom 9. Mär 2003
 
jbg

Registriert seit: 12. Jun 2002
3.485 Beiträge
 
Delphi 10.1 Berlin Professional
 
#10
  Alt 4. Feb 2003, 12:30
Für den Parallelport habe ich eine Unit.
Delphi-Quellcode:
unit LPTPort;
{.$define WINIO} // WinIo nutzen um auf den ParPort zuzugreifen
{.$define USERPORT}  // UserPort.sys nutzen um auf den ParPort zuzugreifen

{$ifdef WINIO}
 {$ifdef USERPORT}
  Es kann nur ein Kernel Mode Treiber genutzt werden
 {$endif}
{$endif}
{$ifdef USERPORT}
 {$ifdef WINIO}
  Es kann nur ein Kernel Mode Treiber genutzt werden
 {$endif}
{$endif}

{ Beschreibung:  Parallel Port Objekt mit direktem Hardwarezugriff }
interface
uses Windows, SysUtils, Classes{$ifdef WINIO}, WinIo{$endif};
const
  PortNames: array [0..2] of string = ('None', 'LPT1', 'LPT2');
  PortAddress: array[0..2] of Word = (0, $378, $278);
  STB = $01;
  AUTOFD = $02;
  INITL = $04;
  SLCI = $08;
  IRQEN = $10;
  ERR = $08;
  SLCO = $10;
  PE = $20;
  ACK = $40;
  BSY = $80;

type
  TPortNumber = (portNone, portLPT1, portLPT2);

  TParPort = class(TObject)
  private
    FPort: TPortNumber;
    FPortAddress: Word;
    PortHandle: THandle;
    FData, FControl, FStatus: Byte;
    FStrobe, FAutoFd, FInit, FSlctIn, FError, FSlct, FPaperEnd: Boolean;
    FAcknlg, FBusy: Boolean;
    procedure SetPort(Value: TPortNumber);
    function GetData: Byte;
    procedure SetData(Value: Byte);
    function GetControl: Byte;
    procedure SetControl(Value: Byte);
    function GetStatus: Byte;
    function GetStrobe: Boolean;
    procedure SetStrobe(Value: Boolean);
    function GetAutoFd: Boolean;
    procedure SetAutoFd(Value: Boolean);
    function GetInit: Boolean;
    procedure SetInit(Value: Boolean);
    function GetSlctIn: Boolean;
    procedure SetSlctIn(Value: Boolean);
    function GetError: Boolean;
    function GetSlct: Boolean;
    function GetPaperEnd: Boolean;
    function GetAcknlg: Boolean;
    function GetBusy: Boolean;
  public
    constructor Create;
    destructor Destroy; override;

    function OpenPort(PortNo: Byte): Boolean;
    function ClosePort: Boolean;

    property Control: Byte read GetControl write SetControl;
  public
    property Port: TPortNumber read FPort write SetPort;
    property BaseAddress: word read FPortAddress;
    property Status: Byte read GetStatus;
    property Data: Byte read GetData write SetData;
    property Strobe: Boolean read GetStrobe write SetStrobe;
    property AutoFeed: Boolean read GetAutofd write SetAutofd;
    property Initialize: Boolean read GetInit write SetInit;
    property SlctIn: Boolean read GetSlctIn write SetSlctIn;
    property Error: Boolean read GetError;
    property Slct: Boolean read GetSlct;
    property PaperEnd: Boolean read GetPaperEnd;
    property Acknlg: Boolean read GetAcknlg;
    property Busy: Boolean read GetBusy;
  end;


implementation

{ ************************************************************************* }

{ Get a Byte from the port }
function InPort(PortAddr: Word): Byte; stdcall;
begin
{$ifdef WINIO}
  Result := WinIo_GetPort(PortAddr)
{$else}
  try
    asm
      mov dx, PortAddr
      in al, dx
      mov Result, al
    end;
  except
    Result := 0;
  end;
{$endif}
end;

{ ************************************************************************* }
{ Write a Byte to the port }
procedure OutPort(PortAddr: Word; DataByte: Byte); stdcall;
begin
{$ifdef WINIO}
  WinIo_SetPort(PortAddr, DataByte)
{$else}
  try
    asm
      mov al, DataByte
      mov dx, PortAddr
      out dx, al
    end;
  except
  end;
{$endif}
end;

{ ************************************************************************* }
{ Do (Action) to b(Bit) of (PortAddr) }
procedure SetBitState(PortAddr: Word; Action: Boolean; Bit: Byte);
begin
  if Action = True then OutPort(PortAddr, InPort(PortAddr) or Bit)
   else   OutPort(PortAddr, InPort(PortAddr) and not Bit);
end;

{ ************************************************************************* }
{ Return status of b(Bit) of (PortAddr) }
function GetBitState(PortAddr: Word; Bit: Byte): Boolean;
begin
  Result := (InPort(PortAddr) and Bit) <> 0;
end;

{----------  TParPort ----------}

{ ************************************************************************* }
constructor TParPort.Create;
begin
  inherited Create;
  FPort := portNone;
  FPortAddress := 0;
  PortHandle := 0;
end;

{ ************************************************************************* }
destructor TParPort.Destroy;
begin
  ClosePort;
  inherited Destroy;
end;

{ ************************************************************************* }
function TParPort.OpenPort(PortNo: Byte): Boolean;
var s: string;
begin
  ClosePort;
  s := '';
  Result := False;
  if (PortNo < 1) or (PortNo > 2) then exit;
  s := '\\.\LPT' + IntToStr(PortNo);
  PortHandle := CreateFile(PChar(s),
                    GENERIC_READ or GENERIC_WRITE,
                    0, nil,
                    OPEN_EXISTING,
                    0, 0);
  if PortHandle = INVALID_HANDLE_VALUE then PortHandle := 0;
  if PortHandle <> 0 then begin
    case PortNo of
      1: FPort := portLPT1;
      2: FPort := portLPT2;
    end;
    FPortAddress := PortAddress[PortNo];
   { Output data = 0 }
    OutPort(FPortAddress, 0);
   { Control reg = 0c }
    OutPort(FPortAddress + 2, (InPort(FPortAddress + 2) and $F0) or $0C);
    Result := True;
  end;
end;

{ ************************************************************************* }
procedure TParPort.SetPort(Value: TPortNumber);
begin
  if Value <> FPort then begin
    { Set default output data }
     OpenPort(Ord(Value));
  end;
end;

{ ************************************************************************* }
function TParPort.GetData: Byte;
begin
  { Get a Byte from the data port }
  if PortHandle <> 0 then FData := InPort(FPortAddress)
   else FData := 0;
  Result := FData;
end;

{ ************************************************************************* }
procedure TParPort.SetData(Value: Byte);
begin
  { Send a Byte to the data port }
  if PortHandle <> 0 then OutPort(FPortAddress, Value);
end;

{ ************************************************************************* }
function TParPort.GetControl: Byte;
begin
 { Get a Byte from the control port }
  if PortHandle <> 0 then FControl := InPort(FPortAddress + 2)
   else FControl := 0;
  Result := FControl;
end;

{ ************************************************************************* }
procedure TParPort.SetControl(Value: Byte);
begin
{ Send a Byte to the control port }
  if PortHandle <> 0 then
     OutPort(FPortAddress + 2, (InPort(FPortAddress + 2) and $F0) or (Value and $0F));
end;

{ ************************************************************************* }
function TParPort.GetStatus: Byte;
begin
{ Read port status, inverting B7 (busy) }
  if PortHandle <> 0 then FStatus := InPort(FPortAddress + 1)
   else FStatus := 0;
  Result := FStatus;
end;

{ ************************************************************************* }
function TParPort.GetStrobe: Boolean;
begin
 { Read the STROBE output level }
  if PortHandle <> 0 then
     FStrobe := not GetBitState(FPortAddress + 2, STB)
   else
     FStrobe := False;
  Result := FStrobe;
end;

{ ************************************************************************* }
procedure TParPort.SetStrobe(Value: Boolean);
begin
 { Condition the STROBE output }
  if PortHandle <> 0 then
     SetBitState(FPortAddress + 2, not Value, STB);
end;

{ ************************************************************************* }
function TParPort.GetAutoFd: Boolean;
begin
 { Read the AUTOFD output level }
  if PortHandle <> 0 then FAutoFd := not GetBitState(FPortAddress + 2, AUTOFD)
   else FAutoFd := False;
  Result := FAutoFd;
end;

{ ************************************************************************* }
procedure TParPort.SetAutoFd(Value: Boolean);
begin
 { Condition the STROBE output }
  if PortHandle <> 0 then
     SetBitState(FPortAddress + 2, not Value, AUTOFD);
end;

{ ************************************************************************* }
function TParPort.GetInit: Boolean;
begin
 { Read the INITIALIZE output level }
  if PortHandle <> 0 then FInit := GetBitState(FPortAddress + 2, INITL)
   else FInit := False;
  Result := FInit;
end;

{ ************************************************************************* }
procedure TParPort.SetInit(Value: Boolean);
begin
 { Condition the INITIALIZE output }
  if PortHandle <> 0 then
     SetBitState(FPortAddress + 2, Value, INITL);
end;

{ ************************************************************************* }
function TParPort.GetSlctIn: Boolean;
begin
 { Read the SLCTIN output level }
  if PortHandle <> 0 then FSlctIn := not GetBitState(FPortAddress + 2, SLCI)
   else FSlctIn := False;
  Result := FSlctIn;
end;

{ ************************************************************************* }
procedure TParPort.SetSlctIn(Value: Boolean);
begin
 { Condition the SLCTIN output }
  if PortHandle <> 0 then
     SetBitState(FPortAddress + 2, not Value, SLCI);
end;

{ ************************************************************************* }
function TParPort.GetError: Boolean;
begin
 { Read the ERROR input level }
  if PortHandle <> 0 then FError := GetBitState(FPortAddress + 1, ERR)
   else FError := False;
  Result := FError;
end;
{ ************************************************************************* }
function TParPort.GetSlct: Boolean;
begin
 { Read the SLCT input level }
  if PortHandle <> 0 then FSlct := GetBitState(FPortAddress + 1, SLCO)
   else FSlct := False;
  Result := FSlct;
end;
{ ************************************************************************* }
function TParPort.GetPaperEnd: Boolean;
begin
 { Read the PE input level }
  if PortHandle <> 0 then FPaperEnd := GetBitState(FPortAddress + 1, PE)
   else FPaperEnd := False;
  Result := FPaperEnd;
end;
{ ************************************************************************* }
function TParPort.GetAcknlg: Boolean;
begin
 { Read the ACK input level }
  if PortHandle <> 0 then FAcknlg := GetBitState(FPortAddress + 1, ACK)
   else FAcknlg := False;
  Result := FAcknlg;
end;
{ ************************************************************************* }
function TParPort.GetBusy: Boolean;
begin
 { Read the inverted BUSY input level }
  if PortHandle <> 0 then FBusy := not GetBitState(FPortAddress + 1, BSY)
   else FBusy := False;
  Result := FBusy;
end;

{ ************************************************************************* }
function TParPort.ClosePort: Boolean;
begin
 { Close currently open LPT }
  if PortHandle <> 0 then begin
   { Output data = 0 }
    OutPort(FPortAddress, 0);
   { Control reg b0..3 = $0C }
    OutPort(FPortAddress + 2, (InPort(FPortAddress + 2) and $F0) or $0C);
    Result := CloseHandle(PortHandle);
  end else Result := False;
  PortHandle := 0;
  FPort := portNone;
  FPortAddress := 0;
end;

{$ifdef USERPORT}
procedure StartUserPortDriver;
var hUserPort : THandle;
begin
  hUserPort := CreateFile('\\.\UserPort',
                          GENERIC_READ,
                          0,
                          nil,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0
                          );
  CloseHandle(hUserPort); // Activate the driver
  Sleep(100); // We must make a process switch
end;

function IsWinNT: Boolean;
var OSVersionInfo: TOSVersionInfo;
begin
  OSVersionInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
  GetVersionEx(OSVersionInfo);
  Result := OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT;
end;

initialization
  if IsWinNT then StartUserPortDriver;
{$endif}

{$ifdef WINIO}
initialization
  WinIo_InstallAndStart;

finalization
  WinIo_ShutDown;
{$endif}

end.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz