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
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.
>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
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.
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
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
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 :-(
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
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...
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.
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
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.