Советы по Delphi

       

Организация задержки I


Организация задержки - все еще большая головная в Delphi. Я использую Delphi 1 и пытаюсь организовать задержку 2 ms с погрешностью -0 ms +1 ms. Может кто-то уже решал подобную проблему? Организация цикла не позволяет достичь такой точности. Стандартный таймерный компонент не позволяет работать с частотой выше чем 18.2 times/sec.

Приведу модуль, который я использовал при создании 16-битного хранителя экрана (screen saver). В нем есть переменная DelayInit, объявленная глобально и инициализируемая во время создания формы как показано ниже:

DelayInit := False;
Delay(0); {Проводим инициализацию и присваиваем 0 для дальнейшей калибровки}

Этим мы указываем на необходимость калибровки для конкретной системы.



unit Globals;

interface

Uses
WinProcs, WinTypes, Messages,Classes, Graphics, IniFiles;

Const
OT_USER = 1;
Var
SsType : Integer; { iObjL : Integer; { Текущая левая координата объекта }
{ iObjR : Integer; { Текущая правая координата объекта }
{ iObjT : Integer; { Текущая верхняя координата объекта }

Finish : Boolean;TestMode : Boolean; { True если режим тестирования }LoopsMs : LongInt; { Ms циклов }ScreenWd : Integer; { Ширина экрана }ScreenHt : Integer; { Высота экрана }
SpotSize : Integer; { Размер точки }SpotSpeed : Integer; { Скорость точки }
DelayInit : Boolean; { True если цикл задержки инициализирован }
Procedure Delay(Ms : Integer); { Задержка для Ms миллисекунд }
Procedure CursorOff; { Включение курсора }Procedure CursorOn; { Выключение курсора }
{$IFDEF NOVELL}

{$ENDIF}
implementation

Uses

SysUtils,Toolhelp;
Procedure CursorOff; { Выключение курсора }Var
Cstate : Integer; { Текущее состояние курсора }Begin
Cstate := ShowCursor(True); { Получаем состояние }While Cstate >= 0 do Cstate := ShowCursor(False); { Пока состояние >= 0 курсор выключен }End;

Procedure CursorOn; { Выключаем курсор }Var
Cstate : Integer; { Текущее состояние курсора }Begin
Cstate := ShowCursor(True); { Получаем состояние }While Cstate < 0 do Cstate := ShowCursor(True); { Пока состояние < 0 курсор включен }End;

Procedure Delay(Ms : Integer); { Задержка для Ms миллисекунд }{Если Ms равно 0, проводим калибровку }Var
L,MaxLoops,StartL,EndL,Down,Up,Res : LongInt; { Локальные переменные }Ti : TTimerInfo;Begin
Up := 0;Down := 100000;if Not DelayInit then beginTi.dwSize := sizeof(LongInt) * 3;TimerCount(@Ti);StartL := Ti.dwmsSinceStart; { Получаем время старта }if Not DelayInit then begin { Включаем тест }for L := 0 to 100000 do begin { Организуем цикл с числом проходов равным 100000 }Dec(Down); { Уменьшаем счетчик }Res := Abs(Down - Up); { Разница }if Res = 0 then Inc(Res); { Сверка }Inc(Up); { Приращение }end;end;TimerCount(@Ti);EndL := Ti.dwmsSinceStart; { Получаем время старта }LoopsMs := 100000 Div (EndL - StartL); { Вычисляем показатель MS }DelayInit := True; { Откалибровали }endelse beginif Ms = 0 then Exit;MaxLoops := LoopsMs * Ms; { Получаем необходимое количество циклов }for L := 0 to MaxLoops do Begin { Организация цикла }Dec(Down); { Уменьшаем счетчик }Res := Abs(Down - Up); { Получаем разницу }if Res = 0 then Inc(Res); { Сверка }Inc(Up); { Приращение }endend;End;

end.
[000264]


Procedure Delay (Seconds: Word);VarLater: TDateTime;BeginLater := Now + (Seconds / (24.0 * 60.0 * 60.0));While Now < Later do Application.ProcessMessages;end;
[000652]


Содержание раздела