Hi, ich hab eine Frage bezüglich Timing/ISR etc. pp. Folgendes Problem liegt zu Grunde. Ich habe ein externes Clocksignal mit 106kHz. Nun möchte ich abhängig meiner Daten ein Rechtecktsignal mit 53 kHz erzeugen. Dies sollte möglichst syncron (konstanter Versatz von 3-4us kein Problem) mit steigender Flanke meines externen Clocksignals mit 106kHz sein. Momentan teste ich mein Timing mittels folgenden Code. Die Idee ist bei jeder steigenden Flanke des Clocksignals den Output zu Toggeln und somit einen Art Clockteiler zu bauen. Später soll der Output dann auf HIGH/LOW entsprechend vorgegebenem Bitstrom gesetzt werden. <code> void setup(){ pinMode(13,OUTPUT); attachInterrupt(1,ISR,RISING); } void loop(){ } void ISR(){ PORTB |=!PortB; } </code> Auf dem Oszi (Anhang) lässt sich erkennen das so kein Clockteiler realisiert werden kann. Zum einen driften Output Signal auf Pin 13 und Clock immer weiter auseinander und zum anderen ist der Output länger auf High als auf Low, was ich mir erst recht nicht erklären kann. Meine Befürchtungen momentan sind, dass 106 kHz Input und Test auf steigende Flanke mittels einer ISR einfach zuviel für den guten Arduino ist. Bei einer groben Überschlagsrechnung kam ich aber zu dem Ergebnis das ungefähr 3us-4us für die Bearbeitung der ISR() nötig sind, was mir bei einem 106kHz => 9.44us Signal doch eigentlich noch genügend Luft (~6us) lässt? Kann mir einer sagen wo ich hier den Denkfehler mache? Ist dies überhaupt zu realisieren mit einem Arduino? Grüße JC
Also an sich ist der Ansatz schon richtig. Jetzt ist das beim Arduino Framework halt so, dass da im Hintergrund Software läuft die man nicht kennt. Die könnte zu dem beobachteten Phasenversatz führen.
@ JC (Gast) >zu Grunde. Ich habe ein externes Clocksignal mit 106kHz. Nun möchte ich >abhängig meiner Daten ein Rechtecktsignal mit 53 kHz erzeugen. Wo ist da die Abhängigkeit? >Dies >sollte möglichst syncron (konstanter Versatz von 3-4us kein Problem) mit >steigender Flanke meines externen Clocksignals mit 106kHz sein. Dann nimm ein einfaches Toggle-FlipFlop, 74HC74 ist dein Freund. >Momentan teste ich mein Timing mittels folgenden Code. Die Idee ist bei >jeder steigenden Flanke des Clocksignals den Output zu Toggeln und somit >einen Art Clockteiler zu bauen. Später soll der Output dann auf HIGH/LOW >entsprechend vorgegebenem Bitstrom gesetzt werden. Kann man machen, aber dann bitte in ASM, den mit C wird das nicht sooo schnell. Bei 16 MHz macht der AVR gerade mal 16 Takte/us. >Auf dem Oszi (Anhang) lässt sich erkennen das so kein Clockteiler >realisiert werden kann. Zum einen driften Output Signal auf Pin 13 und >Clock immer weiter auseinander Weil dir die ISR von Timer 0 reinspuckt, der läuft mit 1kHz beim Arduino-Framework. >Kann mir einer sagen wo ich hier den Denkfehler mache? Ist dies >überhaupt zu realisieren mit einem Arduino? Eher nicht.
Wenn externe Hardware erlaubt ist, und du dich nicht vom Arduino Framework trennen möchtest, erfüllt ein externes RS Flipflop den Job. Es teilt die Frequenz und kann über die R und S Eingänge dabei gesteuert werden. Trennst du dich vom Framework, wird die Antwortzeit der ISR auch ohne externe Hardware ausreichen. Übrigens erlauben die moderneren AVR toggeln eines Pins über Schreiben eines Bit ins PIN Register, es würde also ein PINB = (1 << 0); Bit 0 von Port B toggeln.
JC schrieb: > Bei einer groben Überschlagsrechnung kam ich aber zu dem Ergebnis das > ungefähr 3us-4us für die Bearbeitung der ISR() nötig sind, was mir bei > einem 106kHz => 9.44us Signal doch eigentlich noch genügend Luft (~6us) > lässt? Dann guck dir doch mal an, wie dein Interrupt zeitlich liegt, indem du in der ISR am Anfang einen Portpin direkt setzt und am Ende wieder löscht. Außerdem wäre es bei so zeitkritischen Dingen sicher gut, mal einen Blick in der Listfile zu werfen, um zu gucken, was da nebenher so abläuft. Spontan fällt mir der Millisekundentimer vom Arduino Framework ein. Wesentlich zeitunkritischer wäre es mit Hardwareunterstützung, d.h. ein D-Flipflop, das mit deinen 106kHz getaktet wird und vom Arduino am D-Eingang die Daten bekommt.
@ falk die Abhängigkeit besteht dadurch, dass ich später mal nicht simples Toggeln vorhabe, sondern gezielt (anhand meiner berechneten Daten) das Output Signal HIGH/LOW mit einer Dauer von 9,44us (53kHz) setzen möchte. Kann ich Timer0 ausschalten/deaktivieren?
>Kann ich Timer0 ausschalten/deaktivieren?
Ja, musst nur den Prescaler entsprechend auf keinen Takt einstellen.
Wolfgang schrieb: > Dann guck dir doch mal an, wie dein Interrupt zeitlich liegt, indem du > in der ISR am Anfang einen Portpin direkt setzt und am Ende wieder > löscht. Der Pin wird doch schon in der ISR getoggelt - die zeitliche Lage der ISR ist längst klar. Mehr ist da nicht.
Matthias S. schrieb: > Mehr ist da nicht. Dann guck dir mal den erzeugten Assembler-Code an. Irgendwo muss der Jitter doch her kommen. Oder besser, du gehst das Thema direkt in Assembler an. Dann hast du es in der Hand, was genau passiert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.