mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM auf Timer/Counter0 Probleme


Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Würde gerne eine PWM auf PD5 (Atemga168) mit Timer/Counter0 erzeugen, 
aber wenn ich die Funktion PWM_init aufrufe, tut sich an PD5 leider 
nichts.

Was mache ich hier falsch?

// Timer/Counter 0 mit PWM initialisieren und auf PD5 ausgeben
void PWM_setup(void)
{


DDRD |= (1<<PD5); //PWM PIN PD5 als Ausgang setzen

TCCR0A = (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << WGM02) | (1 << CS00);  //Vorteier=1
OCR0A = 125;//Duty-Cycle              //OCR0A als TOP Wert


}

Wäre jemand so nett, mir mal auf die Sprünge zu helfen?

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PD5 hängt vermutlich an OCR0B. Wenn du da keinen Wert reinschreibt, hast 
du kein PWM Signal.

: Bearbeitet durch User
Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja hängt an OCROB.

Aber anders formuliert:
Ich würde dem Timer gerne einen Topwert zuweisen und mit OCRA festlegen, 
bis wo gezählt wird, um einen Duty-Cycle zu erhalten.

Da stelle ich mich scheinbar zu blöd an.


Mit Timer1 hatte ich es folgendermaßen hinbekommen:


DDRB |= (1<<PB1);  //PWM PIN als Ausgang setzen

TCCR1B = (1<<WGM13);  //PWM, Phasen- und Frequnezrichtig mit ICR1 als 
TOP

ICR1 = 500; //Topwert bis wo gezählt wird. 500 für 20kHz PWM
OCR1A = 250;//50% OCR1A gibt den Duty-Cylce vor (ICR1 für 100%)
TCCR1B |= (1<<CS10);  //Vorteiler = 1
TCCR1A = (1<<COM1A1);  //Nicht invertierende PWM auf OC1A (PB1) ausgeben

Würde im Grunde gerne gleiches mit Timer0 hinbekommen, auch wenn dieser 
nur 8Bit hat.

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans R. schrieb:
> Da stelle ich mich scheinbar zu blöd an.

Nö, du hast nur Stefans Kommentar nicht verstanden. Wenn du OC0A mit dem 
Register OCR0A benutzen willst, dann solltest du den Ausgang auf PD6 
aktivieren und da das Signal abgreifen.
Wenn du jedoch unbedingt an PD5 PWM brauchst, dann stellst du die COMnn 
Bits für OC0B ein und setzt die PWM über OCR0B.

Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tut mir leid, wenn ich mich so blöd anstelle, aber ich bekomme es nicht 
hin. Brauche die PWM zwingend auf PD5.

Immerhin,

eine PWM mit 50% Duty-Cycle kommt, wenn ich folgendes mache (wobei das 
natürlich wohl nicht richtig ist)

DDRD |= (1<<PD5);              //PWM PIN PD5 als Ausgang setzen

TCCR0A = (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << WGM02) | (1 << CS00);   //Vorteier=1
//OCR0B = 100;                         //Duty-Cycle


TCCR0A=(1<<COM0B0);

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, wieso kommentierst du die wichtigste Zeile aus? Da wird doch die 
PWM auf OC0B gesetzt. Wenn OC0B auf 0 steht, bekommst du schmale 
Nadelimpulse am Ausgang. Ausserdem hast du dir Phase Correct mit TOP in 
OCR0A ausgesucht. Da musst du jetzt noch den gewünschten Maximalwert des 
Timers in OCR0A schreiben. Siehe Tabelle 15.8 im Datenblatt des Mega328 
von 5/11.

Autor: S. Landolt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Überhaupt betreibt er seinen ATmega168 jetzt in einem 'Reserved'-Modus.

Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt sieht es also so aus, änder allerdings nichts daran als das ich 
weiterhin 50% Duty-Cycle und nicht 25% an PD5 bekomme:

void PWM_init(void)
{
DDRD |= (1<<PD5);                       //PWM PIN PD5 als Ausgang setzen

TCCR0A = (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << WGM02) | (1 << CS00);  //Vorteier=1
OCR0A = 200;        //TOP-Wert
OCR0B = 50;        //Duty-Cycle


TCCR0A=(1<<COM0B0);
}

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Du schreibst

>TCCR0A = (1 << COM0B1) | (1 << WGM00);
...
>TCCR0A=(1<<COM0B0);

MfG Spess

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. Landolt schrieb:
> Überhaupt betreibt er seinen ATmega168 jetzt in einem 'Reserved'-Modus.

Ursprünglich ist ja WGM00 und WGM02 gesetzt, das ist schon Mode 5.

Aber das macht der TE in der letzten Zeile zunichte:

Hans R. schrieb:
> TCCR0A=(1<<COM0B0);

Und damit hat er den o.a. 'Reserved' Mode eingestellt.
@TE: Miss mal ein bisschen, was da so passiert, klingt interessant :-)

Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt unter Waveform Generation, lege ich mit 1<<WGM02 und 
1<<WGM00 den Mode5 fest. D.h. Phasenrichtige PWM mit OCRA als TOP.

Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maththias, dann sag mir doch bitte wie es richtig lauten müsste.

Autor: Hans R. (hansrichter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, hat sich geklärt. Die letzte Zeile war mist ;-)

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans R. schrieb:
> OK, hat sich geklärt. Die letzte Zeile war mist ;-)

So isses. Wenn du nachträglich ein Bit in einem schon besetzten Register 
setzen willst, musst du eben verodern:
TCCR0A |= (1 <<COMOB0);

Siehe auch
https://www.mikrocontroller.net/articles/Bitmanipulation

Autor: Hans Richter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte da doch noch eine Frage,

meiner Vorstellung nach müsste ich ja mit einem 8MHz Quarz ohne 
Vorteiler auf eine eine PWM von (8MHZ / 256) = 31,250kHz bei OCR0A=255 
kommen.




Laut Oszilloskop beträgt diese allerdings nur etwa die Hälfte 
(15784kHz).
Klar, ich kann mir OCR0A runtergehen, dann wirds schneller.

Aber wie ist der Zusammenhang?

Warum ist die volle Frequenz nicht auf meine 8Bit defiert (OCR0A=255)?

Autor: S. Landolt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das noch der Modus 5 von oben? Wenn ja, dann mal im Datenblatt unter 
"15.7.4 Phase correct PWM mode" nachschauen, in "Figure 15-7." läuft der 
Zähler rauf & runter, ergibt den Faktor 2, oder eben die Formel mit f 
OCnxPCPWM.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.