Forum: Mikrocontroller und Digitale Elektronik ATMega / XMega wie möglichst schnelle Takterzeugung genau X mal?


von Stefan (Gast)


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

von Michael A. (Gast)


Lesenswert?

Stefan schrieb:
> Was gäbe es noch?

Externe Zählerstufe (ggf. mit SW-Zähler erweitert) mit Preset und 
"Taktabwürgegatter" bei 0.
Mehr Aufwand, aber deutlich schneller als µC-Takt.

von Stefan (Gast)


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

von (prx) A. K. (prx)


Lesenswert?

Mit den Megas ist m.W. kein 16MHz Ausgang möglich, weil per Timer 
mindestens halbiert wird.

Es geht jedoch mit den TinyX5, deren Timer mit 64MHz arbeiten kann. 
Allerdings nur vom internen RC-Oszillator, also nicht quarzgenau.

von Jonathan S. (joni-st) Benutzerseite


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

von Oliver (Gast)


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

von Michael A. (Gast)


Lesenswert?

Stefan schrieb:
> Danke, aber a) vermutlich zu teuer und b) habe ich leider keinen Platz
> mehr dafür auf der Platine.

a) Ein 74F161 zählt bis 90MHz und kostet 60ct - nicht sooh teuer.
   Da käme aber schon noch mehr dazu
b) Dann geht's so nicht :-(

von Jonathan S. (joni-st) Benutzerseite


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

von Alex (Gast)


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

von Peter D. (peda)


Lesenswert?

Wenn Du mal sagst, was das ganze werden soll, findet man bestimmt eine 
viel einfachere Lösung.

Irgendwie beschleicht mich der Verdacht, Du willst nen Zähler-IC als 
Output-Expander verwenden.

von Carsten R. (kaffeetante)


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

von Basti M. (counterfeiter)


Lesenswert?

Entweder so wie es Alex mit dem XMega macht, oder einfach mal davon 
ausgehen, dass der XMega auch mehr als 1 USART hat mit dem man so etwas 
bereit stellen könnte (auch gern im SPI Mode)... der zur Zeit kleinste 
aus der A Serie hat schon 5 USARTs und kostet 2,50 €

Grüße

Basti

von amateur (Gast)


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.

von amateur (Gast)


Lesenswert?

Sorry: Natürlich brne und nicht breq.

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.