Форум: "Основная";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];
ВнизПрограммная задержка, независимая от скорости процессора ? Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c