PDA

Просмотр полной версии : Практическая задача


Skazachnik
04.09.2008, 22:45
Господа! Подскажите, пожалуйста, как решить следующую задачу: есть LPT порт, и есть 8 светодиодов, требуется написать программу для управления (через LPT) этими диодами; желательно на Delphi (просто, хотелось бы лучше (= детально) в коде разобраться). Я был бы рад услышать Ваши советы и предложения , а если повезёт, то и увидеть исходники. Я не прошу написать программу за меня (хотя это было бы очень и очень здорово :)), а просто хочу разобраться, как это работает (пока не очень получается, просто не въезжаю... поэтому и прошу помощи). Посоветуйте (= помогите) и заранее Вам спасибо!

Borland
04.09.2008, 22:51
http://www.computer-interfacing.mytutorialcafe.com/interfacing%20port%20printer%200207.htm
Правда, фактически прога на ассемблере...
В чисто дельфи - не уверен, что есть функции для прямой работы с портами...

<добавлено чуть позже>
Хотя вот что-то... http://www.scienceprog.com/control-lpt-port-under-windows-xp-using-delphi/
http://www.arunet.co.uk/tkboyd/ele1pp.htm#uio32

crawler
07.09.2008, 10:38
Работает примерно так: обращаешься к LPT порту, конфигуруруешь его под определенный режим, затем передаешь через LPT порт определенный сигнал - соответсвенно некоторые ножки LPT порта меняют свой уровень с 0 на 1. Как результат те диоды, которые подключены к "1" начинают светить.
Сложность тут только одна - понять какой режим LPT порта тебе нужен, и какую последовательность на него надо послать чтобы включить нужный режим.

sflash
10.10.2008, 14:39
Вот то что ты искал.

unit LptCtrl;

interface

uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;

type
TLpt = (None, Lpt1, Lpt2, Lpt3);
TLptAvail = array [1..3] of boolean; { is port available? }
TPortAddrArr = array [1..3] of word;

TlptCtrl = class(TComponent)
private
{ Private declarations }
FLpt: TLpt;
FPortAddrArr: TPortAddrArr; { LPT port addresses }
FPortAddr: word; { selected LPT port address }
FLptAvail: TLptAvail;
FData: byte; { LPT data out }
FDummy: byte; { will only be used to make 'Status' published }

procedure SetLptPort(Value: Tlpt);
{ SetPortAddress will usually be automatically handled
through SetLptPort. }
procedure SetPortAddress(Value: word);
procedure SetData(Value: byte);
function GetStatus: byte;
function GetCtrl: byte;
procedure SetCtrl(Value: byte);
procedure FindLptAddr;


protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property LptAvail: TLptAvail read FLptAvail; { what ports are available? }

published
{ Published declarations }
property LptPort: TLpt read FLpt write SetLptPort default None;
property PortAdress: word read FPortAddr write SetPortAddress;
property Data: byte read Fdata write SetData default 0;
property Status: byte read GetStatus write FDummy;
property Ctrl: byte read GetCtrl write SetCtrl;
end;

procedure Register;

implementation

{ FindLptAddr - Will find the addresses of LPT port (1-3).
Non valid ports will result in address 0.
Note FLptPortAddr[] and FLptAvail will be affected. }
procedure TlptCtrl.FindLptAddr;
begin
{ Yes, I know, this could have been coded as a loop... }
FPortAddrArr[1] := mem[$0040:$08] + mem[$0040:$09]*256;
if FPortAddrArr[1] > 0 then FLptAvail[1] := true;

FPortAddrArr[2] := mem[$0040:$0A] + mem[$0040:$0B]*256;
if FPortAddrArr[2] > 0 then FLptAvail[2] := true;

FPortAddrArr[3] := mem[$0040:$0C] + mem[$0040:$0D]*256;
if FPortAddrArr[3] > 0 then FLptAvail[3] := true;
end;

procedure TLptCtrl.SetLptPort(Value: Tlpt); { To set up the choosen port }
begin
case Value of
Lpt1: if FLptAvail[1] then
begin
FPortAddr := FPortAddrArr[1];
FLpt := Lpt1;
end;
Lpt2: if FLptAvail[2] then
begin
FPortAddr := FPortAddrArr[2];
FLpt := Lpt2;
end;
Lpt3: if FLptAvail[3] then
begin
FPortAddr := FPortAddrArr[3];
FLpt := Lpt3;
end;
else
begin
FPortAddr := 0;
FLpt := None;
end;
end;
end;

procedure TlptCtrl.SetPortAddress(Value: word); { for those who hate automation : ) }
begin
FPortAddr := Value;
end;

procedure TlptCtrl.SetData(Value: byte); { put data on LPT data lines }
begin
if FLpt <> None then
begin
Port[FPortAddr] := Value;
FData := Value;
end;
end;

function TlptCtrl.GetStatus: byte; { read data from LPT status lines }
begin
if FLpt <> None then
begin
Result := Port[FPortAddr + 1];
end
else
Result := 0;
end;

function TlptCtrl.GetCtrl: byte;{ to read what was put on the Ctrl lines }
begin
if FLpt <> None then
begin
Result := Port[FPortAddr + 2];
end
else
Result := 0;
end;

procedure TlptCtrl.SetCtrl(Value: byte); { put data on Ctrl lines }
begin
if FLpt <> None then
begin
Port[FPortAddr + 2] := Value;
end;
end;

procedure Register;
begin
RegisterComponents('I/O', [TlptCtrl]);
end;

{ constructor }
constructor TLptCtrl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FindLptAddr; (* find available LPT ports *)
end;

{ destructor - just as a placeholder if cleanup will be necessary }
destructor TLptCtrl.Destroy;
begin
inherited Destroy;
end;

end.