Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.07.29;
Скачать: CL | DM;

Вниз

Программная задержка, независимая от скорости процессора ?   Найти похожие ветки 

 
kioto   (2002-07-13 00:36) [0]

Подскажите, как программно организовать независимую от типа (скорости) процессора задержку действия на определённое время с точностью +-1мс ? Заранее благодарю.


 
BAY   (2002-07-13 00:49) [1]

Не знаю функций.
Но я бы сделал так:


T := Time+TimeDelay;
while T<>Time do;


 
NailMan   (2002-07-13 01:12) [2]

Procedure Wait(Delay:Cardinal); //Delay в мс.
Var LastCount,Count:Cardinal;
begin
Last:=GetTickCount;
repeat
Count:=GettickCount;
until Count>=(LastCount+Delay);
end;

Типа так делается задержка.


 
sunwheel   (2002-07-13 09:33) [3]

Посмотри функцию Sleep


 
Anatoly Podgoretsky   (2002-07-13 10:51) [4]

Вся проблема в заявленной высокой точности, это не под силу твоей Операционной Системе


 
Proton   (2002-07-13 19:37) [5]

2BAY
не знаеш - не советуй
твое ршение винду на некоторе всемя повесит ! (или по крайней мере тормазнет дико)
та хитя бы так сказал
while T<Time do application.processmessages;
+ T<>Time - может не сработать и программа просто напросто повиснет
2kioto
есть такая функция - называется Sleep
не думаю недо напомнить что возврат может произойти и значительно позже
если например у вас висить какой нить поцесс с боллее высоким приоритетом
(и это касается не только этого решения)


 
Странный Прохожий   (2002-07-13 20:30) [6]

С точностью +-1мс не получится.

Время задержки кратно 10мс (Windows 95 -- 50мс). Плюс случайная составляющая.

^^^ при использовании Sleep().


Чтобы получить более высокое разрешение, нужна карта, генерирующая прерывания и драйвер.


 
Anatoly Podgoretsky   (2002-07-13 21:10) [7]

Странный Прохожий © (13.07.02 20:30)
На уровне 3 ничто не поможет, есть приоритеты, есть блокирующие операции, скажем есть таймер с точностью 1 мс, плюс система добавить от нуля до нескольких секунд, например достатчно загрузить плохой СД


 
Странный Прохожий   (2002-07-14 00:47) [8]

>Anatoly Podgoretsky

Ну дык я и не спорю :o)



 
BAY   (2002-07-14 20:17) [9]

>Proton
> не знаеш - не советуй
действительно, не знаю сори, а ответ такой написал для начала обсуждения - мне тоже интересно
> T<>Time - может не сработать и программа просто напросто повиснет
это опечатка, и следом был еще один вариант: T>Time, но его убрали


 
Nimbus   (2002-07-16 15:01) [10]

А вот что я накопал на сайте
http://www.interface.ru/

По моему это может помочь Вашей беде, Kioto!!!

Точная цитата:

В ряде практически важных областей применения (при разработке игр, в системах реального времени для управления внешними устройствам и т.п.) интервал 55 мс может оказаться слишком велик. Современный ПК имеет мультимедийный таймер, период срабатывания которого может быть от 1 мс и выше, однако этот таймер не имеет компонентного воплощения, поэтому для доступа к нему приходится использовать функции API.

Общая схема его использования такова. Сначала готовится процедура обратного вызова (call back) с заголовком:


procedure TimeProc(uID, uMsg: UINT; dwUser, dw1, dw2: DWORD); stdcall;

Здесь uID — идентификатор события таймера (см. об этом ниже); uMsg — не используется; dwUser — произвольное число, передаваемое процедуре в момент срабатывания таймера; dw1, dw2 — не используются.

Запуск таймера реализуется функцией:


function timeSetEvent(uDelay, uResolution: UINT; lpTimeProc: Pointer; dwUser: DWORD; fuEvent: UINT): UINT; stdcall; external "winmm.dll";

Здесь uDelay — необходимый период срабатывания таймера (в мс); uResolution — разрешение таймера (значение 0 означает, что события срабатывания таймера будут возникать с максимально возможной частотой; в целях снижения нагрузки на систему вы можете увеличить это значение); lpTimeProc — адрес процедуры обратного вызова; dwUser — произвольное число, которое передается процедуре обратного вызова и которым программист может распоряжаться по своему усмотрению; fuEvent — параметр, управляющий периодичностью возникновения события таймера: TIME_ONESHOT (0) — событие возникает только один раз через uDelay миллисекунд; TIME_PERIODIC (1) — события возникают периодически каждые uDelay мс. При успешном обращении функция возвращает идентификатор события таймера и 0, если обращение было ошибочным.

Таймер останавливается, и связанные с ним системные ресурсы освобождаются функцией:


function timeKillEvent(uID: UINT): UINT; stdcall; external "winmm.dll";

Здесь uID — идентификатор события таймера, полученный с помощью timeSetEvent.

В следующем примере (Timer.dpr) иллюстрируется использование мультимедийного таймера



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;

type
TfmExample = class(TForm)
Panel1: TPanel;
bbRun: TBitBtn;
bbClose: TBitBtn;
edInput: TEdit;
lbOutput: TLabel;
mmOutput: TMemo;
procedure bbRunClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
fmExample: TfmExample;

implementation

{$R *.DFM}
// Объявление экспортируемых функций:

function timeSetEvent(uDelay, uReolution: UINT; lpTimeProc: Pointer;
dwUser: DWORD; fuEvent: UINT): Integer; stdcall; external "winmm";

function timeKillEvent(uID: UINT): Integer; stdcall; external "winmm";

// Объявление глобальных переменных
var
uEventID: UINT; // Идентификатор события таймера
BegTime: TDateTime; // Засекаем время<
Counter: Integer; // Счетчик повторений
Delay: Word; // Период срабатывания

procedure ProcTime(uID, msg: UINT; dwUse, dw1, dw2: DWORD); stdcall;
// Реакция на срабатывание таймера (процедура обратного вызова)
var
h, m, s, ms: Word; // Переменные для декодирования времени
const
MaxCount = 55; // Количество повторений
begin
timeKillEvent(uEventID); // Останавливаем таймер
Counter := Counter+1; // Наращиваем счетчик
if Counter=MaxCount then // Конец цикла?
begin // - Да: декодируем время
DecodeTime((Time-BegTime)/MaxCount, h, m, s, ms);
fmExample.mmOutput.Lines.Add( // Сообщаем результат
Format("Задано %s ms. Получено %d ms",
[fmExample.edInput.Text,ms]));
fmExample.edInput.Text := ""; // Готовим повторение
fmExample.edInput.SetFocus
end else // - Нет: вновь пускаем таймер
uEventID := timeSetEvent(Delay,0,@ProcTime,0,1);
end;

procedure TfmExample.bbRunClick(Sender: TObject);
// Запускает таймер. edInput содержит требуемый период.
begin
// Проверяем задание периода
if edInput.Text="" then Exit;
try
Delay := StrToInt(edInput.Text)
except
ShowMessage("Ошибка ввода числа");
edInput.SelectAll;
edInput.SetFocus;
Exit
end;
Counter := 0; // Сбрасываем счетчик
BegTime := Time; // Засекаем время
// Запускаем таймер:
uEventID := timeSetEvent(Delay,0,@ProcTime,0,1);
if uEventID=0 then
ShowMessage("Ошибка запуска таймера")
end;

procedure TfmExample.FormActivate(Sender: TObject);
begin
edInput.SetFocus
end;

end.





Страницы: 1 вся ветка

Текущий архив: 2002.07.29;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.02 c
14-95521
Viatly
2002-07-02 15:54
2002.07.29
Flash


1-95369
proc
2002-07-15 20:07
2002.07.29
Генерация объектов в run-time


14-95549
Death for...
2002-07-02 19:43
2002.07.29
Пароль под маской...


1-95308
Cosinus
2002-07-15 17:10
2002.07.29
Не подскажите, как сделать так, чтобы после компиляции программы


14-95528
fore_3
2002-06-29 01:21
2002.07.29
Люди, может лучше пользоваться поиском?