Forum: Mikrocontroller und Digitale Elektronik Arduino 53 kHz Output Signal


von JC (Gast)


Angehängte Dateien:

Lesenswert?

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

von Sascha_ (Gast)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@ 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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von JC (Gast)


Lesenswert?

@ 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?

von holger (Gast)


Lesenswert?

>Kann ich Timer0 ausschalten/deaktivieren?

Ja, musst nur den Prescaler entsprechend auf keinen Takt einstellen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.