Seite 2 von 3

Verfasst: 07.11.2007 15:16
von Thalius
hab da was gefunden:

Code: Alles auswählen


; Author: chrizl
; Source: German Pureboard
Procedure DELAYUS(t.l)
  Structure DLong
    lowlong.l
    hilong.l
  EndStructure
  DLong=0
  hitimefreq.DLong
  QueryPerformanceFrequency_(@hitimefreq)
  hitimecount1.DLong
  hitimecount2.DLong
  QueryPerformanceCounter_(@hitimecount1)
  Repeat
    QueryPerformanceCounter_(@hitimecount2)
  Until Int((hitimecount2\lowlong - hitimecount1\lowlong)/(hitimefreq\lowlong/1000000.0))>=t
EndProcedure 
Das könnt Dich interessiern:
http://www.purebasic.fr/german/viewtopic.php?t=8025

und wech!
Thalius

Verfasst: 07.11.2007 16:08
von #NULL
:D super

Verfasst: 07.11.2007 16:12
von Fluid Byte
Ich arbeite mit einer schnittstelle und wenn ich kein Delay benutze kommen die signale zu schnell, wenn ich Delay(1) benutze ist mir das alles zu langsam.
Was für eine Schnittstelle? Was für Daten? Wie werden die Daten verarbeitet? Warum zu schnell?

Verfasst: 07.11.2007 19:32
von Falko
Ich glaube nicht, dass das IC mit der seriellen Schnittstelle angesteuert
werden sollte, wobei die Baudrate dann auch nicht nützlich wäre.

Unter der Hardwareecke ist einiges über eine CNC-Portal-Fräse und dessen
Ansteuerung im µs-Bereich beschrieben, was auch erklärt, was und wofür
so eine kurze Pause zwischen den Signalen gebraucht wird.
Es scheitert nur an dem Echtzeitsystems, da Windows mit einer Zeitscheibe
arbeitet, welches im Hintergrund laufende Programme die jeweiligen Zeiten
zuteilt. Darum wird es auch bei der µs-Delay-Methode
Probleme geben. Unter DOS oder noch besser mit einen Atmel
könnte man bessere Ergebnisse erzielen.

Gruß Falko

Verfasst: 07.11.2007 19:42
von NicTheQuick
@Falko: Oder unter Windows die Priorität nach oben schrauben. Das wäre
zumindest eine gute Verbesserung, aber natürlich noch nicht 100%.

Verfasst: 07.11.2007 19:53
von Falko
@NTQ

Ja, damit hast du vollkommen Recht. Das ist dann unter Windows
die einzigste Möglichkeit :allright: .

Gruß Falko

Verfasst: 07.11.2007 22:02
von mk-soft
Habs mal nach PB v4.x umgestellt und etwas optimiert.

Code: Alles auswählen

; Author: chrizl
; SecendAuthor: mk-soft
; Source: German Pureboard

Procedure DELAYUS(t.l)
  
  Protected hitimefreq.q, hitimecount1.q, hitimecount2.q, hitimediff.q, hitimemax.q
  
  QueryPerformanceFrequency_(@hitimefreq)
  
  hitimemax = hitimefreq * t / 1000000
  QueryPerformanceCounter_(@hitimecount1)
  Repeat
    QueryPerformanceCounter_(@hitimecount2)
    hitimediff = hitimecount2 - hitimecount1
  Until hitimediff >= hitimemax
EndProcedure 


Debug "Start"
QueryPerformanceCounter_(@start.q)
DELAYUS(100)
QueryPerformanceCounter_(@ende.q)
Debug "Ende"

QueryPerformanceFrequency_(@freq.q) 
result.q = (ende-start)
result * 1000000
result / freq
Debug "Zeit: " + StrQ(result)

Mein PC liegt etwa 15-28 uS über der Sollzeit

für lange Pausen nicht zu gebrauchen wegen der vollen CPU-Auslastung

FF :wink:

Verfasst: 07.11.2007 22:17
von Falko
Dann schalt mal den Debugger aus und ersetze dieses

Code: Alles auswählen

...
MessageRequester("NoDebug","Zeit: " + StrQ(result) )
...
Bei mir liegt das dann 5-6µs minimal darüber. :lol:

korrigiert auf : DELAYUS(95)

komme ich nach Zehn Tests auf genau 100µs, also 0 Abweichung.

[Edit] Wenn ich dann aber folgendes in eine Exe compiliere und dann teste, kommen bei mir Abweichungen bis ca. 6µs was aber hierbei mit
Windowsdiensten, etc. zusammen hängt.

Code: Alles auswählen

; Author: chrizl
; SecendAuthor: mk-soft
; Source: German Pureboard

Procedure DELAYUS(t.l)
 
  Protected hitimefreq.q, hitimecount1.q, hitimecount2.q, hitimediff.q, hitimemax.q
 
  QueryPerformanceFrequency_(@hitimefreq)
 
  hitimemax = hitimefreq * t / 1000000
  QueryPerformanceCounter_(@hitimecount1)
  Repeat
    QueryPerformanceCounter_(@hitimecount2)
    hitimediff = hitimecount2 - hitimecount1
  Until hitimediff >= hitimemax
EndProcedure

For i = 0 To 10
;Debug "Start"
QueryPerformanceCounter_(@start.q)
DELAYUS(95)
QueryPerformanceCounter_(@ende.q)
;Debug "Ende"

QueryPerformanceFrequency_(@freq.q)
result.q = (ende-start)
result * 1000000
result / freq
MessageRequester("NoDebug","Zeit: " + StrQ(result) )
DELAYUS(95)
Next i
Gruß Falko

Verfasst: 07.11.2007 23:02
von mk-soft
Die Frage ist ob der Counter bei Überlauf auch sauber von Plus ins Minus läuft.
Sonst kann die Differenzberechnung zum Fehler führen und das Programm hängt.

FF :wink:

P.S. Beispiel

Code: Alles auswählen

; test Quad Counter Differenzberechnung

start.q = $7FFFFFFFFFFFFF00
ende.q = start + 1000

diff.q = ende - start

Debug "Start: " + StrQ(start)
Debug "Ende : " + StrQ(ende)
Debug "Diff : " + StrQ(diff)

Verfasst: 12.11.2007 21:01
von zigapeda
der code für Delayus() is genau das was ich gesucht hab, danke @all

>Was für eine Schnittstelle? Was für Daten? Wie werden die Daten verarbeitet? Warum zu schnell?
Ich benutze die Pins DTR, RTS und CTS der RS-232 Schnittstelle um einen I²C-Bus IC (PCF8591) zu steuern...