Добро пожаловать на Форум по станкам с ЧПУ!

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

Тема в разделе "Программные вопросы", создана пользователем NCuser, 23 окт 2017.

  1. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0
    Насколько мне известно этот таймер - лучшее что есть под 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.
     
  2. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0
    Этот таймер применен для реализации системы управления шаговым приводом в программе GIGAMESH 1H

    Код:
      if not(TimeOut=0) then
        fHRT.Wait(TimeOut);  //Задержка таймаута
      PortWork(Mask, 32); //Выдача в порт команды
    
      fHRT.Wait(PulseTime-TimeOut); //Задержка стола
      PortWork(fPortState, 32); //Возврат состояния порта
    
    
     
  3. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0
    Из ЛС:
    Весьма интересные ссылки, спасибо!, особо - архивчик в конце второй ссылки (они правда на С++), у меня таймер реализован на QueryPerfomanceCounter - как в описании выше.
    Помог бы еслиб мог - я только по-наслышке знаю что такое OCX.
     
  4. MurCom

    MurCom Member

    Регистрация:
    11 май 2012
    Сообщения:
    74
    Симпатии:
    0
    там они тоже используют QueryPerfomanceCounter но вызывают его ассемблером как я понял и используют что-то вроде калибровки. overhed что-ли...
    этот самый оверхэд позволяет им отсчитывать наносекунды. Также важно использование потоков. Сам я их не использовал но пытался разобраться (в VB) даже вроде как почти получилось. не довёл дело до конца. VB всё-таки не то что нужно по сравнению с дельфи или Си что касается написания таймеров.
     
  5. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0
    Да, калибровку видел, правда пока не совсем понял сам принцип, да и сильно не разбирался в коде - пока нет необходимости. Впринципе таймер, который у меня реализован работает неплохо, есть конечно ньюансы кой какие: в GIGAMESH`е он работает в отдельном потоке, и, соответственно, этому потоку можно задать приоритет такой что винда вообще затыкается - тогда двигатели работают идеально, либо это должна быть машина с двухъядреным процессором - для такой машины тоже все отлично - винда выделяет для потока таймера одно ядро, а второе использует для собственных нужд и интерфейса.
     
  6. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0
    Статья - анализ реализаций таймеров под Windows с примерами на VBA
     
  7. NCuser

    NCuser Member

    Регистрация:
    8 май 2012
    Сообщения:
    308
    Симпатии:
    0