hab nur eine LED Steuerung in HW PWMZitat von orko512
ich habe da mal einige fragen zu pwm und hoffe das mir jemand helfen kann.
1.
ich habe einen atmega128 und habe gelesen das er 6 pwm ports hat.
- nun kann ich aber nirgends finden welche ports das sind
- ich kann nichts darüber finden wie man dann das pwn aktiviert und
entsprechend programmiert
2.
wie kann man pwm softwaretechnisch realisieren. man findet zwar an mehreren stellen code-auszüge doch leider immer nicht ganz vollständig
ich wäre echt dankbar wenn mir jemand weiterhelfen könnte.
vielleicht hat sogar jemand ein code-beispiel. in c.
es muss doch jemand geben der seine motoren über pwm in C ansteuert.
gruß orko
hab nur eine LED Steuerung in HW PWMZitat von orko512
Er hat sogar 8 PWM-Kanäle!
Wenn du mit Ports die Pins des Chips meinst sind das alle die, an denen OCxx dran steht. Steht für Output-Compare.
Zur Programmierung der PWM-Kanäle würde ich dir empfehlen die entsprechenden Seiten im Datenblatt zu sehen. Es kommt schließlich drauf an, welchen Kanal du mit welcher Frequenz und und welcher Auflösung ansteuern willst.
Hier ist ein relativ komplexes Beispiel einer Anwendung des PWM für einen Mega8. entscheidend ist das richtige Setzen der Register TCCR...
Code:#include <avr/io.h> #include <inttypes.h> #include <avr/interrupt.h> #include <avr/signal.h> void pwminit(){ TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10); // WGM* = Fast PWM Mode 14 // CS10 = Prescaler = 1 TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11); // COM* = OC1A/B sind aktiv, bei Comparematsch wird der Ausgang gesetzt bei TOP gelˆscht // WGM* = ICR1 = Obergrenze TIMSK = (1<<TOIE1) | (1<<OCIE1B); // OCIE1B = Output Compare Interrupt Enable 1B // TOIE1 = Timer Overflow Interrupt Enable ICR1 = 200; OCR1B = 100; OCR1A = 0; }; int main(void) { pwminit(); SREG |= (1<<7); DDRB = 0b00111111; DDRC = 0b00111000; DDRD = 0b11111110; PORTB |= ((1<<1) | (1<<0)); for(;;){}; }
MFG Moritz
www.free-webspace.biz/update
hi moritz,
danke für die hinweise.
ich werde mich mit den infos mal ans werk machen und versuchen meine motoren zum laufen zu bekommen.
gruß orko
Hi Orko,
wir können ja mal versuchen das zusammen hinzukriegen.
Also wen ich das richtig verstehe willst du den Hardware-PWM benutzen und keinen interrupt auslösen.
Dann müssten wir klären welche Auflösung 8...10 Bits oder variabel und welche Frequenz du benutzen willlst.
hier mal das Datenblatt:
http://www.atmel.com/dyn/resources/p...ts/doc2467.pdf
Wenn du nichts dagegen hast nehmen wir einfach mal den Timer/Counter0. Der hat eine 8-Bit Auflösung.
OK?
MFG Moritz
www.free-webspace.biz/update
hi rco,
danke für dein angebot.
würde ich gerne in anspruch nehmen.
Hier mal kurz ne beschreibung was ich eigemtlich machen will:
ich möchte meinen robi mit zwei lego-motoren fahren.
diese möchte ich über pwm ansteuern. ich habe inzwischen mal einige versuche mit software pwm gestartet. die laufen auch, aber sind im prinzip nur schleifen in denen ich hochzähle und den ausgang dann setze oder nicht setze.
alles ohne timer und interrupt.
läuft zwar ist aber auf dauer keine gute lösung.
nun habe ich gelesen das es auch hardware pwm gibt, die mein atmega128 unterstützt.
ich habe auch schon danach gegoogelt und auch einige infos gefunden.
leider verstehe ich es trotzdem nicht wie das ganze abläuft.
in den meisten beispielen werden dann irgendwelche register gesetzt.
wofür diese dann jeweils sind, steht leider meist nicht dabei.
klar könnte ich mir ein beispiel nehmen und solange rumdocktorn bis es läuft, ich würde aber gerne verstehen was ich da mache und nicht einfach nur kopieren.
also wenn du lust hättest einen anfänger (der auch auf anhieb nicht immer gleich alles versteht) zu helfen würde ich mich echt freuen.
gruß orko
Hi Orko,
also wenn du zwei Motoren ansteuern willst, dann verwenden wir nicht Timer0, da der nur einen Ausgang hat.
Das siehst du im Datenblatt auf Seite 2 (OC0).
Wir verwenden besser Timer1, dann brauchen wir nur einen Timer.
Wir hätten sogar 3 (OC1A-OC1C) zur Verfügung.
Der Vorteil bei der PWM-Ansteuerung eines Motors ist, dass wir in Sachen Frequenz und Genauigkeit nicht festgelegt sind.
Im folgenden werden wir uns jetzt durchs Datenblatt und durch die Register arbeiten. (Ich hoffe, dein Englisch ist gut )
Ab Seite 111 wird es also interessant. Wobei, da am Anfang erstmal sehr viel über die prinzipielle Funktionsweise geht. Danach noch etwas Assembeler etc. Für uns erstmal nicht interessant. Wenn du Lust hast, kanst du dich da ja mal durcharbeiten.
Der Vorteil des des Hardware-PWMs ist ja, dass außer der Initialisierung keine Rechenzeit verschwendet wird. das ganze läuft vollkommen im Hintergrund.
Auf Seite 135 findest du jetzt erstmal einen Überblick über die möglichen Einstellungen der Timer.
Da wir keine besonderen Ansprüche an den PWM haben, würde ich vorschlagen, dass wir ihn im Mode 5,6 oder 7 betreiben, je nachdem, welche Auflösung du haben willst. Das ist der Fast PWM. Der ist am einfachsten zu erklären.
Was heißt das jetzt:
Der Counter1 zählt mit einer Frequenz, die wir später festlegen, bis zu einer Grenze (entweder 256, 512 oder 1024). Wobei, wenn der Counter bei 256, 512, 1024 ankommt wieder auf Null springt. Das ist ein einfacher Überlauf. Jetzt haben wir 3 Register, in die wir Werte schreiben. Wenn der Counter1 auf einen Zahl = einem der 3 Register kommt, wird ein Ausgang gesetzt oder gelöscht, je nachdem wie wir das noch einstellen.
Der Counter1 Zählt also einfach und vergleicht, ob der Wert, an dem ein Ausgang gesetzt werden soll, schon erreicht ist. Kommt der Counter an seine Obergrenze, so setzt oder löscht er den Zustand des Ausgangs automatisch.
Schau dir am besten mal die Seiten 124 und 125 dazu an.
Timer und PWM beruhen nur auf einem Counter, der immer nach einer bestimmten Zeit seinen Wert inkrementiert.
Bei welcher Frequenz betreibst du den AVR eigentlich?
Ist soweit alles klar? Kommst du mit, sonst stell Fragen.
Wie du siehst, kommst du um das Datenblatt nicht herum.
MFG Moritz
www.free-webspace.biz/update
hi rco,
super von dir. ist ja wie ein online-kurs.
ich fange gleich mal an zu fragen.
sollte ich irgendwo einen fehler machen bitte gleich anmarkern.
>> (Ich hoffe, dein Englisch ist gut)
ob mein englisch reicht???
sieht eher schlecht aus.
>>also wenn du zwei Motoren ansteuern willst, dann verwenden wir nicht
>>Timer0, da der nur einen Ausgang hat.
>>Das siehst du im Datenblatt auf Seite 2 (OC0).
verstehe ich das richtig:
wenn an den pins OC0 steht dann sind die für Timer0?
entsprechend für die anderen TimerX.
danach hätte ich einen
timer0 mit einen ausgang (oc0)
timer1 mit drei ausgängen (oc1a, oc1b, oc1c)
timer2 mit einem ausgang (oc2)
timer3 mit drei ausgängen (oc3a, oc3b, oc3c)
also insgesamt 4 timer.
>>Auf Seite 135 findest du jetzt erstmal einen Überblick über die
>>möglichen Einstellungen der Timer
buh... ganz schön viele infos.
>>Der Counter1 zählt bis zu einer Grenze (entweder 256, 512 oder 1024)
wenn ich das richtig verstehe ist das nun abhängig vom modus.
modus 5 = 8bit = 256
modus 6 = 9bit = 512
modus 7 = 10bit = 1024
in der tabelle61 auf seite 135 steht nun welche bits ich in den timer laden muss damit ich den entsprechenden modus setze.
richtig??????
für modus 7:
WGMn3 = 0
WGMn2(CTCn) = 1
WGMn1(PWMn1) = 1
WGMn0(PWMn0) = 1
das bedeutet = Fast PWM, 10-bit
wie sieht das jetzt softwaretechnisch aus??
ich möcht timer1 benutzen.
er soll in modus 7 betrieben werden.
genau hier hört es jetzt bei mir auf.
ich schaue in das datenblatt und komme nicht weter.
ich finde Timer/Counter1 Control und
Timer/Counter3 Control
gibt es denn mehrere??
nun gleich noch ne frage:
wenn ich mir so einige beispiele anschaue finde ich dort zum setzen des modus folgendes:
TCCR1A|= (1<<WGM10);
TCCR1A|= (1<<WGM11);
TCCR1B|= (1<<WGM12);
TCCR1B|= (1<<WGM13);
warum werden wgm10 und wgm 11 in TCCR1A gesetzt und
wgm12 und wgm13 in TCCR1B ?????
im datenblatt kann ich dazu nichts finden.
>>Wenn der Counter1 auf einen Zahl = einem der 3 Register kommt, wird >>ein Ausgang gesetzt oder gelöscht,
Ist das dann immer der ausgang der zu dem timer gehört???
in meinem fall (OC3A/AIN1) = PE3??
>>Bei welcher Frequenz betreibst du den AVR eigentlich?
mit 4 mhz;start-up time: 6 ck + 64ms
schon kommt die nächte frage:
wo ist der unterschied zwischen 6ck +0ms, 6ck +4ms und 6ck +64ms??
So ich glaube ich mache jetzt hier erstmal schluss und
freue mich schon auf eine antwort.
ich hoffe das du nicht verzweifelst wenn du meine fragen liest.
gruß und ein schönes wochenende
orko
@RCO
Ich hätte auch eine Frage dazu:
ich benutze zwar das Mega2650, aber im Prinzip dürfte das ja das gleiche sein.
Wenn ich z.B. Timer1 nehme, wie kann ich einstellen, welcher Pin (A,B oder C) dann geschalten wird? und wie lege ich für diese Pins einen Vergleichswert fest?
Bene
Genau.Zitat von orko512
Genau, deshalb steht im Datenblatt auch 8 PWM-Channels.Zitat von orko512
Zitat von orko512Genau so gehts. Man kann es allerdings kompakter schreiben:Zitat von orko512
TCCR1A = (1<<WGM11) | (1<<WGM10);
TCCR1B = (1<<WGM12);
Warum? Keine Ahnung. Wo du was setzten muss, findest du aber im Datenblatt (Seite 133 und 136).Zitat von orko512
Es gibt auch noch eine Übersicht auf Seite 365ff.
Genau. Das passiert natürlich nur, wenn die Register so eingestellt sind, dass die Pins gesetzt werden sollen.Zitat von orko512
Vielleicht möchte man ja auch nur einen Interrupt auslösen und den PWM garnicht nutzen.
Was mit den Pins passiert, kann man für OC1A über COM1A1 und COM1A0 einstellen (siehe seite 134).
Das werden wir auch noch machen müssen.
Timer1 und Timer3 werden quasi genau gleich angesteuert.Zitat von orko512
Das kleine n ist dann durch 1 oder 3 zu ersetzen.
Ich weiß leider nicht, was mit 6ck + 64ms gemeint ist. ck steht für cycles, aber sonst...Zitat von orko512
4Mhz ist das Entscheidende.
OK, wenn ich nichts übersehen habe, sollte das hier zur Initialisierung des Timers reichen:
TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0);
TCCR1B = (1<<WGM12) | (1<<CS11);
OCR1AH = 0;
OCR1AL = 128;
OCR1BH = 0;
OCR1BL = 128;
WGM setzt den entsprechenden Modus (10-Bit Fast-PWM), COM regelt das Setzen/Löschen der Pins:
"Set OCnA/OCnB/OCnC on compare match, clear OCnA/OCnB/OCnC at BOTTOM, (inverting mode)"
CS regelt den Prescaler. Hier ist nur CS11 gesetzt. Aus der Tabelle auf Seite 137 entnehmen mir nun,
dass CS11 bedeutet, dass der Takt durch 8 geteilt wird.
==> 4 Mhz / 8 = 500 kHz
Der Timer wird allso alle 1/500k s erhöht.
Da der Timer auf 10 Bit (1024) gesetzt ist, ergibt sich eine Frequenz von 500k/1024 Hz (=488,28... Hz).
Mit welcher Frequenz du einen Motor am besten ansteuert weiß ich leider nicht.
OCR setzt den Wert an dem der Ausgang gesetzt wird. Der "inverting mode" eignet sich eignetlich nicht so gut für deinen Zweck,
war aber einfacher als Erklärung.
OK, soweit alles klar?
@Bene: Ich hoffe, dass das was ich oben geschrieben hat dir weiterhilft.
MFG Moritz
www.free-webspace.biz/update
Lesezeichen