如何在delphi中编程控制并口,及控制并口各针电平高低。(200分)

W

wzdapex

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在delphi中编程控制并口,及控制并口各针电平高低。有无控件或用汇编写出程序代码(delphi中)
 
在DELPHI中嵌入汇编
如果要控制各针电平高低,问题就大了!
没发现这样的控件,你想用他做什么方面的应用?
 
有一段控制并口的代码,不过是 Delphi 1.0的
不知道有没有用?
国外有一本全面介绍如何介绍并口编程的书,
但我现在一时还没找到。


unit LptCtrl;
{--------------------------------------------------------------------
IDENTIFICATION
Unit Name: LptCtrl
Reg No: -
Revision: See revision history.
File Name: LptCtrl.pas
Target: PC w Intel 386+, LPT port, Windows 3.1 or compatible.
Compiler: Delphi 1.x. Note! This unit will probably
not compile with Delphi 2.x.
Issued By: (c) Tord Andersson, 1996. (anderssonto@decus.se).
Legal disclaimer. The author will take no responsibilty
for damages that could be the result of using this
component.
Reviewed By: -
Tested By: -

DESCRIPTION
This unit holds TlptCtrl, a class/component which is intended
for reading/writing directly to an LPT port.

REVISION HISTORY
Version Date Change/addition Resp
0.2 960606 Released to the public domain. Tord Andersson

====================================================================}


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.
 
谢谢jiangtao的回答,不知该程序是否能控制并口各针,忘了告诉您们,我主要是为了数控机床的各轴联动(实时)
 
对打印口控制没问题。以下程序可以在DELPHI4。0下作控制。
如果控制其他口,使用其他方法,DELPHI4。0不允许。
FUNCTION ReadPort:byte;
Var a : Byte;
BEGIN
ASM
MOV DX, pn;
IN AL, DX;
MOV a, AL;
END;
GetPort:=a;
END;

PROCEDURE writePort;
BEGIN
ASM
MOV DX, pn;
MOV AL, a;
OUT DX, AL;
END;
END;
 
const portn//为数控机床的各轴联动的端口
function ReadPort:byte;
Var a : Byte;
begin
ASM
MOV DX, portn;
IN AL, DX;
MOV a, AL;
END;
ReadPort:=a;
end;
procedure WritePort(ConByte:byte);
begin
ASM
MOV DX, portn;
<font color=red>MOV AL, ConByte;</font>
OUT DX, AL;
END;
end;
ConByte对应为端口的控制字
我不懂什么叫"各轴联动"但我想
控制端口个动作一定有对应的控
制字就像我们以前写DOS程序控
制磁带机等外设一样,写入一定的
ConByte控制字来完成一定的动作.
 
"各轴联动"对硬件控制的要求不是很高,
要求的算法比较复杂。实际是先对运动轨
迹进行计算,然后分配到各坐标轴。控制
只需输出相应的坐标值即可(各轴应该有
相应的伺服控制系统)。
 
对我说吗?:(
 
wzdapex:
你试过了吗?
行不行告诉大家一声
 
wzdapex:
你试过了吗?
行不行告诉大家一声
 
就是在DOS下你有办法用汇编控制每个角电平吗?还是用单片机作中间接调控
那成本会上一些但接口就很简单了。也不要考虑隔离。
 
接口电路肯定会提供的
 
我在d1下用TDCB
用SetDCB 设置并口
然后用嵌入汇编
如上唐兄所写的openport closeport函数
但只对并口的控制端输出电平可以保持,而输出脚不能保持,除非你用驱动+继电器
 
异步通讯专业版,有源码,不知能否解决你的问题,请下载。
async25 5.2M
http://www.seawind.com.cn/files/delphi/async25.zip
 
那位把这个5吨的东东拉回来了,能
寄给我吗?(我用吸血鬼拉了几个星期都没拖回来)
不胜感激!<a href="mailto:xftang@shtdu.edu.cn">xftang@shtdu.edu.cn</a>
顺便说一句,这个问题该结束了.
 
我以前用DELPHI做过数控电机的程序,用并口控制电机驱动电路.
数据采集卡采集电机转速,进行适时处理.

用delphi内嵌汇编
asm
mov dx,portaddress;
in al,dx;
mov inbyte,al;
end;
用来接收数据采集卡数据.

asm
mov al,outbyte;
mov dx,portaddress;
out al,dx;
end;
用来控制并口 2-9 针的电平,高电平(12V)为 '1',低电平(0V)为 '0'; 25针为地.
(先将outbyte的各位设好.)
如有需要通知我(siheyuan@263.net)给你源代码.
 
好象不用这么麻烦吧,我记得有一个小控件,可以
直接读写内存和串,并口,好象叫V什么的,是在
nease的一个homepage上,我的光盘上有,可偏偏
今天光驱坏了,只好等过两天了,你如果要我可以
写信到zph_linux@126.com
 
我认为只需要往并口输出数据即可!
 
wangzhiren说的是对的。但要想读写其他控制脚就不行了。
偶这里有一个控件可以直接读写内存及I/O口,想要的话请用mail通知我。
 
多人接受答案了。
 
顶部