Forum: Mikrocontroller und Digitale Elektronik Nutzung des Timer0 des ATtiny45 für PWM-Ausgabe UND Timer-Interrupt


von Third E. (third-eye)


Lesenswert?

Hallo Leute,

in Ermangelung eines weiteren Timers muss ich Timer 0 gleichzeitig für 
PWM-Erzeugung als auch für Sprünge in die Timer-ISR nutzen.
Die PWM soll eine Frequenz von ca. 1-10kHz haben (Grundwelle), die ISR 
soll ca. alle 1 bis 20ms aufgerufen werden. Soweit grob das Ziel.

Hier das Datenblatt (complete):
http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

Ich habe beim Einstellen der Register aber noch etwas 
Verständnisprobleme:
Auf was muss ich TCCR0A (S.77) einstellen?

Da ich am liebsten "phase correct" haben möchte, da sich OCR0A ständig 
ändert, steht COM0A1 (S.78) auf 1.

Aber muss ich "Bits 1:0 – WGM0[1:0]: Waveform Generation Mode" dann auf 
Mode 1 oder 5 setzen?

Der Aufruf der ISR (Timer 0 Overflow) soll unabhängig von OCR0A sein.
Geht das?

Wenn nicht, dann habe ich nämlich am Montag ein riesen Problem...!

Danke für Eure Hilfe.
Third-Eye

von Rudolph (Gast)


Lesenswert?

Mach doch in der Overflow-ISR mit OCR0A als TOP (Mode 7) einen Zähler.
Erreicht der einen bestimmten Wert wird der eigentliche Code ausgeführt.

10kHz / 20ms -> 200
1kHz / 1ms -> 1
1kHz / 20ms -> 20

Das on-the-fly zu berechnen dürfte ein wenig trickreich sein, je nachdem 
wie dynamisch die ganze Geschichte werden soll.

von Rolf Magnus (Gast)


Lesenswert?

Im Modus 5 zählt er nur bis zu dem Wert in OCR0A und dann rückwärts 
wieder runter. Das ist also eher nicht so sinnvoll, wenn du an OC0A eine 
PWM haben willst. Im Modus 1 zählt er bis 0xFF.

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Welchen Takt hat der Tiny und was ist jetzt Dein eigentliches Problem ?
Die PWM läuft unabhängig vom Overflow.
Willst Du die PWM für DDS einsetzen oder soll sie einfach nur von 1kHz 
bis 10kHz geregelt werden können ?

von c-hater (Gast)


Lesenswert?

Third Eye schrieb:

> Die PWM soll eine Frequenz von ca. 1-10kHz haben (Grundwelle), die ISR
> soll ca. alle 1 bis 20ms aufgerufen werden. Soweit grob das Ziel.

Das kann nicht nicht funktionieren. Ein Timer kann nur eine Frequenz 
erzeugen, wobei in bestimmten Timermodi allerdings nur die Hälfte der 
Frequenz ausgegeben wird bzw. die doppelte Frequenz als Interruptrate 
auftritt, wie immer man das sehen will.

Das Verhältnis zwischen Interruptraten und Ausgabefrequenz ist also je 
nach Modus und Interrupt immer fix, entweder 1:1 oder 2:1. Was anderes 
geht grundsätzlich nicht.

> Auf was muss ich TCCR0A (S.77) einstellen?

Das kommt drauf an.

> Aber muss ich "Bits 1:0 – WGM0[1:0]: Waveform Generation Mode" dann auf
> Mode 1 oder 5 setzen?

Das kommt drauf an. Nämlich ob du zwei PWM-Kanäle mit voller 
8Bit-Auflösung brauchst und dafür mit einer festgelegten PWM-Frequenz, 
nur über prescaler anpaßbar leben kannst (Mode1) oder ob du unbedingt 
die Frequenz anpaßbar haben mußt, dann hast du nur noch einen PWM-Kanal 
und dieser bietet auch nicht mehr die volle 8Bit-Auflösung (Mode5).

Damit zusammenhängend ändert sich auch die Bedeutung von TCCR0A.
Im Mode5 kontrolliert man damit die Zyklusfrequenz (und dazu gegenläufig 
die Auflösung), deswegen gibt es dann auch nur einen PWM-Kanal.
Im Mode1 hingegen ist die Zyklusfrequenz (minimum) und Auflösung 
(maximum) fest vorgegeben und deswegen steht TCCR0A eben zur Steuerung 
des zweiten PWM-Kanals zur Verfügung.

> Der Aufruf der ISR (Timer 0 Overflow) soll unabhängig von OCR0A sein.
> Geht das?

Nur im Mode 1, denn im Mode5 kontrolliert ja OCR0A die Frequenz des 
Timers.

> Wenn nicht, dann habe ich nämlich am Montag ein riesen Problem...!

Dann lies' das Posting besser erst am Montag. Warum soll man sich den 
Sonntag unnütz versauen?

von Thomas E. (thomase)


Lesenswert?

Third Eye schrieb:
> Hallo Leute,
>
> in Ermangelung eines weiteren Timers muss ich Timer 0 gleichzeitig für
> PWM-Erzeugung als auch für Sprünge in die Timer-ISR nutzen.
> Die PWM soll eine Frequenz von ca. 1-10kHz haben (Grundwelle), die ISR
> soll ca. alle 1 bis 20ms aufgerufen werden. Soweit grob das Ziel.

Wenn es auch ca. 16ms sein dürfen, kannst du den Watchdog als Timer 
verwenden.

mfg.

von Rudolph (Gast)


Lesenswert?

c-hater schrieb:
>> Die PWM soll eine Frequenz von ca. 1-10kHz haben (Grundwelle), die ISR
>> soll ca. alle 1 bis 20ms aufgerufen werden. Soweit grob das Ziel.
>
> Das kann nicht nicht funktionieren.

Stimmt. :-)

Das einzige echte Problem ist doch das die Auflösung der PWM mieserabel 
ist wenn man nur einen 8-Bit Timer hat und OCR0A als TOP für die 
Frequenz manipuliert.
Und die AVR Prescaler sind sowieso gemein grob einstellbar.

Der Tiny44 ist da super, der hat einen 16-Bit Timer.

von Third E. (third-eye)


Lesenswert?

kopfkratzer schrieb:
> *kopfkratz*
> Welchen Takt hat der Tiny und was ist jetzt Dein eigentliches Problem ?
16MHz, die interne PLL wird dafür genutzt.
Mein Problem ist, dass ich die Bedeutung der Register noch nicht so ganz 
verstanden habe.

> Die PWM läuft unabhängig vom Overflow.
> Willst Du die PWM für DDS einsetzen oder soll sie einfach nur von 1kHz
> bis 10kHz geregelt werden können ?
Nein, es soll nichts geregelt werden. Die Frequenz soll fest sein! Da 
habe ich mich vielleicht etwas unklar ausgedrückt.
Der Overflow soll auch einfach in einem festen Zeitintervall 
stattfinden.
Das einzige, was sich laufend ändert, ist der Inhalt von OCR0A.


c-hater schrieb:
>> Aber muss ich "Bits 1:0 – WGM0[1:0]: Waveform Generation Mode" dann auf
>> Mode 1 oder 5 setzen?
>
> Das kommt drauf an. Nämlich ob du zwei PWM-Kanäle mit voller
> 8Bit-Auflösung brauchst und dafür mit einer festgelegten PWM-Frequenz,
> nur über prescaler anpaßbar leben kannst (Mode1)...
Ja, das würde mir reichen!

>
>> Der Aufruf der ISR (Timer 0 Overflow) soll unabhängig von OCR0A sein.
>> Geht das?
>
> Nur im Mode 1, denn im Mode5 kontrolliert ja OCR0A die Frequenz des
> Timers.

Also sollte Mode 1 für mich das Richtige sein, wenn ich jetzt alles 
verstanden habe... Bitte korrigiert mich, wenn ich falsch liege.

Thomas Eckmann schrieb:
> Wenn es auch ca. 16ms sein dürfen, kannst du den Watchdog als Timer
> verwenden.
Das ist auch eine prima Idee! Denn das was in der ISR abläuft, ist nicht 
auf eine hohe zeitliche Genauigkeit angewiesen und der Watchdog wird 
ohnehin von mir nicht genutzt.

Danke für die Hilfe!

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Third Eye schrieb:

> Die Frequenz soll fest sein! Da
> habe ich mich vielleicht etwas unklar ausgedrückt.

Ja, hast du. Mit dieser Information klärt sich die Sache eindeutig.

> Also sollte Mode 1 für mich das Richtige sein

Jepp. Du hast dann zwei PWM-Kanäle, duty factor steuerbar über OCR0A und 
OCR0B, Auflösung fix auf "volle 8 Bit". Du kannst für jeden der beiden 
Kanäle unabhängig bestimmen, ob er überhaupt am zuständigen Pin 
erscheinen soll und wenn ja, ob "direkt" oder "invertiert".

Die PWM-Zyklusfrequenz beider Kanäle entspricht der Frequenz der für 
Timer0 gewählten Taktquelle durch (prescaler factor  256  2).

Der Overflow-Interrupt wird mit genau derselben Frequenz ausgelöst, 
immer dann, wenn der Wert in TCNT0 Null erreicht.

Die Compare-Match Interrupts von OCR0A und OCR0B hingegen werden (nur in 
den meisten Fällen!!!) mit der doppelten Frequenz ausgelöst, sind aber 
auch dabei noch mit einem starken Jitter behaftet, der vom aktuellen 
Wert des jeweiligen Registers abhängt. Sinnvoll nutzbar ist das wohl 
allenfalls dann, wenn die PWM-Modulation nicht allzu sehr um den 
Mittelwert schwankt.

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Timer0 gewählten Taktquelle durch (prescaler factor  256  2).

Oh mein Gott, wie grottenschlecht ist denn diese Boardsoftware...

Es ist doch nun wirklich absolut trivial, zu erkennen, daß hier das 
Asterisk nicht dazu gedacht ist, eine Textformatierung vorzunehmen. Der 
Autor sollte sich mal mit regulären Ausdrücken beschäftigen, damit 
braucht er nämlich nichtmal großartig zu programmieren, um das sinnvoll 
zu implementieren.

Frage: Was soll FETT dargestellt werden und was soll dabei weggelassen 
werden?

Antwort:

"\*\([^ \t].+[^ \t]\)\*"

der Match des gesamten Ausdrucks muß durch \1 (den ersten und einzigen 
geklammerten Teilausdruck) ersetzt und dieser Ersatzwert dann fett 
gedruckt dargestellt werden.

Absolut trivial. Das geht (ggf. mit leicht abgewandelter RE) in 
praktisch jeder üblichen Programmiersprache kinderleicht zu realisieren.

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.