Высокоточный таймер под Windows

Mach, популярные и не очень CAD, CAM. Обсуждение и разработка программ для управления станками.
spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Высокоточный таймер под Windows

Сообщение spike »

Насколько мне известно этот таймер - лучшее что есть под Windows

Код: Выделить всё

{  Имя файла: HRTimer.PAS V1.00
   Создан: Апр 17 1997, 06:40, автор John Mertus
   Обновлен #6: Окт 12 1997, 10:56 John Mertus

   Оболочка для таймера высокой точности при создании приложений под Win95/WinNT


пример использования:

Var  
  HRT : THRTimer

  HRT := THRTimer.Create;
  HRT.StartTimer;  Сброс таймера в ноль
  HRT.ReadTimer;   Возвращает отсчитанное время в миллисекундах начиная со времени старта

  HRT.Free; }

{-----------------Модуль HRTimer-------------------John Mertus Апрель 97---}


Unit HRTimer;
{-------------------Объявления-------------------------------}

interface

Uses Windows;

Type

  THRTimer = Class(TObject)
     Constructor Create;
     destructor Destroy; override;
     Function StartTimer : Boolean;
     Function ReadTimer : Double;
     procedure Wait(mks: integer);


  private
    StartTime : int64;
    ClockRate : int64;

  public
    Exists    : Boolean;
  End;

{--------------------------Реализация-----------------------------------}


implementation

{------------------Create-------------------------John Mertus----Мар 97-}


Constructor THRTimer.Create;
{ Получаем точное системное время и сохраняем его для дальнейшего использования.}
BEGIN
  Inherited Create;
  QueryPerformanceFrequency(ClockRate);
END;

{------------------StartTimer---------------------John Mertus----Мар 97-}

Function THRTimer.StartTimer : Boolean;
{ Получаем точное системное время и сохраняем его для дальнейшего использования.}
BEGIN
  Result := QueryPerformanceCounter(StartTime);
END;

procedure THRTimer.Wait(mks: integer);
var 
  Counter, Freq, WaitUntil: Int64;
begin 
  if QueryPerformanceCounter(Counter) then
  begin 
    QueryPerformanceFrequency(Freq);
    WaitUntil := Counter {+ WaitCal} + (mks * (Freq div 1000000));
    while Counter < WaitUntil do 
      QueryPerformanceCounter(Counter); 
  end 
  else 
    Sleep(mks div 1000);
end;

{-------------------ReadTimer---------------------John Mertus----Мар 97---}

destructor THRTimer.Destroy;
begin

  inherited;
end;

Function THRTimer.ReadTimer : Double;
Var
  ET : TLargeInteger;
BEGIN
  QueryPerformanceCounter(ET);
  Result := 1000000.0*(ET - StartTime)/ClockRate;
END;

end.
spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Применение в GIGAMESH 1H

Сообщение spike »

Этот таймер применен для реализации системы управления шаговым приводом в программе GIGAMESH 1H

Код: Выделить всё

  if not(TimeOut=0) then
    fHRT.Wait(TimeOut);  //Задержка таймаута
  PortWork(Mask, 32); //Выдача в порт команды

  fHRT.Wait(PulseTime-TimeOut); //Задержка стола
  PortWork(fPortState, 32); //Возврат состояния порта

spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Re: Высокоточный таймер под Windows

Сообщение spike »

Из ЛС:
CrowScout писал(а): ... Я тоже воткнулся было в такую проблему. .. так пока окончательно не решил - необходимость отпала (хотя интерес остался). Дык вот тут http://forums.overclockers.ru/viewtopic ... E0&start=0 - интересные решения для таймеров в дельфи . Статья "Системный таймер и частота процессора
" и тут - http://www.cyberforum.ru/cpp-beginners/thread20934.html
если помог - напиши.
Весьма интересные ссылки, спасибо!, особо - архивчик в конце второй ссылки )ay( (они правда на С++), у меня таймер реализован на QueryPerfomanceCounter - как в описании выше.
CrowScout писал(а):Хотел получить таймер в OCX - сам не умею. Мож вы поможете?
)bk( Помог бы еслиб мог - я только по-наслышке знаю что такое OCX.

Прикреплю архив с таймерами на С сюда:
timers.zip
(47.45 КБ) 614 скачиваний
CrowScout
Новичок
Сообщения: 1
Зарегистрирован: 19 ноя 2009, 21:24
Репутация: 0
Контактная информация:

Re: Высокоточный таймер под Windows

Сообщение CrowScout »

там они тоже используют QueryPerfomanceCounter но вызывают его ассемблером как я понял и используют что-то вроде калибровки. overhed что-ли...
этот самый оверхэд позволяет им отсчитывать наносекунды. Также важно использование потоков. Сам я их не использовал но пытался разобраться (в VB) даже вроде как почти получилось. не довёл дело до конца. VB всё-таки не то что нужно по сравнению с дельфи или Си что касается написания таймеров.
spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Re: Высокоточный таймер под Windows

Сообщение spike »

Да, калибровку видел, правда пока не совсем понял сам принцип, да и сильно не разбирался в коде - пока нет необходимости. Впринципе таймер, который у меня реализован работает неплохо, есть конечно ньюансы кой какие: в GIGAMESH`е он работает в отдельном потоке, и, соответственно, этому потоку можно задать приоритет такой что винда вообще затыкается - тогда двигатели работают идеально, либо это должна быть машина с двухъядреным процессором - для такой машины тоже все отлично - винда выделяет для потока таймера одно ядро, а второе использует для собственных нужд и интерфейса.
spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Re: Высокоточный таймер под Windows

Сообщение spike »

Статья - анализ реализаций таймеров под Windows с примерами на VBA
spike
Почётный участник
Почётный участник
Сообщения: 358
Зарегистрирован: 08 фев 2010, 01:03
Репутация: 5
Контактная информация:

Re: Высокоточный таймер под Windows

Сообщение spike »

Точное время: измеряем, применяем - статья на Хабре, насколько я понял QueryPerfomanceCounter не используется...
Ответить

Вернуться в «Windows / Mach»