Forum: Mikrocontroller und Digitale Elektronik Geschwindigkeit ATMega


von Sebastian R. (lange_leitung)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

Ich benutze einen ATMega32U4 um einen Motor anzusteuern. Dabei habe ich 
jetzt aber ein Geschwindigkeitsproblem festgestellt. Ich kann mit der 
Ansteuerfrequenz nicht so hoch gehen, wie ich möchte, weil der ATMega 
irgendwann sein Limit erreicht.
Allerdings muss ich zugeben, dass mir die Parametrierung des ATMega noch 
nicht ganz klar ist. Vielleicht könnt ihr mir da helfen.

Ich habe einen externen Quarz mit 16MHz. In den Projekteigenschaften von 
Eclipse kann ich die "MCU Clock Frequency" einstellen. Ich denke, dass 
das dasselbe ist wie die F_CPU. F_CPU definiere ich im Code nicht; den 
Wert von "MCU Clock Frequency" habe ich auf 2.000.000 (also 2MHz) 
gesetzt. Warum? Weil nur dann die Zeiten, die _delay_ms erzeugt stimmen.

Wenn ich in main nichts mache außer eine LED zu toggeln, erreiche ich 
damit 200kHz. Auch wenn ich "MCU Clock Frequency" auf 16MHz setzte, 
bleibt es bei 200kHz. Aber so wie ich das verstehe, stellt der MCU bzw. 
F_CPU Parameter ja auch nichts ein, sondern sagt dem Code nur, wie der 
Chip konfiguriert ist.

Im Anhang noch das Bild von den Fuses. Das ist die Standardeinstellung, 
weil ich die Unterschiede nicht verstehe. Kann ich damit den Chip 
beschleunigen? Und wie sind die Einträge zu verstehen?

Besten Dank!!
Sebastian

von Falk B. (falk)


Lesenswert?

Sebastian R. schrieb:
> Hallo zusammen.
>
> Ich benutze einen ATMega32U4 um einen Motor anzusteuern. Dabei habe ich
> jetzt aber ein Geschwindigkeitsproblem festgestellt. Ich kann mit der
> Ansteuerfrequenz nicht so hoch gehen, wie ich möchte, weil der ATMega
> irgendwann sein Limit erreicht.

Wirklich? Das Limit (aka Grenze) liegt eher beim Programmierer als der 
Hardware.

> Ich habe einen externen Quarz mit 16MHz. In den Projekteigenschaften von
> Eclipse kann ich die "MCU Clock Frequency" einstellen.
> Ich denke, dass
> das dasselbe ist wie die F_CPU. F_CPU definiere ich im Code nicht; den
> Wert von "MCU Clock Frequency" habe ich auf 2.000.000 (also 2MHz)
> gesetzt. Warum? Weil nur dann die Zeiten, die _delay_ms erzeugt stimmen.

Dann stimmt deine Einstellung in der Hardware nicht, denn 2 MHz ist um 
Faktor 8 zu wenig. Surprise, surprise, es gibt eine DIV8 Fuse 8-0

> Wenn ich in main nichts mache außer eine LED zu toggeln, erreiche ich
> damit 200kHz. Auch wenn ich "MCU Clock Frequency" auf 16MHz setzte,
> bleibt es bei 200kHz. Aber so wie ich das verstehe, stellt der MCU bzw.
> F_CPU Parameter ja auch nichts ein, sondern sagt dem Code nur, wie der
> Chip konfiguriert ist.

Richtig.

> Im Anhang noch das Bild von den Fuses. Das ist die Standardeinstellung,
> weil ich die Unterschiede nicht verstehe. Kann ich damit den Chip
> beschleunigen? Und wie sind die Einträge zu verstehen?

Der Haken bei LOW:CKDIV8 muss weg! Denn damit wird der Quarztakt intern 
durch 8 geteilt!

Siehe AVR Fuses.

von Sebastian R. (lange_leitung)


Lesenswert?

Besten Dank Falk!!! Ich hatte ja gehofft, dass es "nur" so was einfaches 
ist, wovon ich bisher noch nichts wusste.
Jetzt erreiche ich 1,6MHz. Das heißt dann, dass das Toggeln 10 
Rechenschritte benötigt; richtig?

Sebastian

von Falk B. (falk)


Lesenswert?

Sebastian R. schrieb:
> Besten Dank Falk!!! Ich hatte ja gehofft, dass es "nur" so was einfaches
> ist, wovon ich bisher noch nichts wusste.
> Jetzt erreiche ich 1,6MHz. Das heißt dann, dass das Toggeln 10
> Rechenschritte benötigt; richtig?

Diese "Rechenschritte" nennt man CPU-Takte.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Sebastian R. schrieb:
> Das heißt dann, dass das Toggeln 10 Rechenschritte benötigt; richtig?

Schneller (6 Zyklen -> 2,67 MHz) geht es, wenn du per Schreibzugriff auf
das PIN-Register toggelst (s. Datenblatt). Wenn das Tastverhältnis des
Ausgangssignals statt 50% auch 25% sein darf, gehen 2 Toggles in 4
Zyklen -> 4 MHz.

Oder du überlässt das generieren des Signals der Hardware (Timer), dann
sollten bis zu 8 MHz möglich sein.

Wenn das immer noch nicht reicht, kannst du mittels entsprechender
Konfiguration am CLKO-Pin die volle CPU-Frequenz von 16 MHz abgreifen.

: Bearbeitet durch Moderator
von Amateur (Gast)


Lesenswert?

Denk aber daran, dass Du in der Praxis solche Werte noch nicht mal 
annähern erreichst.
Also Deine 1,6 MHz werden sozusagen nur im Leerlauf erreicht.

von H.Joachim S. (crazyhorse)


Lesenswert?

Sebastian R. schrieb:
> Jetzt erreiche ich 1,6MHz. Das heißt dann, dass das Toggeln 10
> Rechenschritte benötigt; richtig?

loop:
sbi x,y //(Schreiben ins PIN-Register)braucht 2 Takte
rjmp loop //auch 2 Takte

also für einen kompletten Zyklus (2x toggeln) 8 Takte

von Yalu X. (yalu) (Moderator)


Lesenswert?

H.Joachim S. schrieb:
> sbi x,y //(Schreiben ins PIN-Register)braucht 2 Takte

Der OUT-Befehl braucht nur 1 Takt. Man muss dazu das zu schreibende
Bitmuster natürlich vorher in ein Datenregister laden.

von Sebastian R. (lange_leitung)


Lesenswert?

Amateur schrieb:
> Denk aber daran, dass Du in der Praxis solche Werte noch nicht mal
> annähern erreichst.
> Also Deine 1,6 MHz werden sozusagen nur im Leerlauf erreicht.

Ja, das hab ich auch gemerkt. Ich hab das Toggeln nur benutzt, um eine 
möglichst einfache Aufgabe zu haben, und damit die max. Frequenz am 
einfachsten zu sehen. Der echte Code ist natürlich deutlich langsamer.

Yalu X. schrieb:
> Oder du überlässt das generieren des Signals der Hardware (Timer), dann
> sollten bis zu 8 MHz möglich sein.
>
> Wenn das immer noch nicht reicht, kannst du mittels entsprechender
> Konfiguration am CLKO-Pin die volle CPU-Frequenz von 16 MHz abgreifen.

Damit meinst Du jetzt aber nur das Toggeln der LED, oder? Für meinen 
echten Code hilft das nix.

von Carsten R. (kaffeetante)


Lesenswert?

Was soll es denn werden? Welche Frequenz brauchst du? Das klingt 
eigentlich sehr nach einer Aufgabe, für die die Timer erfunden wurden. 
Die machen das (größtenteils) an der CPU vorbei.

Für relativ hohe Frequenzen bieten sich Timer im CTC-Mode und Toggle on 
Compare Match an.

von Maxim B. (max182)


Lesenswert?

Sebastian R. schrieb:
> den
> Wert von "MCU Clock Frequency" habe ich auf 2.000.000 (also 2MHz)
> gesetzt. Warum? Weil nur dann die Zeiten, die _delay_ms erzeugt stimmen.

Ich sehe hier ein Problem: eine Def für F_CPU ist gerade für _delay_ms() 
und _delay_us() von Bedeutung.

"As an alternative method, it is possible to pass the
    F_CPU macro down to the compiler from the Makefile."

So steht wahrscheinlich in Makefile F_CPU = 2000000

: Bearbeitet durch User
von Sebastian R. (lange_leitung)


Lesenswert?

Carsten R. schrieb:
> Was soll es denn werden? Welche Frequenz brauchst du? Das klingt
> eigentlich sehr nach einer Aufgabe, für die die Timer erfunden wurden.
> Die machen das (größtenteils) an der CPU vorbei.
>
> Für relativ hohe Frequenzen bieten sich Timer im CTC-Mode und Toggle on
> Compare Match an.

Hallo Carsten.
Den CTC Modus benutze ich schon. Damit erzeuge ich mir das Zeitsignal. 
In main werden dann die Ausgabewerte über SPI rausgegeben. Ich hab eine 
LookUpTable, die ich durchlaufe und die Werte rausgebe. Aber dieser Teil 
des Codes sollte doch eben nicht in die ISR, oder? Die sollte doch so 
kurz wie möglich bleiben.

von OMG (Gast)


Lesenswert?

Sebastian R. schrieb:
> Ich benutze einen ATMega32U4 um einen Motor anzusteuern. Dabei habe ich
> jetzt aber ein Geschwindigkeitsproblem festgestellt.

Ich kann mir einfach nicht vorstellen dass man in diesem
Zusammenhang auf ein Geschwindigkeitsproblem stösst. Ein Motor
ist so ein träges Gebilde dass es vollkommen ausreicht ihn
mit ein paar hundert Hz anzusteuern. Das muss ein ATMega locker
schaffen.

Ich denke das Problem sitzt vor dem Bildschirm und Tastatur.

Eine genaue Dasrtellung des Problems würde helfen, aber zum
Motor und der Art der Ansteuerung haben wir nichts erfahren.

von Sebastian R. (lange_leitung)


Lesenswert?

Maxim B. schrieb:
> So steht wahrscheinlich in Makefile F_CPU = 2000000

Ja, das F-CPU wird schon gesetzt. Das macht das "MCU Clock Frequency". 
Passt also soweit.

von Sebastian R. (lange_leitung)


Lesenswert?

OMG schrieb:
> Eine genaue Dasrtellung des Problems würde helfen, aber zum
> Motor und der Art der Ansteuerung haben wir nichts erfahren.

Ja, das hab ich weggelassen, weil es nicht zum eigentlichen Problem 
gehört, dass der Chip ncoh nicht schnell genug war. Aber wenn man etwas 
weiter greifen möchte, hast Du recht; dann ist es wichtig! Deshalb:

Es ist ein Piezomotor. Der soll mit max. 1500Hz angesteuert werden. Dazu 
kommen dann aber noch die Mikroschritte. Z. B. 128 Mikroschritte und 
schon ist man bei 200kHz.

von Karl M. (Gast)


Lesenswert?

Hallo

Sebastian R. schrieb:
> Es ist ein Piezomotor. Der soll mit max. 1500Hz angesteuert werden. Dazu
> kommen dann aber noch die Mikroschritte. Z. B. 128 Mikroschritte und
> schon ist man bei 200kHz.

Hast Du den vorher mal eine Abschätzung durchgeführt, ob man mit 16*10⁶ 
Hz genügend Takte zur Verfügung hat, die Aufgabenstellung zu lösen?

Man kann ja nur ganzzahlige Taktunterteilungen nutzen.

Warum nicht einen AVR mit 64 MHz I/O Takt nutzen?

von Falk B. (falk)


Lesenswert?

Sebastian R. schrieb:
> Hallo Carsten.
> Den CTC Modus benutze ich schon. Damit erzeuge ich mir das Zeitsignal.
> In main werden dann die Ausgabewerte über SPI rausgegeben. Ich hab eine
> LookUpTable, die ich durchlaufe und die Werte rausgebe. Aber dieser Teil
> des Codes sollte doch eben nicht in die ISR, oder?

Wie soll man das bewerten, wenn man weder deine Schaltung noch deinen 
Quelltext kennt?

> Die sollte doch so
> kurz wie möglich bleiben.

Jain. Das heißt aber NICHT, daß man dort krampfhaft nix machen darf. Es 
gibt ISRs, die viele hundert oder gar tausende Takte benötigen und 
trotzdem wunderbar funktionieren. Es kommt also auf das Gesamtkonzept 
an.

von Sebastian R. (lange_leitung)


Lesenswert?

Karl M. schrieb:
> Hast Du den vorher mal eine Abschätzung durchgeführt, ob man mit 16*10⁶
> Hz genügend Takte zur Verfügung hat, die Aufgabenstellung zu lösen?
>
> Man kann ja nur ganzzahlige Taktunterteilungen nutzen.
>
> Warum nicht einen AVR mit 64 MHz I/O Takt nutzen?

Nur so ganz grob. Weil ich ja nicht weiß / wusste, wieviele Takte für 
andere Dinge verloren gehen.
Aber ich komme jetzt auf eine ganz vernünftige Geschwindigkeit. Wenn ich 
noch mehr Performance brauche, muss ich noch am Code schrauben, oder - 
wie Du schon sagst - einen schnelleren µC nehmen. Danke!

von Wolfgang (Gast)


Lesenswert?

Sebastian R. schrieb:
> Wenn ich noch mehr Performance brauche, muss ich noch am Code schrauben,
> oder - wie Du schon sagst - einen schnelleren µC nehmen. Danke!

Vielleicht kannst du auch die Hardware deines µC benutzen, um dein 
Signal zu erzeugen. Dann müsstest du nur eine neu Aufgabe suchen, um den 
Rechenkern zu beschäftigen. Ob das funktionieren würde, hängt von deiner 
Anwendung ab.

von Sebastian R. (lange_leitung)


Lesenswert?

Danke, Wolfgang. Gib mir bitte mal ein paar Stichworte, was ich da im 
Datenblatt lesen sollte. Damit kenn ich mich noch nicht aus.
Wie gesagt, bisher erzeuge ich mein Signal, indem ich ein fest 
hinterlegtes Array durchlaufe.
Eine neue Beschäftigung fände sich bestimmt. Dann lass ich halt die LED 
wieder blinken! :)

: Bearbeitet durch User
von Christian B. (luckyfu)


Lesenswert?

Das Array kannst du ja weiter nutzen. Schau dir mal die verschiedenen 
PWM generation modes der Timer an. Damit geht das fast wie von selbst. 
im CTC mode kannst du mit einem Comparewert die Frequenz und mit einem 
anderen das Tastverhältnis der PWM einstellen (Achtung: Einen Haken gibt 
es bei der Sache: Die automatische PWM Erzeugung geht nur an bestimmten 
Pins!). evtl musst du die Durchläufe noch zählen und aller x- Durchläufe 
änderst du den comparewert für das Tastverhältnis, mehr ist da nicht zu 
tun. Den Rest macht der Controller komplett autark

: Bearbeitet durch User
von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Auch eine Endlosschleife ist Beschäftigung genug für einen Prozessor.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

im CTC Mode würde ich jetzt nicht ohne Zwang eine PWM erzeugen wollen. 
Dafür gibts schließlich die PWM Modi die das erheblich erleichtern. Man 
ist auch nicht an die Hardware-Timerpins gebunden. Man kann auch jeden x 
beliebigen Pin in der Timer ISR toggeln lassen.

von Falk B. (falk)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> im CTC Mode würde ich jetzt nicht ohne Zwang eine PWM erzeugen wollen.
> Dafür gibts schließlich die PWM Modi die das erheblich erleichtern.

Es gibt PWM+CTC in verschiedenen Modi! Damit hat man sowohl eine 
programmierbare Periodendauer als auch Pulsbreite.

> Man
> ist auch nicht an die Hardware-Timerpins gebunden. Man kann auch jeden x
> beliebigen Pin in der Timer ISR toggeln lassen.

Dann ist es aber keine Hardware-PWM mehr! Und gerade DIE braucht man bei 
höheren PWM-Frequenzen, erst recht, wenn die CPU noch viel zu tun hat. 
Und genau DARUM geht es hier!

von Sebastian R. (lange_leitung)


Lesenswert?

Kann ich mit der Hardware PWM jede Kurve erzeugen? Ich verstehe, dass 
Sinusschwingungen gehen. Ich benötige aber ggfs. eine periodische Kurve, 
die sehr unsinusförmig ist.
Ferner sind die Werte, die ich im Array habe und rausschreibe, 
Eingangswerte für einen DA-Wandler. Die gebe ich ja über SPI raus. Mir 
leuchtet noch nicht ein, wie ich das mit PWM zusammen bringen kann.

von Maxim B. (max182)


Lesenswert?

Sebastian R. schrieb:
> Ferner sind die Werte, die ich im Array habe und rausschreibe,
> Eingangswerte für einen DA-Wandler. Die gebe ich ja über SPI raus. Mir
> leuchtet noch nicht ein, wie ich das mit PWM zusammen bringen kann.

Gleiche Daten nach z.B. OCR1A statt nach SPDR zu schicken. PWM-Frequenz 
sollte sowieso um mehrfaches höher sein als Ausgangsfrequenz, deshalb 
kommt Interferenz kaum in Betracht.

: Bearbeitet durch User
von Atmel Betrüger (Gast)


Lesenswert?

Ich plädiere jetzt schon mal für einen STM32F103 (Bluepill)
oder einen etwas grösseren Buder ....

Wird einem vermutlich viel Kopfzerbrechen ersparen
(und Verarbeitungsgeschwindigkeit bringen), aber einarbeiten
wäre dann die Kehrseite der Medallie ...

von Maxim B. (max182)


Lesenswert?

Atmel Betrüger schrieb:
> Ich plädiere jetzt schon mal für einen STM32F103 (Bluepill)

STM32 ist gut, aber nicht immer und nicht überall. Mit 3,3 Volt gibt es 
Problem, MOSFET direkt zu steuern, und das ist gerade bei Verwendungen 
für Motorregler wichtig. AVR mag etwas langsamer zu sein, dafür aber 
weniger Aufwand für Treiber.

von Stefan F. (Gast)


Lesenswert?

Wenn der ATmega unerwartet um Faktor 8 zu langsam läuft, liegt es daran, 
das man vergessen hat, die CLKDIV8 Fuse zu löschen.

Alternativ kannst du den Prescaler per Software umkonfigurieren, dazu 
dient das Register CLKPR.

von Frank K. (fchk)


Lesenswert?

Maxim B. schrieb:
> Atmel Betrüger schrieb:
>> Ich plädiere jetzt schon mal für einen STM32F103 (Bluepill)
>
> STM32 ist gut, aber nicht immer und nicht überall. Mit 3,3 Volt gibt es
> Problem, MOSFET direkt zu steuern, und das ist gerade bei Verwendungen
> für Motorregler wichtig. AVR mag etwas langsamer zu sein, dafür aber
> weniger Aufwand für Treiber.

Extra dafür hat Microchip dsPICs im Angebot, die mit 70 MHz laufen, 
Motor PWM Einheiten haben und mit 5V IO-Spannung arbeiten. Intern 
arbeiten die Dinger ja alle mit 1.8V oder 2.5V. Und die Versionen mit 28 
Pins gibts auch in SDIP28. Mit reduziertem Takt gehen diese Teile von 
-40 bis +150°C.

https://www.microchip.com/wwwproducts/en/dsPIC33EV256GM102

Und trotz einer um eine Größenordnung höhere Performance ist der Chip 
eher billiger, wenn ich mir auf Digikey oder Mouser die Preise anschaue.

fchk

: Bearbeitet durch User
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.