Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 2002.12.30;
Скачать: [xml.tar.bz2];

Вниз

Как сделать таймер с задержкой меньше 1 мс?   Найти похожие ветки 

 
lmd_sting   (2002-10-23 14:09) [0]

Возник такой трабл. Нужно реализовать принятие данных из com порта . Если считывать информацию из буфера то без проблем достигается скорость около 11 кб/c . Но контроллер передает по одному байту потом ждет ответа от компа. Стандартный таймер имеет минимальную задержку в 1 мс , т.е. я проверяю буфер достаточно редко и скорость резко падает. Может кто нибудь знает как это реализуется или я думаю не в том направлении?


 
Opuhshii   (2002-10-23 14:14) [1]

у Стандартного таймера минимальная задержка больше 1 мс .. смотри FAQ


 
Bis   (2002-10-23 15:18) [2]

а зачем это делать по таймеру?


 
Anatoly Podgoretsky   (2002-10-23 15:25) [3]

Без таймера спокояно передается до 90 кб в секунду, просто быстрее компорт не попадался


 
lmd_sting   (2002-10-24 12:30) [4]

А как это реализовать без таймера? Каким образом можно передавать со скоростью 90 кб/c если IMHO com расчитан максимум на 128000 кбит/c (16 кб/c) хотя реально я устанавливал скорость только на 115200 если больше то выдавалась ошибка инициализации порта.


 
lmd_sting   (2002-10-24 12:35) [5]

Есть какие нибудь события по которым можно определить пришли ли данные в ком порт?


 
sunsb   (2002-10-25 02:35) [6]

Сам я им не пользовался, но в демках DX для Делфи
он используется сплош и рядом. Надеюсь немца вы найдете ))).

unit DXTimer; // 22-OCT-98 as (Arne Schдpers)
Overhead: P-166 Win95
1 Timer, 20 msec (50 Events) 4%
5 Timer, 20 msec (250 Events) 13%
25 Timer, 100 msec (250 Events) 16%
25 Timer, 20 msec (1000 Events) 37%
1 Timer, 1 msec (1000 Events) 35%

Grenze fьr Win95: 3000 Events/sec sync, 15000 Events async
Bei 1000 Events/sec benцtigt Synchronize rund 15%

MODs 06-MAR-99: Typecasts von MaxWait, NextTick wg. Delphi 4.
Vernьnftig unter einen Hut bringen lдЯt sich das nicht, weil
D3 auch bei Cardinal gnadenlos ein Vorzeichen reinhaut...
}
interface
uses Windows, SysUtils, Classes, MMSystem;

type
TDXTimer = class(TComponent)
private
FInterval: Cardinal; // echte Millisekunden
FOnTimer, FOnAsyncTimer: TNotifyEvent;
FEnabled: Boolean;
StartTickTime, NextTick: Integer; // Zeitrahmen
TimerThread: TThread; // TDXTimerThread (implementation)
procedure UpdateTimer; // XRef: Set..., Destroy
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
procedure SetOnAsyncTimer(Value: TNotifyEvent);
protected
procedure Timer; // per Synchronize
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled
write SetEnabled default True;
property Interval: Cardinal read FInterval
write SetInterval default 20;
property OnTimer: TNotifyEvent // synchron
read FOnTimer write SetOnTimer;
property OnAsyncTimer: TNotifyEvent // asynchron
read FOnAsyncTimer write SetOnAsyncTimer;
end;

implementation

type // intern verwendeter Thread
TDXTimerThread = class(TThread)
private
Owner: TDXTimer;
TimerEvent: THandle; // zum Warten und fьr Updates
public
constructor Create(AOwner: TDXTimer);
destructor Destroy; override;
procedure Execute; override;
procedure Terminate;
end;

constructor TDXTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True; FInterval := 20;
TimerThread := TDXTimerThread.Create(Self);
end;

destructor TDXTimer.Destroy;
begin
FEnabled := False; UpdateTimer; // Timer aus
TimerThread.Terminate;
inherited Destroy;
end;

procedure TDXTimer.UpdateTimer;
begin
StartTickTime := timeGetTime;
NextTick := StartTickTime+Integer(Interval);
SetEvent(TDXTimerThread(TimerThread).TimerEvent);
end;

procedure TDXTimer.SetEnabled(Value: Boolean);
begin
if Value = FEnabled then Exit;
FEnabled := Value; UpdateTimer;
end;

procedure TDXTimer.SetInterval(Value: Cardinal);
begin
if Value = FInterval then Exit;
FInterval := Value; UpdateTimer;
end;

procedure TDXTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value; UpdateTimer;
end;

procedure TDXTimer.SetOnAsyncTimer(Value: TNotifyEvent);
begin
FOnAsyncTimer := Value; UpdateTimer;
end;

procedure TDXTimer.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;


// ------------- TDXTimerThread -----------------
constructor TDXTimerThread.Create(AOwner: TDXTimer);
begin
inherited Create(False);
Owner := AOwner;
TimerEvent := CreateEvent(nil, False, False, nil);
FreeOnTerminate := True;
end;

procedure TDXTimerThread.Terminate;
begin
inherited Terminate;
SetEvent(TimerEvent); // sonst wartet der ewig...
end;

destructor TDXTimerThread.Destroy;
begin
CloseHandle(TimerEvent);
inherited Destroy;
end;

procedure TDXTimerThread.Execute;
var MaxWait, WaitResult: Integer;
begin
while not Terminated do
begin
with Owner do
if Enabled and (Assigned(FOnTimer) or
Assigned(FOnAsyncTimer)) then
begin
MaxWait := Cardinal(NextTick)-timeGetTime;
if MaxWait <= 0 then
begin // Breakpoints bei der Entwicklung erzeugen sonst
if -MaxWait > 10*Integer(Interval) // *sehr* eilige Timer..
then NextTick := timeGetTime;
MaxWait := 0;
end;
end
else MaxWait := Integer(INFINITE);
if MaxWait = 0 then WaitResult := WAIT_TIMEOUT
else WaitResult := WaitForSingleObject(TimerEvent,MaxWait);
case WaitResult of
WAIT_OBJECT_0: ; // neue Werte
WAIT_TIMEOUT:
with Owner do
begin
Inc(NextTick,Interval);
// zuerst ein eventueller asynchroner, dann ein
// synchronisierter Aufruf
if Assigned(FOnASyncTimer) then OnASyncTimer(Owner);
if Assigned(FOnTimer) then Synchronize(Timer)
end;
else
raise Exception.Create
(Format("DXTimer: WaitResult = %d?",[WaitResult]));
end;
end;
end;
end.

www : http://sunsb.dax.ru , http://sunsb.narod.ru


 
Aleks1   (2002-10-25 04:24) [7]

Я и сам, нередко, использую в подобных задачах таймер. Но лишь для того только, чтобы не насиловать железо. Пусть у него будет время жить своей жизнью.
Но, во-первых, драйвер порта всегда сообщает о том, что что-то принято! Во-вторых тот же драйвер сообщает, что что-послано! Следовательно, весьма логично писать подобную задачу используя эти события!


 
lmd_sting   (2002-10-25 10:44) [8]

Каким образом он это сообщает (какое при этом возникает событие)? Я щас это узнаю путем проверки количиства байт в буфере.


 
Странник   (2002-10-25 11:06) [9]

а ты лови соответствующее событие...


procedure TComThread.Execute;
var
EventHandles: Array[0..1] of THandle;
Overlapped: TOverlapped;
Signaled, BytesTrans: DWORD;
begin
FillChar(Overlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := CreateEvent(nil, True, True, nil);
EventHandles[0] := FStopEvent;
EventHandles[1] := Overlapped.hEvent;
repeat
WaitCommEvent(FComPort.Handle, FMask, @Overlapped);
Signaled := WaitForMultipleObjects(2, @EventHandles, False, INFINITE);
case Signaled of
WAIT_OBJECT_0: Break;
WAIT_OBJECT_0 + 1:
if GetOverlappedResult(FComPort.Handle, Overlapped, BytesTrans, False)
then DispatchComMsg;
else Break;
end;
until False;
PurgeComm(FComPort.Handle, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR);
CloseHandle(Overlapped.hEvent);
CloseHandle(FStopEvent);
end;


 
Шуррик   (2002-10-25 11:25) [10]

Доп. вопрос: мне тоже нужен таймер, но не для кома, хотя он будет использоваться впоследствии и именно частоту его событий (и еще чуть быстрее) я собираюсь (пока) эмулировать. Один из вариантов - запустить на модеме Локал Аналог Лупбак - и использовать его события. Вообще, никто такой фихой раньше не занимался?


 
Steven Deathman   (2002-10-26 09:49) [11]

Проще взять стандартный объект, например Async32? Он сам все за тебя сделает. У меня работает обмен с микроконтроллером на 57600 без проблем, а между компами на 115200.



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

Форум: "Система";
Текущий архив: 2002.12.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
1-99083
Emigrant
2002-12-17 02:25
2002.12.30
D6: TListBox


1-99184
reticon
2002-12-18 20:32
2002.12.30
Обработка события OnKeyDown


1-99099
TsaturSoft
2002-12-18 08:36
2002.12.30
???


14-99297
Best Sniper
2002-12-08 19:15
2002.12.30
Установил Oper у 6.05.......


1-99153
Berg
2002-12-18 17:30
2002.12.30
Тип TStringList





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский