Liebe Community, ich versuche gerade PWM bei den AVRs zu verstehen. Bis jetzt habe ich immer nur in Arduino die ``analogWrite()`` funktion benutzt. Was ich bisher verstanden habe ist das Grundprinzip von PWM und dass dies über timer realisiert wird die immer hochzählen bis zu einem bestimmten Wert und dann den Ausgang setzten. \ Meine Fragen: 1. Die meisten AVRs haben aber doch nur wenige Timer/"Timer-Pins". Wie macht es dann der Arduino, dass er zig PWM Ausgänge hat und diese so einfach nur mit einer Funktion ansteuerbar sind? 2. Wie macht ihr das in der Praxis wenn ihr PWM mit einem AVR nutzt? Jedes Mal aufwendig über diese ganzen Register oder gibts da ne einfache, schnelle und übersichtliche Variante? 3. Was genau macht das``analogWrite()``? Setzt das die Register und alles im Hintergrund? Viele Grüße Johannes
:
Bearbeitet durch User
Johannes schrieb: > Wie macht es dann der Arduino, dass er zig PWM Ausgänge hat und diese so > einfach nur mit einer Funktion ansteuerbar sind? Es sind lange nicht alle Pins für PMW-Ausgabe nutzbar. Hier eine Übersicht: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
Johannes schrieb: > dass dies über timer realisiert wird die immer hochzählen bis zu einem > bestimmten Wert und dann den Ausgang setzten. \ Das ist vom eingestellten Modus abhängig. Es gibt auch den Phasecorrect-Mode bei dem der Timer hoch- und wieder runterzählt. Johannes schrieb: > 1. Die meisten AVRs haben aber doch nur wenige Timer/"Timer-Pins". > Wie macht es dann der Arduino, dass er zig PWM Ausgänge hat und diese so > einfach nur mit einer Funktion ansteuerbar sind? Wie viele brauchst du? Man kann auch per Software mehr Pins verwenden; allerdings schlägt sich das auf die allgemeine Performance nieder, da Software-Lösungen - imm Gegensatz zu Hardwarelösungen - immer den Prozessor verwenden > 2. Wie macht ihr das in der Praxis wenn ihr PWM mit einem AVR nutzt? > Jedes Mal aufwendig über diese ganzen Register oder gibts da ne > einfache, schnelle und übersichtliche Variante? Es gibt auch (Online-)Tools zur Berechnung der Einstellungen. Wenn man sich allerdings mit den Beschreibungen im Datenblat auseinandersetzt, würde sich deine erste Frage erledigen. > 3. Was genau macht das``analogWrite()``? Setzt das die Register und > alles im Hintergrund? Sowas kann man dadurch nachvolziehen, indem man sich den Arduino-Quellcode der Timer anguckt.
Rahul D. schrieb: > Sowas kann man dadurch nachvolziehen, indem man sich den > Arduino-Quellcode der Timer anguckt. Ich würde dazu eher in den Quellcode der Funktion analogWrite() in wiring_analog.c gucken oder welche Stelle im Arduino-Quellcode meinst du speziell genau. In wiring_analog.c steht das Setzen der Register für die PWM-Ausgabe. Die Timer müssen natürlich laufen, aber das passiert unabhängig von der PWM-Ausgabe. Beim Arduino Due werden für analogWrite() allerdings bei den Kanälen 0 und 1 direkt die DACs benutzt, so dass PWM und Timer dabei außen vor sind, ist aber natürlich nicht AVR.
:
Bearbeitet durch User
Beitrag #7605641 wurde vom Autor gelöscht.
Veit D. schrieb: > bezieht sich deine Frage auf konkrete Controller? Wenn ja welche? Ne ganz allgemein :)
:
Bearbeitet durch User
Rainer W. schrieb: > Ich würde dazu eher in den Quellcode der Funktion analogWrite() in > wiring_analog.c gucken oder welche Stelle im Arduino-Quellcode meinst du > speziell genau. In wiring_analog.c steht das Setzen der Register für die > PWM-Ausgabe. Die Timer müssen natürlich laufen, aber das passiert > unabhängig von der PWM-Ausgabe. > > Beim Arduino Due werden für analogWrite() allerdings bei den Kanälen 0 > und 1 direkt die DACs benutzt, so dass PWM und Timer dabei außen vor > sind, ist aber natürlich nicht AVR. Johannes schrieb: > Veit D. schrieb: >> bezieht sich deine Frage auf konkrete Controller? Wenn ja welche? > Ne ganz allgemein :) Genau so meinte ich das auch: ganz allgemein.
Johannes schrieb: > Ne ganz allgemein :) Rahul D. schrieb: > ganz allgemein. Dann gibts auch keine konkrete Antwort. Wenn du konkretes Wissen möchtest, dann schaue dir konkrete µC an und auch ihren konkreten Arduino Core.
:
Bearbeitet durch User
Johannes schrieb: > dass dies über timer realisiert wird die immer hochzählen Nein. Es gibt auch TimerModes die rückwärts zählen. Aber unwichtig wenn man noch am Anfang steht. Bestimmte Timer können nur bestimmte Pins erreichen. Will man auch woanders PWM ausgeben, macht man das in Software, per timer-gesteuertem Interrupt. Ganz so hohe Frequenzen wie bei hardware-Timern schafft man dann nicht. Johannes schrieb: > Jedes Mal aufwendig über diese ganzen Register Klar. Kinderkram bei AVR gegenüber echten Prozessoren wie ARM. Johannes schrieb: > Was genau macht dasanalogWrite Schau es dir an https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_analog.c
Arduino F. schrieb: > Dann gibts auch keine konkrete Antwort. > Wenn du konkretes Wissen möchtest, dann schaue dir konkrete µC an und > auch ihren konkreten Arduino Core. Da hast du was falsch zitiert... ich bin durchaus in der Lage, auf einem AVR (, einem STM32 oder demnächst auf einem Pi Pico) eine PWM zu realisieren. ;)
Johannes schrieb: > Veit D. schrieb: >> bezieht sich deine Frage auf konkrete Controller? Wenn ja welche? > Ne ganz allgemein :) Für mich hört sich die Frage ganz klar nach Microchip/Atmel AVRs an. Johannes schrieb: > ich versuche gerade PWM bei den AVRs zu verstehen.
:
Bearbeitet durch User
Rainer W. schrieb: > Johannes schrieb: >> Veit D. schrieb: >>> bezieht sich deine Frage auf konkrete Controller? Wenn ja welche? >> Ne ganz allgemein :) > > Für mich hört sich die Frage ganz klar nach Microchip/Atmel AVRs an. Natürlich bezieht sich die Frage auf Atmel/Microchip. Nur beim Begriff AVR könnten nur die neuen Controllerserien gemeint gewesen sein. Deswegen die Rückfrage.
Johannes schrieb: > Liebe Community, > > ich versuche gerade PWM bei den AVRs zu verstehen. > Bis jetzt habe ich immer nur in Arduino die ``analogWrite()`` funktion > benutzt. > > Was ich bisher verstanden habe ist das Grundprinzip von PWM und dass > dies über timer realisiert wird die immer hochzählen bis zu einem > bestimmten Wert und dann den Ausgang setzten. Genau, der Timer zählt bis zum eingestellten TOP, welches die Periodendauer vorgibt, und wenn der Timerzähler unterwegs an einem eingestellten Compare-Wert (Duty) vorbeikommt passiert irgendwas, was der Anwender konfiguriert hat. Entweder schaltet ein Pin sein Pegel um oder die ISR wir aktiv ... Bei TOP passiert auch irgendwas je nach Timerkonfig. > Meine Fragen: > > 1. Die meisten AVRs haben aber doch nur wenige Timer/"Timer-Pins". > Wie macht es dann der Arduino, dass er zig PWM Ausgänge hat und diese so > einfach nur mit einer Funktion ansteuerbar sind? Es werden möglichst alle Compare Ausgänge eines Timers verwendet und möglichst alle vorhandenen Timer. Ein Timer hat in der Regel, bei den "alten" ATmegas 2 bis 3 eigene Ausgänge OCnx je Timer. Bei den neueren Serien gibt es noch einen Splitmode, dann hat man statt 3 (16-Bit) plötzlich 6 (8-Bit) Compareausgänge zur Verfügung mit einem einzigen Timer. Daran kannste sehen was alles hinter den Kulissen im Arduino Framework abläuft um es dem Anwender so einfach wie möglich zu machen, wenn dieser nur analogWrite() verwenden muss. > 2. Wie macht ihr das in der Praxis wenn ihr PWM mit einem AVR nutzt? > Jedes Mal aufwendig über diese ganzen Register oder gibts da ne > einfache, schnelle und übersichtliche Variante? Es gibt nur die eine Möglichkeit die Register entsprechend zu konfigurieren. Das macht das Arduino Framework so und man muss es selbst auch machen. Egal wie man es macht, man muss immer die Register konfigurieren und ggf. zur Laufzeit ändern. > 3. Was genau macht das analogWrite()? Setzt das die Register und > alles im Hintergrund? Genau. Das Arduino Framework konfiguriert einige Register vor, auch wenn die Hardwareeinheit in dem Moment noch nicht genutzt wird oder nie genutzt wird. Deswegen ist es bspw. wichtig bei eigener Verwendung der Timer alle Register zu nullen bevor man selbst konfiguriert. Ohne Arduino Framework sind alle Register nach Reset genullt bzw. haben die Default Einstellung laut Manual. Mach selbst einmal folgenden Test. Lasse dir von einem Timer deiner Wahl, wovon du weißt das Pins für analogWrite verfügbar sind, alle Registerwerte ausgeben. Danach nutzt du 1x analogWrite und lässt dir erneut alle Registerwerte ausgeben. Wenn du wissen möchtest was beim Arduino Frameworkim Hintergrund passiert, dann: Michael B. schrieb: > https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_analog.c Liegt auch alles auf deinem Rechner im Arduino Installationsverzeichnis.
Johannes schrieb: > 2. Wie macht ihr das in der Praxis wenn ihr PWM mit einem AVR nutzt? > Jedes Mal aufwendig über diese ganzen Register oder gibts da ne > einfache, schnelle und übersichtliche Variante? Man setzt sich einmal gründlich auf Registerebene – z.B. in klassischer C-Sprache unter 'Atmel/Microchip Studio', ATMEGA328P, µC-Datenblatt, Oszilloskop und ohne irgendwelche ArduinoUnterprogramme oder -interrupts im Hintergrund – damit auseinander und fängt dabei mit dem Einfachsten an, beispielsweise Fast-PWM mit einem Kanal/Output. Schritt für Schritt entstehen dann automatisch eine Initialisierungsroutine, die Befehle zum Ein-, Ausschalten oder Ändern der Parameter des Timers, die man wahlweise als eigene Macros oder Unterprogramme schreiben kann, man erstellt quasi eine kleine, eigene Bibliothek – das muss man dann nicht immer wieder neuschreiben, sondern greift in nächsten Projekten auf das schon Vorhandene, Gestestete und Funktionierende zurück – gegebenenfalls mit entsprechenden Anpassungen. Es gibt aber natürlich Leute, die sich dumm anstellen und diese Arbeit bei jedem neuen Projekt immer wieder von vorne anfangen zu machen. Auf der Registerebene sollte man sich von Anfang an die richtige Nomenklatur mit der AND/OR/XOR-Verkettung (Beispiele unten) angewöhnen, nicht mit reinen Zahlen arbeiten, denn das ist auch – sofern nicht gezielt zum Testen gedacht – ziemlich dumm und obendrein noch reine Zeitverschwendung und Zeit ist kostbar, programmtechnisch ist es dann eigentlich auch eine Sackgasse. Bei den AVRs ist das mit den Registern und Peripherie relativ moderat und überschaubar – die STM32 z.B. sollte man sich nicht als absoluter Anfänger am Anfang antun; wenn man das relativ Einfache der AVRs begriffen hat und anzuwenden vermag, kann man später immer noch auf komplexere µController übergehen, sofern jemand dazu gewillt ist und nicht bei den AVRs mental steckenbleibt, was man aber leider auch oft beobachten kann – diese Fraktion meint dann auch naiv und selbstbelügend, mit ihrem AVR alles bauen zu können. Arduino ist übrigens sehr gut für Leute, die nie von einem µC gehört haben, aber mit einem projektmäßig etwas doch „erreichen” möchten; auch für Schüler in der Unter- und Mittelstufe ganz gut geeignet, um erste Erfahrungen mit µC zu sammeln und relativ schnell Ergebnisse für den Unterricht zu haben – eine Ampelschaltung ist so auf µC-Ebene mit Arduinocode in dem Alter zumutbar, mit einem „nackten” µC und auf Registerebene könnte das zu einem Desaster, Frustration und negativer Erfahrung führen. Erfolge – auch kleine – und positive Erfahrungen sind in der Hinsicht für weitere Entwicklungen ausschlaggebend. _
1 | PORTD=(1<<PORTD0)|(1<<PORTD1)|(1<<PORTD2)|(1<<PORTD3)|(1<<PORTD4)|(1<<PORTD5)|(1<<PORTD6)|(1<<PORTD7); |
1 | PORTD=(1<<PORTD7)|(1<<PORTD6)|(1<<PORTD5)|(1<<PORTD4)|(1<<PORTD3)|(1<<PORTD2)|(1<<PORTD1)|(1<<PORTD0); |
1 | TCCR0A=(3<<WGM00)|(3<<COM0B0)|(2<<COM0A0); |
:
Bearbeitet durch User
Johannes schrieb: > 1. Die meisten AVRs haben aber doch nur wenige Timer/"Timer-Pins". > Wie macht es dann der Arduino, dass er zig PWM Ausgänge hat und diese so > einfach nur mit einer Funktion ansteuerbar sind? Du brauchst nicht für jeden PWM-Ausgang einen separaten Timer. Es genügt im Grunde völlig, wenn die Control-Register unterschiedlich sind. Bei Motoren ist häufig aber nicht einmal das nötig ;)
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.