Board index » delphi » FAST TIMER FOR REAL TIME APPLICATIONS

FAST TIMER FOR REAL TIME APPLICATIONS

I am french and i work with DELPHI 2
Please where can i find a timer component with a precision of 1/10000s

or how can i do this.
for all your ideas please contact me to my email : m...@worldnet.fr

 

Re:FAST TIMER FOR REAL TIME APPLICATIONS


Quote
m...@worldnet.fr wrote:
> I am french and i work with DELPHI 2
> Please where can i find a timer component with a precision of 1/10000s

> or how can i do this.
> for all your ideas please contact me to my email : m...@worldnet.fr

For the greatest possible resolution of timers under Windows, use
timeSetEvent, or some of the other time functions available in MMSYSTEM.DLL.
You can find help for them in either MMSYSTEM.HLP or MM.HLP depending on the
version of Delphi/Pascal you are using.  MM.HLP in your case.

--Brad

Regards,
Brad
bstow...@pobox.com
Free Delphi Stuff:  http://www.pobox.com/~bstowers/delphi/

Re:FAST TIMER FOR REAL TIME APPLICATIONS


Quote
m...@worldnet.fr wrote:

> I am french and i work with DELPHI 2
> Please where can i find a timer component with a precision of 1/10000s

> or how can i do this.
> for all your ideas please contact me to my email : m...@worldnet.fr

I think you are asking for a tall order. I have managed to use the DOS
timer down to 1ms for realtime apps, but that is pushing DOS to the
limit.
I doubt if you'll get 100us that you are looking for in a WINDOWS timer.
That has been what is keeping me in DOS programs for REALTIME apps so far
is the fact that WINDOWS realtime stuff is too slow.

The only way you'll get around it is to use DMA, which the soundblasters
use. If you are doing A/D stuff, why not use a soundblaster.

Hope this helps
PAUL

Re:FAST TIMER FOR REAL TIME APPLICATIONS


Try
  start_ticker;
do something nice
  stop_ticker;
  edit1.text := floatToStr(tick_seconds);

----------------hope this helps

unit D_timer;

{
John Biddiscombe
J.Biddisco...@rl.ac.uk

Revised for Delphi 2.

Should get 840nS resolution, but the graininess is quite coarse.
(ie ticks are every 840nS, but the accuracy is much less )

Delphi 1 users - see BYTE magazine April 95
'The software stopwatch' by Rick Grehan
Thanks very much for that !
Delphi 2 users, Win32API supports high resolution timers.

This version March 96

Quote
}

interface

uses WinTypes,WinProcs;

type { useful for monitoring average frame speed }
  frame_speed_obj = Class(TObject)
    average_frame_speed : double;
    averages            : double;
    procedure reset(avgs:double);
    function  update(newtime:double) : double;
  end;

procedure start_ticker;
procedure stop_ticker;
function  tick_seconds    : double;
function  tick_seconds2   : double;
function  elapsed_ticks   : longint;
procedure get_ticks;

{$IFDEF VER80 } { Borland Delphi version 1 }
function  get_VTD_address : pointer;
{$ENDIF }

implementation

var
  {$IFDEF VER90}
  ticks_per_second : comp;
  {$ENDIF }
  last_ticks       : comp;
  this_ticks       : comp;
  {$IFDEF VER80 }
  VTD_addr     : pointer;
const
  ticks_per_second = 1193180;  { 1/1193180 = 8.381e-7 }
  {$ENDIF }

{
---------------------------------------------------------------------------

Quote
}

{           Frame speed object, useful for
game                               }
{
---------------------------------------------------------------------------
Quote
}

procedure frame_speed_obj.reset(avgs:double);
begin
  average_frame_speed := 0;
  averages            := avgs;
end;

function frame_speed_obj.update(newtime:double) : double;
begin
  average_frame_speed := average_frame_speed -
(average_frame_speed/averages);
  average_frame_speed := average_frame_speed + (newtime/averages);
end;
{
---------------------------------------------------------------------------

Quote
}

{           Timer/Ticker
stuff                                                }
{
---------------------------------------------------------------------------
Quote
}

procedure start_ticker;
begin
  get_ticks;
  last_ticks:=this_ticks;
end;

procedure stop_ticker;
begin
  get_ticks;
end;

function elapsed_ticks : longint;
begin
  elapsed_ticks := round(this_ticks-last_ticks);
end;

function tick_seconds : double;
begin
  if this_ticks>last_ticks then tick_seconds :=
(this_ticks-last_ticks)/Ticks_per_second
  else begin  { timer overflow }
    tick_seconds :=
(9.223372036854775807E18-(last_ticks-this_ticks)+1)/Ticks_per_second;
  end;
end;

{ returns time elapsed without resetting ticker }
function tick_seconds2 : double;
var temp : comp;
begin
  temp := this_ticks;
  get_ticks;
  tick_seconds2 := tick_seconds;
  this_ticks    := temp;
end;

{$IFDEF VER90 } { Borland Delphi version 2 }
procedure get_ticks;
begin
  QueryPerformanceCounter(TLargeInteger(this_ticks));
end;
{$ELSE }
function get_VTD_address : pointer;
begin
  asm
    mov AX,$1684        { Subcode to return API   }
    mov BX,$05          { Virtual Timer Device ID }
    xor DI,DI
    mov ES,DI
    int $2F
    mov [BP-04],DI      { put result on stack     }
    mov [BP-02],ES
  end;
end;

procedure get_ticks;
label retspot;
begin
  asm
    push cs                         { push code segment      }
    mov  bx,OFFSET retspot          { push offset of retspot }
    push bx
    mov  AX,WORD PTR VTD_Addr       { push VTD address       }
    mov  DX,WORD PTR VTD_Addr+2
    push DX
    push AX
    mov  AX,$0100
    retf                            { fake a far call        }
retspot :
    mov  WORD PTR this_ticks,ax     { comes back to here !   }
  end;
  inline(
    $66/$A3/this_ticks/             { mov this_ticks,EAX     }
    $66/$89/$16/this_ticks+4        { mov this_ticks+4,EDX   }
  );
end;
{$ENDIF }

initialization
  {$IFDEF VER90 } { Borland Delphi version 2 }
  QueryPerformanceFrequency(TLargeInteger(ticks_per_second));
  { should be 840 nS - or 838.xxx or something }
  {$ELSE }
  VTD_addr := get_VTD_address;
  {$ENDIF }
end.

Re:FAST TIMER FOR REAL TIME APPLICATIONS


If you are running on a Pentium, you can use the undocumented (?) RDTSC
instruction.
It reads a 64 bit counter that increments on CPU clock tick. On a 100MHz
Pentium
it gives 10ns resolution !!! (of cause you can't read it that fast, but
anyway...)
I often use it for profiling code.

16-bit code to read counter:

function GetCpuTimeStamp: Comp;
begin
  asm
    db $0F,$31               { RDTSC    Read Time Stamp Counter to
EDXEAX }
    db $66                   { 32 bit data prefix }
    mov word ptr Result,ax   { [Result]=eax       }
    db $66                   { 32 bit data prefix }
    mov word ptr Result+4,dx { [Result+4]=edx     }
  end;
end;

HTH
Michael Brinks

Other Threads