Seite 1 von 1

hochauflösender Delay()

Verfasst: 20.04.2014 10:19
von SBond
Hi Leute,

gibt es eine einfache Möglichkeit einen hochauflösenden Delay zu erstellen?

Delay(1) ist zu langsam
Delay(0) ist zu schnell.

ich möchte damit einen Thread steuern, um die Verarbeitung von Daten zu regulieren.


viele Grüße,
SBond

Re: hochauflösender Delay()

Verfasst: 20.04.2014 10:49
von NicTheQuick
Hm... Das klingt irgendwie nicht so als ob du das Problem korrekt angehst. Kannst du etwas genauer erzählen welche Daten da verarbeitet werden sollen?

Re: hochauflösender Delay()

Verfasst: 20.04.2014 11:14
von _sivizius
du könntest den Inline-Assembler nutzen und mit

Code: Alles auswählen

NOP ; No-Operation
das fein abpassen.

Re: hochauflösender Delay()

Verfasst: 20.04.2014 11:49
von STARGÅTE

Code: Alles auswählen

Global QueryPerformanceFrequency.q, QueryPerformanceFactor.f
QueryPerformanceFrequency_(@QueryPerformanceFrequency)
QueryPerformanceFactor = 1e6/QueryPerformanceFrequency

Procedure DelayMicroSeconds(Time.q)
   Protected StartTime.q, EndTime.q
   QueryPerformanceCounter_(@StartTime)
   Repeat
      Delay(0)
      QueryPerformanceCounter_(@EndTime)
   Until (EndTime-StartTime)*QueryPerformanceFactor > Time
EndProcedure



a = ElapsedMilliseconds()
For n = 1 To 1000
   DelayMicroSeconds(300)
Next
Debug ElapsedMilliseconds()-a


Re: hochauflösender Delay()

Verfasst: 20.04.2014 11:58
von SBond
danke erstmal ;)

eingentlich ist die frage ganz allgemein gemeint. In meinem aktuellen Fall lese ich über den seriellen Port Daten ein und übertrage dies einem großen Ringpuffer. Das ganze geht in einem Thread. Damit der Thread die CPU nicht so stark belastet nutze ich ein Delay um ihn abzubremsen oder um den Füllstand des COM-Puffers zu regeln.

Der Delay ist in meinem Fall aber nicht so krittisch, da auch ein Delay von 10ms noch ok ist.

-----------------------------------------------

Aber mal ganz allgemein....
Nehmen wir mal an, ich habe eine Prozedur die 5000 mal pro Sekunde ausgeführt werden soll. Die Ausführung soll gleichmäßig sein. Das heißt, ich will die Prozedur nicht in den ersten 100ms 5000 mal aufrufen und dann 900ms pausieren, sondern die Prozedur alle 200µs aufrufen.

...eventuell wird es so deutlicher:

Code: Alles auswählen

Counter = 0
Timer	= ElapsedMilliseconds()

While ElapsedMilliseconds() - Timer <= 1000
	Counter + 1
Wend
Debug "Messung 1: " + Str(Counter)

; ############################################

Counter = 0
Timer	= ElapsedMilliseconds()

While ElapsedMilliseconds() - Timer <= 1000
	Counter + 1
	Delay(0)
Wend
Debug "Messung 2: " + Str(Counter)

; ############################################

Counter = 0
Timer	= ElapsedMilliseconds()

While ElapsedMilliseconds() - Timer <= 1000
	Counter + 1
	Delay(1)
Wend
Debug "Messung 3: " + Str(Counter)
Mit Delay(1) erreicht der Zähler nach einer Sekunde den Wert von ca. 1000.
Ohne Delay erreicht der Zähler nach einer Sekunde den Wert von ca. 5,2 Millionen.

Was muss ich machen, wenn ich z.B auf 10000 hochzählen möchte ohne dass ich die CPU unnötig belaste. Alse so etwas wie ein: Delay(0.1), den es ja nicht gibt.


...ich bin schlecht in veranschaulichen. vergebt mir :mrgreen:

----------------------------------------------------------
EDIT: hoppla.... da war einer schneller :) DelayMicroSeconds ist genau das richtige :)

Re: hochauflösender Delay()

Verfasst: 24.04.2014 20:17
von Thorium
Für alles unter 1ms nutzt man QueryPerformanceCounter. Damit kannst du die Zeit messen. Ein genaues Steuern ist nicht möglich. Du befindest dich in einem Multitaskingsystem und wieviel CPU Zeit dir wann zugesprochen wird ist kaum beeinflussbar.

Sollte eine genauere Syncronisation mit Peripherie nötig sein musst du ein Echtzeitsystem einsetzen. Oder noch nen Controller dazwischen setzen.

Alles unter Delay(1) lasstet die CPU aus. Das liegt am OS, was keine genauere Steuerung zulässt. Allerdings ist das auch kein wirkliches Problem.