延时70微妙(100分)

  • 主题发起人 主题发起人 JJams
  • 开始时间 开始时间
J

JJams

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要移植一块卡的控制程序到windows下,(win98就行,它原来在dos下)
在读卡的数据时有个特殊要求,就是要按如下步骤执行:写portx,写porty,
延时70微妙,读数据。原来在dos下,我采用循环的办法来延时,可是在windows
下有多线程调度问题,循环不再精确了。请问那位大虾可以帮我延时着70微妙
谢谢先!
 
办不到,1个ms就已经不容易了
 
1、延时函数


procedure TForm1.Delay(msecs:integer);
var
FirstTickCount:longint;
begin
FirstTickCount:=GetTickCount;
repeat
Application.ProcessMessages; {allowing access to other
controls, etc.}
until ((GetTickCount-FirstTickCount) >= Longint(msecs));
end;



2、延时函数

Sleep(1000);
单位毫秒

第一个好用。
 
好象有多媒体定时器很精确,查一查。
 
我看用硬件来实现是没问题,
有一种激光器叫飞秒激光,它的发射晨间只有几个飞秒,用电路控制。
几个飞秒都可作到,哪几个微秒。。。。
 
软件实现可以试试直接控制8259(定时芯片,PC/XT中是这样的),但要先获取
时钟频率。好象很困难。
最好用硬件。
 
精确到 0.015ms 的Timer

unit Z_timer;

interface
uses classes,windows,messages,forms;

TYPE

TZTimer = class(Tcomponent)
private
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
fcount,FInterval,ftimeout,ReqToStop:integer;
FWindowHandle: HWND;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: extended);
function getinterval:extended;
procedure SetOnTimer(Value: TNotifyEvent);
procedure Timerloop;
procedure WndProc(var Msg: TMessage);
protected
procedure Timer;virtual;
public
property count :integer read fcount;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: extended read getInterval write SetInterval;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
property TimeoutSeconds:integer read ftimeout write ftimeout;
end;

procedure Register;

implementation

const WM_PACER:integer=WM_USER+202;

procedure Register;
begin
RegisterComponents('System', [TZTimer]);
end;

constructor TZTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := false;
FInterval := 1000;
ftimeout:=10;
FWindowHandle := AllocateHWnd(WndProc);
end;

destructor TZTimer.Destroy;
begin
FEnabled := False;
updatetimer;
DeallocateHWnd(FWindowHandle);
inherited Destroy;
end;
procedure TZTimer.WndProc(var Msg: TMessage);
begin
with Msg do
if Msg = WM_PACER then
try
Timerloop;
except
Application.HandleException(Self);
end
else
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;

procedure TZTimer.UpdateTimer;
begin
reqtostop:=1; // break out current loop
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer)
and not (csdesigning in componentstate) then
postmessage(fwindowhandle,WM_PACER,0,0); // start new run after cleanup
end;


procedure TZTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;

procedure TZTimer.SetInterval(Value: extended);
begin
FInterval := round(Value*10);
if finterval<1 then finterval:=1;
UpdateTimer;
end;
function TZTimer.getInterval: extended;
begin
result:=FInterval/10;
end;
procedure TZTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
UpdateTimer;
end;

procedure TZTimer.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;
procedure TZTimer.Timerloop;
label again;
var sampletime,timeout,areqtostop:integer;
begin
sampletime:=round(finterval/0.1509);
timeout:=trunc(1e4*ftimeout/finterval);
reqtostop:=0;
fcount:=0;
{$IFDEF WIN32}
SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
{$ENDIF}
asm
in al,61h
and al,0010000b
mov ah,al
again: mov ecx,sampletime
@wait: in al,61h
and al,0010000b
cmp al,ah
je @wait // wait for levelchange
mov ah,al
dec ecx
jnz @wait
push ax
end;
inc(fcount);
timer ; // perform ontimer event
if fcount>timeout then reqtostop:=1;
areqtostop:=reqtostop;
asm
pop ax
cmp areqtostop,0
jz again
end;
{$IFDEF WIN32}
SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
{$ENDIF}
end;


end.
 
能不能用哩。。我试试看。。
 
如果是单线程程序好办,上面几位的办法都可以,要是多现成就不好办了!
 
不一定要这么准确的延时吧?
一般来说,端口数据如果不被取走的话,会一直放在缓冲区里面的,只要缓冲区不溢出,你的数据就不会丢失。
我猜想那个70微秒只是说设备在收到命令之后,要经过这么长的时间才能发出数据,如果你提前去读的话,就可能读不到东西。
如果硬要这么精确,那就得创建一个优先级极高的线程了,这对系统来说无疑是一个灾难。
 
谢谢各位大虾先!

延时70微妙是由硬件决定的,如果小于70则扫描头未能停稳,如果比70微妙大很多
则还没扫描完扫描表面就已经翻转

我决定采用OopsWare的方法试一下,不过我还有几个问题问一下
第一是61h端口的那一位的翻转频率是多少
第二是我同时需要实时显示,更改优先级会对我的显示线程有很大影响吗
 

Similar threads

后退
顶部