Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.011 c
1-95332
ivlex
2002-07-13 16:22
2002.07.29
Запись в log при завершении или перезагрузке


3-95204
John Eagle
2002-07-06 00:32
2002.07.29
DBGrid - чтоб не менялся фокус при скроллинге...


1-95374
Jo
2002-07-15 11:11
2002.07.29
Может кто подскажет?


3-95208
alexvan
2002-07-06 18:57
2002.07.29
При SQL запросе запрос проходит 1 раз


1-95319
olookin
2002-07-15 16:07
2002.07.29
Перечисление констант





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский