Forum: Mikrocontroller und Digitale Elektronik Atmega 2561 und PWM


von Matthias K. (bartimaeus)


Lesenswert?

Hallo liebe Community,
Ich wende mich mal mit meiner Frage an euch, vielleicht kann mir jemand 
helfen.

Ich möchte mich nicht als blutiger Anfänger bezeichnen, da ich schon das 
ein oder andere Programm auf einem µC zum laufen gebracht hab, aber ich 
bin halt doch nicht so der Crack, der bei allem voll durchsteigt.

Es geht um eine PWM Implementiereung auf einem Atmega2561.
Ich möchte mit dem µC vier Motoren über PWM ansteuern. D.h. ich möchte 
bei jedem einzelnen Motor die Drehzahl unabhängig einstellen können.

Im Datenblatt steht, dass dieser µC 6 PWM Module besitzt.
http://www.atmel.com/devices/atmega2561.aspx?tab=overview
Aber auf welchen Pins kommt das PWM Signal raus? Und wie initialisiere 
ich alle 6 PWM Kanäle, oder in meinem Fall nur 4 Stück davon?

Eine Initialisierung habe ich bereits gefunden:
1
//FAST PWM
2
3
 TCCR0A = (1<<WGM01) | (1<<WGM00) | (1<<COM0A1) | (0<<COM0A0);
4
 TCCR0B = (0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
5
 OCR0A  = 255;

So wie ich den Code verstehe, werden zwei Timer A und B initialisiert, 
die, wenn sie den Wert 255 erreichen, ein Bit umschalten.

Aber an welchem Pin liegt das Signal jetzt an und wie sag ich dem µC, 
dass der Motor nur bei 50% der Drehzahl laufen soll?

Wahrscheinlich klingt die Frage für euch schon sehr Anfängerhaft, aber 
ich komm grad echt nicht weiter. Es ist alles so verwirrend. Ich würde 
mich deshalb freuen, wenn einer von euch Licht ins Dunkel bringen könnte 
:)

P.S.: Suchfunktion benutzt :) Außerdem hab ich mich durch das Datenblatt 
des Atmega2561 gewühlt, aber das ist ein riesiger Informationswulst, den 
ich nicht bewältigen kann...

von spess53 (Gast)


Lesenswert?

Hi

>Im Datenblatt steht, dass dieser µC 6 PWM Module besitzt.

Der ATMega2561 hat 10 PWM-Channel. 4 mit 8-Bit-Timer, 6 mit 16-Bit-Timer

>Aber auf welchen Pins kommt das PWM Signal raus?

Das sind die Pins mit der Funktion OCnX.

>Eine Initialisierung habe ich bereits gefunden:
>//FAST PWM

> TCCR0A = (1<<WGM01) | (1<<WGM00) | (1<<COM0A1) | (0<<COM0A0);
> TCCR0B = (0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
> OCR0A  = 255;

>So wie ich den Code verstehe, werden zwei Timer A und B initialisiert,
>die, wenn sie den Wert 255 erreichen, ein Bit umschalten.

Nein. Da wird eine PWM für Timer0 (8-Bit) initialisiert. Wobei bei 
OCR0A=255 ein Konstanter H Pegel erzeugt wird.
Für den PWM-Kanal B müssen noch die COM0Bn-Bits und OCR0B noch 
initialisiert werden.
Wenn du das gleiche mit Timer2 vom ATMega2561 machst hast du 4 
PWM-Kanäle.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Matthias Kesenheimer schrieb:

> Im Datenblatt steht, dass dieser µC 6 PWM Module besitzt.
> http://www.atmel.com/devices/atmega2561.aspx?tab=overview
> Aber auf welchen Pins kommt das PWM Signal raus? Und wie initialisiere
> ich alle 6 PWM Kanäle, oder in meinem Fall nur 4 Stück davon?
>
> Eine Initialisierung habe ich bereits gefunden:
>
>
1
> //FAST PWM
2
> 
3
>  TCCR0A = (1<<WGM01) | (1<<WGM00) | (1<<COM0A1) | (0<<COM0A0);
4
>  TCCR0B = (0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
5
>  OCR0A  = 255;
6
>
>
> So wie ich den Code verstehe, werden zwei Timer A und B initialisiert,
> die, wenn sie den Wert 255 erreichen, ein Bit umschalten.

Nicht 2 Timer.
Das ist 1 Timer, nämlich Timer 0.
Aber dieser Timer hat 2 Compare Register und kann damit 2 PWM Signale 
erzeugen.

> Aber an welchem Pin liegt das Signal jetzt an und wie sag ich dem µC

an OC0A bzw. OC0B

> dass der Motor nur bei 50% der Drehzahl laufen soll?
>

indem du das OCR0A Register auf den halben Wert stellst, den der Timer 
durchlaufen kann. Ob das dann tatsächlich 50% Drehzahl ergibt, ist eine 
andere Sache. Aber die PWM läuft dann zumindest mal auf 50%.

> Wahrscheinlich klingt die Frage für euch schon sehr Anfängerhaft, aber
> ich komm grad echt nicht weiter. Es ist alles so verwirrend.

Vielleicht wird es besser, wenn du dir mal überlegst, wie das eigentlich 
alles auf Hardwareebene funktioniert. Es ist im Grunde sehr einfach.
FAQ
Letzter Abschnitt: der Timer
Das ist zwar für einen anderen AVR-Typ geschrieben, aber das Prinzip ist 
identisch.

von Matthias K. (bartimaeus)


Lesenswert?

Ah, ok. Vielen Dank jetzt ist es schon ein bisschen klarer geworden.

Der µC Atmega2561 hat wie ich aus dem Datenblatt entnehmen kann 5 Timer, 
mit denen ich insgesamt 10 PWM Signale bereitstellen kann?

Mit dem obigen Beispielcode wird also der Timer0 mit dem Vorteiler und 
Fast_PWM initialisiert.
Und wenn ich jetzt also OCR0A auf 128 setze liegt am Pin OC0A zur Hälfte 
der Zeit eine 1 und zur anderen Hälfte der Zeit eine 0 an.
Genauso wenn ich in Register OCR0B einen bestimmten Wert schreibe liegt 
an Pin OC0B ein entsprechendes Signal an.
Die PWM Signale haben dann eine Auflösung von 8 Bit.
Richtig soweit?

Wenn ich also 4 PWM Signale nutzen möchte benutze ich die Ausgänge
OC0A, OC0B, OC2A, OC2B
oder doch besser
OC0A, OC1A, OC2A, OC3A?
Bei der zweiten Variante "verbrate" ich allerdings 4 unabhängige Timer, 
die ich vielleicht auch anderweitig benutzen könnte. Somit würde sich 
die erste Variante anbieten, oder?

von spess53 (Gast)


Lesenswert?

Hi

>Wenn ich also 4 PWM Signale nutzen möchte benutze ich die Ausgänge
>OC0A, OC0B, OC1A, OC1B
>oder doch besser
>OC0A, OC1A, OC2A, OC3A?

Das kommt auf deine gewünschte Auflösung an. 8-Bit-Timer sind auf 256 
begrenzt. Die 16-Bit-Timer haben fixe Auflösungen von 8/9/10 und 16 Bit 
sowie Modi mit variabler Auflösung.

>Lässt sich OC0A und OC0B Softwaremäßig zusammenlegen, damit ich 16 Bit
>Auflösung habe?

Nein. Aber die Ausstattung mit 16-Bit-Timern ist doch recht üppig.

MfG Spess

von Matthias K. (bartimaeus)


Lesenswert?

OK. Nur um nochmal sicher zu gehen :) und ob ich alles verstanden habe:
Sagen wir mal ich möchte eine 16 Bit Auflösung, dann wähle ich den Timer 
1 und 3 und benutze demnach dann die Ausgänge
OC1A, OC1B, OC3A, OC3B.

Dann kann ich mit
OCR1A, OCR1B, OCR3A, OCR3B
die Werte der einzelnen PWM Signale wählen. Ich kann in diese Register 
(immer OCRnXH und OCRnXL zusammen) jeweils Werte von 0 bis 2^16 - 1 = 
65535 eingeben, stimmt das?
Somit zählen die beiden Zähler von 0 bis 65535 hoch und geben dann 
jeweils ein entsprechendes Signal an den Ports OCnX aus, so wie es die 
Compare Register vorgeben.

von spess53 (Gast)


Lesenswert?

Hi

>Somit zählen die beiden Zähler von 0 bis 65535 hoch und geben dann
>jeweils ein entsprechendes Signal an den Ports OCnX aus, so wie es die
>Compare Register vorgeben.

Vorausgesetzt du konfigurierst das Verhalten der Pins mit den passenden 
COM-Bits in den TCCRxA und setzt die PINs auf Ausgang.

MfG Spess

von Matthias K. (bartimaeus)


Lesenswert?

Ok, vielen Dank für die netten und hilfreichen Antworten!

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.