Toon posts:

[Python] Het probleem van de 100 Hz

Pagina: 1
Acties:

Verwijderd

Topicstarter
Al een poosje ben ik in Python een programma aan het schrijven waarmee ik door middel van JTAG data in een chip kan zetten of uitlezen. Deze JTAG-interface komt op de parallelle poort.

Het is me gelukt om door middel van een zelf geschreven module de LPT-poort aan te sturen, maar hierbij stuit ik op een probleem.
Ik noem dit probleem "het probleem van de 100 Hz".

Tijdens het testen van mijn eerste het script kreeg ik de verversingsfrequentie van de poort niet hoger dan 100 Hz, dit is gemeten met de Oscilloscoop.
Om dit te omzeilen heb ik via de module "ctypes" geprobeerd door middel van de Windows-timers in de kernel32.dll de frequentie nog meer omhoog te krijgen. De timers die in Windows zitten kan je theoretisch op 100 ns. nauwkeurig instellen. Maar ook via deze weg kom ik niet verder dan 100 Hz.

Nu heb ik uit frustratie een pythonextension in c geschreven waarbij ik gebruik maakt van de Windows API. Van deze extension heb ik een hoop grijze haren gekregen en (bijna) geen nagels meer overgehouden.
En u raad het waarschijnlijk al, weer niet verder dan 100 Hz. Dit keer ben ik er wel minder zeker van de nauwkeurigheid omdat ik geen oscilloscoop tot mijn beschikking heb. Maar wanneer je een lijst van 400 items in de buffer van je extension zet en het LED-tje brandt ongeveer 4 sec. terwijl de verversingsfrequentie op 1 MHz staat, kan je er wel vanuit gaan dat het ongeveer 100 Hz is.

Ik weet dat de module "time" ook een nauwkeurigheid heeft van 1/100 sec. en ik heb ook ergens gelezen dat deze tijd ergens in Python zit ingebakken. (Ik kan de link niet meer terug vinden.)

Mijn punt is of er meer mensen met het 100 Hz probleem te maken hebben gehad en hoe ze dit hebben opgelost.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 11-02 08:33
Voorzover ik weet is JTAG een serieel protocol. Met de parallelle poort dus met de hand alle bits versturen lijkt me dan nogal omslachtig en gaat dus niet werken, mede omdat je nooit zo precies kunt timen op een multitasking, niet-realtime OS. Kan het niet gewoon met de seriele poort? Daar gooi je je spullen in een buffer, geef je aan hoe snel de poort werkt en als het goed is doet de UART de rest... :)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
Er zijn al verschillende topics over geweest. Bottom line:

Timing nodig die precieser is dan 10ms --> realtime OS nemen.

Je zou met timeBeginPeriod je resolutie misschien iets kunnen opschroeven, maar ik kan je verzekeren dat het sappelen blijft.

NB Het is niet voor niets dat programmers en debuggers die bij dat soort spul horen allemaal externe uP's gebruiken.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
De JTAG die ik hier heb is van olimex http://www.olimex.com/dev/msp-jtag.html. Deze simpele uitvoering haalt maar een paar kB/s en maak toch geen gebruik van een µC.

Deze JTAG werkt gewoon goed met IAR (een ontwikkelomgeving). Wel moet ik erbij vertellen dat IAR een dll van de fabrikant van deze chips gebruikt. Ik kan deze dll wel gebruiken maar er is nergens documentatie van te vinden.

Voor het verversen van de registers in de LPT slinger ik een thread aan. Deze thread maakt gebruik van SetWaitableTimer en WaitForSingleObject om te synchroniseren.
De clock die nodig is om de seriele data te versturen komt vanuit de parallelle poort door een pin steeds hoog/laag te maken.

timeBeginPeriod kon ik nog niet. Ik zal deze functie uitproberen.

Misschien scheelt het als er in plaats van een thread een nieuwe process gemaakt wordt, zodat het (misschien) buiten Python om gaat. Maar hoe zit je dan met het gebruik van je buffers.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
De hoogste precisie zonder een busywait loop kun je bereiken met multimedia timers ( let erop dat de callback functie in een aparte thread runt )

Met een busywait kun je iets beter bereiken, maar tijdens de loop 'hangt' je systeem. ( Een busywait is een loopje die eigenlijk niets doet dan (pseudo)

code:
1
2
while timer < target
end while


Je kunt dit eigenlijk niet fatsoenlijk gebruiken als langer dan 10ms wilt wachten. ( Probeer maar eens een andere applicatie aan te klikken als je iar download )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 19-10-2025
Gebruik je toevallig inpout.dll voor de lpt poort? Deze is namelijk nogal traag.
Als er tussen 2 aanroepen zelfs maar 1 ms zat kreeg ik al een vertraging van 16 ms.

Een oplossing daarvoor was steeds de dll aan te roepen, dan zit je dus wel op 100% cpu gebruik.

Misschien dat je windows 98 kunt gaan draaien en dan een byte pointer aanmaken naar het adres van de lpt poort.

Maar als je toch al verstand hebt van elektronica is het praktischer om een pic te pakken die je aanstuurt via rs232.

[ Voor 14% gewijzigd door bobo1on1 op 26-06-2006 16:02 ]

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Verwijderd

Topicstarter
timeBeginPeriod en timEndPeriod verhogen de resolutie van de timer naar 1 ms. Dit werkt, en maakt van mijn Pythonporbleem een Windowsprobleem.
Ik kan afleiden aan de tijd dat mijn LED brand dat de verversingstijd ongeveer 1 ms is.

De extension waaraan ik bezig ben maakt geen gebruik van andere dll's, het is zelf een dll met pythonfuncties. Met _outp(data, register) en _inp(register) functies uit conio.h kan je met naar je LPT schrijven en lezen.

Maar hoe zit het dan met de printers die op een parallelle poort zijn aangesloten. Is het alleen mogelijk om als driver in Windows real-time bezig te zijn? Daarnaast vindt ik het vreemd dat ze op msdn aangeven dat de resolutie van functie SetWaitableTimer "maarliefst" 100 ns is.

Zo'n while-lus kan een oplossing zijn. Maar als veel data heb kan het inderdaad minder prettig zijn.

  • geforce5_guy
  • Registratie: December 2001
  • Niet online
Verwijderd schreef op maandag 26 juni 2006 @ 17:32:
timeBeginPeriod en timEndPeriod verhogen de resolutie van de timer naar 1 ms. Dit werkt, en maakt van mijn Pythonporbleem een Windowsprobleem.
Ik kan afleiden aan de tijd dat mijn LED brand dat de verversingstijd ongeveer 1 ms is.

De extension waaraan ik bezig ben maakt geen gebruik van andere dll's, het is zelf een dll met pythonfuncties. Met _outp(data, register) en _inp(register) functies uit conio.h kan je met naar je LPT schrijven en lezen.

Maar hoe zit het dan met de printers die op een parallelle poort zijn aangesloten. Is het alleen mogelijk om als driver in Windows real-time bezig te zijn? Daarnaast vindt ik het vreemd dat ze op msdn aangeven dat de resolutie van functie SetWaitableTimer "maarliefst" 100 ns is.

Zo'n while-lus kan een oplossing zijn. Maar als veel data heb kan het inderdaad minder prettig zijn.
De printer krijgt alles binnen via 8 datalijnen. Er zijn dan nog wat lijnen voor aan te geven wat begin is en eind etc. De data gaat dus paralel ( naast elkaar) naar de printer.
elke bit heeft zijn eigen datalijn. JTAG / serieel werkt via een tijd gebonden communicatie via 1 zend en 1 ontvangende datalijn.

JTAG is een serieel protocol dat Atmel ook gebruikt voor zijn chips. En dus eigenlijk alleen maar af te lezen/schrijven met een COM (RS232) poort volgens mij.

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 19-10-2025
Drivers mogen direct naar de lpt poort schrijven maar met een printer werkt dat nog weer net iets anders, een usb naar lpt converter heeft geen adres om direct naar te schrijven, toch werkt een printer daar goed mee.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op maandag 26 juni 2006 @ 17:32:
Maar hoe zit het dan met de printers die op een parallelle poort zijn aangesloten. Is het alleen mogelijk om als driver in Windows real-time bezig te zijn?
Ja en nee. Als driver heb je natuurlijk wel wat meer vrijheid, maar nog altijd geen real-time garanties. Maar de communicatie met een printer hoeft ook niet per se met een vaste datarate te gebeuren, het kan prima in bursts - zolang de driver z'n timeslice heeft kan ie gewoon data over de kabel jassen, als ie z'n timeslice kwijt is wordt er dus niets verzonden. Ik weet overigens niet zeker of drivers ook altijd zo werken, maar het is zeker een goede optie.
Daarnaast vindt ik het vreemd dat ze op msdn aangeven dat de resolutie van functie SetWaitableTimer "maarliefst" 100 ns is.
Resolutie is niet gelijk aan granulariteit. Ze vragen om een getal in eenheden van 100ns, maar niets zegt dat ze een dergelijke resolutie ook halen. timeGetTime() geeft ook antwoorden in milliseconden, desalniettemin is het verschil tussen twee calls naar timeGetTime() vaak een veelvoud van ongeveer 18 ms.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
geforce5_guy schreef op maandag 26 juni 2006 @ 17:41:
De data gaat dus paralel ( naast elkaar) naar de printer.
elke bit heeft zijn eigen datalijn.
Je kan het ook zien als 8 losse seriele lijnen die toevallig in 1 register zitten. 1 bit voor TCK (clock), 1 voor de TDI (data in), 1 voor TMS (een soort trigger).
.oisyn schreef op maandag 26 juni 2006 @ 18:11:
Resolutie is niet gelijk aan granulariteit.
Daar heb je gelijk in.

Ik bedenk me ook dat het mogelijk is om via de parallelle poort een hardware interrupt binnen te krijgen. Deze interrupt, van bijvoorbeeld een printer, kan een routine aanroepen die weer nieuwe data in de register van de parallelle poort schrijft. Hierdoor is zijn er geen timers nodig, het doel bepaald de snelheid.
Maar uit het schema van de JTAG is weinig logica te vinden, behalve een buffer (sn74hc244), opamp en een spanningsregelaartje.

Het probleem van een com is denk ik, dat je geen clock mee kan sturen.

Ik maak hieruit op dat heel moeilijk is om relatief snelle timingen in Windows uit te voeren.

[ Voor 4% gewijzigd door Verwijderd op 26-06-2006 19:47 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
Verwijderd schreef op maandag 26 juni 2006 @ 19:37:
Ik bedenk me ook dat het mogelijk is om via de parallelle poort een hardware interrupt binnen te krijgen. Deze interrupt, van bijvoorbeeld een printer, kan een routine aanroepen die weer nieuwe data in de register van de parallelle poort schrijft. Hierdoor is zijn er geen timers nodig, het doel bepaald de snelheid.
Dat zou kunnen, maar dan zit je dus wel op ring 0 ( kernel ) niveau omdat je in user space geen mogelijkheid hebt om interrupts op te vangen. ( Trouwens ook op dit niveau heb je geen enkele garantie hoe snel jouw interrupt handler wordt aangeroepen door het systeem. )
Ik maak hieruit op dat heel moeilijk is om relatief snelle timingen in Windows uit te voeren.
Schaamteloze zelfquote
farlane schreef op maandag 26 juni 2006 @ 11:40:
Bottom line: Timing nodig die precieser is dan 10ms --> realtime OS nemen.
Dit is btw geen Windows only tekortkoming. Ook op bijv Linux is high resolution timing een probleem. ( Eigenlijk belachelijk dat na weet ik veel hoeveel jaar x86 daar nog niets op bedacht is )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
farlane schreef op dinsdag 27 juni 2006 @ 08:40:
[...]

Dit is btw geen Windows only tekortkoming. Ook op bijv Linux is high resolution timing een probleem. ( Eigenlijk belachelijk dat na weet ik veel hoeveel jaar x86 daar nog niets op bedacht is )
Wat is het punt dat je hier probeert te maken? Blijkbaar hebben Linux en Windows beide geen realtime in zich. Mogelijk bewust? Het brengt namelijk extra problemen met zich mee voor een OS om multitasking en RT met elkaar te combineren. En omdat het m.i. maar voor een beperkte set applicaties echt van belang is om timings < 10 ms aan te kunnen, kan ik me voorstellen dat een generic multitask oriented OS daar niet in voorziet.

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 19-10-2025
In de linux 2.6 kernel zit wel ondersteuning om threads op een extreem hoge prioriteit te draaien, als zo'n thread de cpu nodig heeft hebben alle andere threads pech en moeten die maar even wachten, zelfs je muis reageert dan even niet meer.

Dit wordt veel gebruikt voor realtime audio bewerking, waarbij de bewerking precies op dat moment moet gebeuren, als het later gebeurt heeft het al geen zin meer want dan is de volgende data al aangekomen.

Of je daarmee ook een timer zo precies kunt laten werken weet ik niet, maar daar heb je dan al bijna een dedicated computer voor nodig, als zo'n thread een beetje flink bezig is valt er niet meer met die pc te werken.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Verwijderd

geforce5_guy schreef op maandag 26 juni 2006 @ 17:41:
[...]

JTAG is een serieel protocol dat Atmel ook gebruikt voor zijn chips. En dus eigenlijk alleen maar af te lezen/schrijven met een COM (RS232) poort volgens mij.
Nee, JTAG is juist iets wat je via bit-banging en de paralelle poort aanstuurt. RS232 heeft daar de verkeerde signaal-niveaus voor (+12V en -12V voor resp. 1 en 0, ipv. de benodigde +5V en 0V). Bovendien stuur je via je seriele poort altijd groepjes van 8 bits, terwijl je bij JTAG soms 11, 7 of 53 bits moet lezen of schrijven.

Het probleem wat de TS heeft is dat het vanuit userspace onder moderne Windowsen gewoon heel lastig is een beetje vlot de paralelle poort aan te sturen. Het probleem is namelijk dat elke parpoort-operatie een kernel call is (en dus een contextswitch). Dit probleem heb je overigens ook onder Linux.

Wat je overigens wel kunt proberen is of je je OS zo ver kunt krijgen dat je I/O rechten verkrijgt, en dus via de x86 'in' en 'out' instructies bij je paralelle poort kunt. De processor heeft daar mogelijkheden voor, maar ik weet niet in hoeverre Windows dat ondersteund. Nadeel hiervan is ook dat je een stukje assembly moet schrijven (ik weet niet of je daar ervaring mee hebt).

Een ander alternatief is natuurlijk om te kijken of iemand anders dat werk al voor je gedaan heeft.
Verwijderd schreef op maandag 26 juni 2006 @ 19:37:
Maar uit het schema van de JTAG is weinig logica te vinden, behalve een buffer (sn74hc244), opamp en een spanningsregelaartje.
Dat schema doet niets anders dan de signaallijnen netjes bufferen.

[ Voor 13% gewijzigd door Verwijderd op 27-06-2006 15:55 ]


Verwijderd

Topicstarter
Verwijderd schreef op dinsdag 27 juni 2006 @ 15:53:
Het probleem wat de TS heeft is dat het vanuit userspace onder moderne Windowsen gewoon heel lastig is een beetje vlot de paralelle poort aan te sturen.
Hier komt het inderdaad op neer. De nauwkeurigheid van te timing is van minder groot belang. Wanneer je met maar met 1 kHz je poort kan verversen, duurt het flashen best lang.

Hieronder zie je een voorbeeld van het wegschrijven van 16 bitjes. De clock (TCK) komt vanuit je parallelle poort. Dit houdt in dat je met 1kHz maar 500 bitjes/s kan overzetten, en dat is de overhead nog niet meegerekend.
Afbeeldingslocatie: http://www.xs4all.nl/~klein00/JTAG-data.gif

Verwijderd

Verwijderd schreef op dinsdag 27 juni 2006 @ 17:47:
[...]

Hier komt het inderdaad op neer. De nauwkeurigheid van te timing is van minder groot belang. Wanneer je met maar met 1 kHz je poort kan verversen, duurt het flashen best lang.
Helemaal als je nog 'ns je flash via boundary-scanning moet aansturen...

Nou zat ik nog 'ns door mijn oude JTAG code heen te bladeren, en 't blijkt dus dat ik indertijd onder Linux veel hogere snelheden haalde. Dus of Windows zit meer in de weg dan ik dacht, of jouw code is wat minder optimaal dan die van mij.

Nou gaat 't in mijn geval om een C programma, dus misschien dat 't zin heeft dat te proberen. Misschien dat bepaalde Python-operaties die je gebruikt wat meer overhead hebben dan je denkt? Ik mag aannemen dat je de modificatie van alle signaallijnen met 1 operatie doet... Hoe wacht je tussen elke modificatie?

Als je overigens interesse hebt kan ik je mijn code wel opsturen, maar ik kan niet garanderen dat 't werkt (of ueberhaupt compileert).



Ik heb nog even gezocht. Kan je hier niet wat mee? Ze zeggen dat 't ook onder win32 werkt.

[ Voor 9% gewijzigd door Verwijderd op 27-06-2006 21:05 ]


Verwijderd

Topicstarter
Deze link zal ik helemaal gaan uitspitten misschien dat ik zo verder komt.

Op internet ben ik iets van QueryPerformanceCounter tegen gekomen. Dit schijnt het enigste snelle teller of timer te zijn binnen windows.
Tijdens mijn korte zoektocht in de code van Tabsels link zag ik deze functie dan ook voorbij schieten.

Ik begin weer goede hoop te krijgen.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
bigbeng schreef op dinsdag 27 juni 2006 @ 09:13:
Wat is het punt dat je hier probeert te maken? Blijkbaar hebben Linux en Windows beide geen realtime in zich. Mogelijk bewust? Het brengt namelijk extra problemen met zich mee voor een OS om multitasking en RT met elkaar te combineren. En omdat het m.i. maar voor een beperkte set applicaties echt van belang is om timings < 10 ms aan te kunnen, kan ik me voorstellen dat een generic multitask oriented OS daar niet in voorziet.
Zelfs als je een busyloop maakt ( mt is dan ook ver te zoeken ) kom je niet aan een timing <1ms. Dat vind ik slecht voor een stuk techniek dat sinds DOS6 'verhonderdvoudigd' is in snelheid. Dat is mijn punt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
Verwijderd schreef op dinsdag 27 juni 2006 @ 22:05:
Deze link zal ik helemaal gaan uitspitten misschien dat ik zo verder komt.

Op internet ben ik iets van QueryPerformanceCounter tegen gekomen. Dit schijnt het enigste snelle teller of timer te zijn binnen windows.
Tijdens mijn korte zoektocht in de code van Tabsels link zag ik deze functie dan ook voorbij schieten.

Ik begin weer goede hoop te krijgen.
Is geen timer maar en soort hoge resolutie GetTickCount. Beter dan in een busyloop krijg je em niet en dat wordt weer niet beter dan 1ms.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-02 21:33
farlane: waarom zou je in een busy loop geen betere granulariteit dan 1 ms kunnen krijgen? Dat lijkt me nu net het hele punt van een busy loop en een goede timer; anders kun je ook wel GetTickCount gebruiken.

Verder is het hele topic typisch voor nauwkeurige timing op non-realtime besturingssystemen: met de standaard system calls krijg je nooit nauwkeurigere timing dan de time slices die het besturingssysteem gebruikt. Voor kleine intervallen ben je dus aangewezen op busy waiting, maar je moet er dan rekening mee houden dat je elk moment onderbroken kan worden, zelfs als je proces hoge prioriteit heeft. In de praktijk kun je dan natuurlijk wel heel dicht bij de gewenste frequentie komen.

Trouwens, wat QueryPerformanceCounter betreft: denk er aan dat het resultaat daarvan uitgedrukt wordt in klokslagen van de processor, maar dat de klokfrequentie niet constant is op moderne systemen. Daar wisselt de processor immers van frequentie als de belasting wijzigt.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:46

Creepy

Tactical Espionage Splatterer

M.b.v. queryperformancecounter maak je gewoon een busyloop. Overigens is er dan prima te timen < 1ms.

Echter garanties geven kan je nooi aangezien je een preemptive multitasking OS draait. Het OS bepaalt wanneer en hoelang je app op de processor draaity. Als applicatie kan je wel je timeslice eerder afgeven (d.m.v. sleep bijv.). De minste tijd die onder Windows NT varianten en Linux nodig voordat je app dan weer aan de beurt is normaal gesproken 10 ms. Dit is een OS design en geen i386 hardware probleem. Er zijn namelijk ook realtime OS'en te vinden die op i386 varianten draaien en waarbij je app wel timers kan gebruiken die sneller zijn dan 10ms.

[ Voor 3% gewijzigd door Creepy op 28-06-2006 16:42 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15-02 11:20
Creepy schreef op woensdag 28 juni 2006 @ 16:41:
M.b.v. queryperformancecounter maak je gewoon een busyloop. Overigens is er dan prima te timen < 1ms.
Klopt, ik was in de war met die keren dat ik geprobeerd heb op us te timen. Het probleem is alleen dat als je deze manier gebruikt om ( zoals de TS wil ) een klok te genereren dat je systeem tijdens die communicatie gewoon stilstaat.
Dit is een OS design en geen i386 hardware probleem. Er zijn namelijk ook realtime OS'en te vinden die op i386 varianten draaien en waarbij je app wel timers kan gebruiken die sneller zijn dan 10ms.
Hmm en hoever gaat dat dan? Kan ik ook op 1us timen zonder dat ik een busyloop gebruik? Naar mijn weten kan je dit soort dingen alleen doen op een hardware interrupt en daar zou je weer speciale hardware voor moeten hebben. Of heeft x86 een hardware interrupt die snel genoeg loopt?

( op wikipedia wordt o.a. vermeld dat de snelste int frequentie die je met de PIT kunt halen ongevee 1MHz is.)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Topicstarter
Ik ga aan de slag met de gegevens die ik nu heb.
Komende week heb ik het druk met andere dingen, dan kan alles even bezinken. Hierna ga ik verder met het probleem.
Wanneer de code is gefabriceerd, zal het resultaat hier een keer verschijnen :) .

Verwijderd

Topicstarter
Ik had belooft om mijn oplossing posten, dus...
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
unsigned int periode, frequentie=5000;
LARGE_INTEGER tijd, tijd2;

/* De waarde voor de timer berekenen */
QueryPerformanceFrequency(&tijd);
periode = tijd.LowPart / frequentie;

/* De huidige waarde van de timer opslaan en
een waarde erbij optellen voor de eerste doorloop */
QueryPerformanceCounter(&tijd);
tijd.QuadPart += periode;

while( voorwaarde ){
    
    /* Doe iets wat niet tijd kritisch is, zoals iets berekenen */
    
    /* Trigger wanneer de tijd om is */
    while( tijd.QuadPart > tijd2.QuadPart ){
        QueryPerformanceCounter(&tijd2);
    }
    
    /* Doe iets wat op direct moet gebeuren.
    Zoals in mijn geval data naar de parallelle poort wegschrijven */
        
    /* De periodetijd erbij optellen */
    tijd.QuadPart += periode;
}

Zoals je ziet stelt het weinig voor. Het is een in deze discusie eerder genoemde busywait loop.

De QueryPreformanceCounter is een teller die ergens in je chipset/cpu zit en de frequentie hiervan kan verschillen per hardware, vandaar QueryPerformanceFrequency. Dit was in mijn geval ongeveer 3,6 MHz.

Let goed op dat je met frequentie de maximale frequentie aangeeft. Het ligt aan windows hoevaak de code uitgevoerd wordt, wat afhankelijk is van de hardware en hoe druk windows het heeft.

Ik hoop dat ik hiermee anderen kan helpen.
Als er nog opmerking over zijn, bv een andere methode, dan hoor ik het graag.
Pagina: 1