ATMega / XMega wie möglichst schnelle Takterzeugung genau X mal?

Gast #3094483
Lesenswert?

Hi,
ich habe einen ATMega2561 (alternativ würde ich auch einen XMega 
einsetzen wenn es dort bessere Möglichkeiten gibt) mit 16 Mhz und muss 
genau X mal, möglichst schnell an einem Port ein Taktsignal ausgeben 
(also den Port togglen). X= immer wieder unterschiedlich zwischen 0 und 
5 Millionen

Was wäre da die beste und schnellste Strategie (SPI Clockausgang fällt 
leider flach, denn den brauche ich für was anderes)?

Ideal wäe natürlich ein 16 Mhz Taktausgang oder PWM nur die kann ich 
beide nicht mitzählen um dann den Taktausgang nach X Takten 
abzuschalten. "Normaler" Code ist mir zu langsam (da komme ich 
vielleicht auf 1 Mhz, ich brauche aber mehr).

Was gäbe es noch?

Danke für Eure Ideen

Stefan
Gast #3094511
Lesenswert?

>externe Zählerstufe
Danke, aber a) vermutlich zu teuer und b) habe ich leider keinen Platz 
mehr dafür auf der Platine.

was ich noch vergaß: der Takt muss NICHT über die Anzahl der Takte (X) 
einheitlich rund laufen, wenn zwischendurch mal ein paar ns Pause ist, 
ist das egal (wichtig ist die absolute Zeit in der X Takte ausgeschickt 
werden, wenn der Takt "stolpert", macht das also nix).
Meine SW Lösung z.B. stolpert, da werden bis zu 3 Schleifen (jeweils max 
0-255) ineinandergeschachtelt (alles byteweise zu halten ist immer noch 
am schnellsten) und beim Schleifenüberlauf gibt es eine kurze Pause.


Stefan
Persönliche Seite #3094533
Lesenswert?

A. K. schrieb:
> Mit den Megas ist kein 16MHz Ausgang möglich, weil per Timer mindestens
> halbiert wird.
>
> Es geht allerdings mit den TinyX5, dessen Timer mit 64MHz arbeiten kann.
> Allerdings nur vom internen R/C-Oszillator, nicht quarzgenau.

Das bringt mich auf eine Idee: Man setzt einen 64MHz-Timer so auf, dass 
er ein Signal mit der gewünschten Frequenz erzeugt, zählt die Anzahl der 
Takte mit einem synchronen zweiten Timer (welchen man vielleicht sogar 
mit Input Capture auf den Taktausgang laufen lässt) und lässt diesen 
irgendwann per Output Compare exakt auf die gewünschte Anzahl an Takten 
den Taktausgang durch Anhalten des ersten Timers abstellen. Da ist unter 
Umständen ein wenig Feintuning nötig, aber es dürfte funktionieren.


Gruß
Jonathan
Gast #3094535
Lesenswert?

Die AVRs können zwei Timer ver-multiplexen, üblicherweise Timer 0 und 
Timer 1. Nennt sich output-compare-modulator.

Ob sich allerdings damit der Bereich 0...5 Mio einstellen lässt, weiß 
ich nicht.

Alternativ mitzählen. Das musst du ja nicht für jeden Zählimpuls machen, 
zählen kann der Timer alleine. Du brauchst nur die Überläufe zu zählen, 
um dann im letzten Zyklus per CTC auf deine genaue Zykluszahl zu kommen. 
In der letzten ISR hälstdu den Timer dann an, die Anzahl Takte für den 
Einsprung in die ISR und den out-Befehl ins TCCRB-Register musst du halt 
mit berücksichtigen.

Damit bekommst du F_CPU/2 per PWM hin, mit 20Mhz-Quarz sind das lockere 
10 Mhz.

Oliver
Persönliche Seite #3094546
Lesenswert?

Oliver schrieb:
> Die AVRs können zwei Timer ver-multiplexen, üblicherweise Timer 0 und
> Timer 1. Nennt sich output-compare-modulator.
>
> Ob sich allerdings damit der Bereich 0...5 Mio einstellen lässt, weiß
> ich nicht.
>
> Alternativ mitzählen. Das musst du ja nicht für jeden Zählimpuls machen,
> zählen kann der Timer alleine. Du brauchst nur die Überläufe zu zählen,
> um dann im letzten Zyklus per CTC auf deine genaue Zykluszahl zu kommen.
> In der letzten ISR hälstdu den Timer dann an, die Anzahl Takte für den
> Einsprung in die ISR und den out-Befehl ins TCCRB-Register musst du halt
> mit berücksichtigen.
>
> Damit bekommst du F_CPU/2 per PWM hin, mit 20Mhz-Quarz sind das lockere
> 10 Mhz.
>
> Oliver

Heh, genau das war auch meine Idee zur selben Zeit. Allerdings muss man 
nicht nur den letzten Zyklus per CTC machen, sondern die letzten beiden. 
Falls das Abstellen des Timers nämlich exakt einen Takt nach dem letzten 
regulären Int kommt, hat man das Problem, dass die ISR noch recht lange 
braucht, bis die Ausgabe dann tatsächlich abgestellt ist. Als 
Alternative könnte man bei weniger als 512 verbleibenden Takten einfach 
per Indirektem Sprung in ein NOP-Feld springen, welches dann die 
gewünschte Restverzögerung erzeugt, sodass das Timing immer exakt passt 
und man den Timer nicht noch in den CTC umschalten muss.


Gruß
Jonathan
Gast #3095028
Lesenswert?

Mit einem Xmega geht das Problemlos. Systemtakt auf 32MHz, Mit 
Eventkanal als DMA-Trigger Qelle. Eine Variable mit einem gestzten Bit 
für den zu toggelnden Pin und als Zieladresse das Toggelregister eines 
Ports.
Mit der Einstellung des Transfercounts der DMA ergibt sich das x-mal 
toggeln. fertig. Benötigt nicht mal Prozessorleistung...
#3095359
Lesenswert?

Ja das klingt in der Tat verdächtig danach. Das wäre aber wirklich eine 
Umständliche Lösung. Aber wenn man nur noch ein Pin frei hat... Wobei 
man auch dann noch tricksen könnte, je achdem was genau man 
beabsichtigt, Z. B. etwas in der Art USART oder 1-Wire. Und sei es auch 
nur eine Art Soft-Lösung. Bei mehr als einem Pin oder einem gemeinsamen 
Takt käme noch Soft-SPI in Frage. Wobei es bei den soften Lösungen etwas 
haarig beim THema möglichst schnell und CPU Zeit wird. Ganz nebenbei 
bemerkt:

Wenn das echte SPI nicht permanent kommuniziert, so kann man das 
mehrfach belegen wie ein BUS. Man muß sich dann nur entscheiden wie man 
die Geräte selektiert. Entweder über das Protokoll per Adressübertragung 
oder über ein Chipselekt. Üblich wäre Chipselekt. Aber wir wissen ja 
nicht was dranhängt.

Gruß

Carsten
Gast #3095423
Lesenswert?

Wenn Dir 1/6 der Quarzuhr ausreichen, so kannst Du auch eine Schleife in 
Form von:

Lade Zähler                  0 ... 255
Set Bit in I/O Register      1 Tackzyklus
Dec Zähler                   1 T.
Nop                          1 T.
Clear Bit in I/O Register    1 Tackzyklus
Breq Set_Bit_Befehl          2 T. bei Sprung

Bei 1/10 Tackt kann man auch 65535 Takte ausgeben.
So war’s zumindest anno ATMega16.

Das ist natürlich nur sinnvoll nur wenn Du's eilig hast und nicht noch 
im Hintergrund was machen willst. Sauber und Jitterfrei.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren