Forum: Mikrocontroller und Digitale Elektronik ATtiny85: Timer1 CTC und PWM1


von leo (Gast)


Lesenswert?

Hallo,

ich bin derzeit dabei die Programmierung von AVR's zu erlernen und bin 
dementsprechend Anfänger.

Ich hab zuletzt mit dem ATtiny85 rumgespielt und dabei ein 
Verständnisproblem was den Timer/Counter1 betrifft, welcher doch etwas 
anders ist als Timer0 sowie die Timer der ATmega's mit denen ich zu tun 
hatte.

Aus dem Datenblatt des ATtiny85 
(http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf):

- Bit 7 – CTC1 : Clear Timer/Counter on Compare Match
When the CTC1 control bit is set (one), Timer/Counter1 is reset to $00 
in the CPU clock cycle after a compare
match with OCR1C register value. If the control bit is cleared, 
Timer/Counter1 continues counting and is unaffected
by a compare match.

- Bit 6 – PWM1A: Pulse Width Modulator B Enable
When set (one) this bit enables PWM mode based on comparator OCR1B in 
Timer/Counter1 and the counter
value is reset to $00 in the CPU clock cycle after a compare match with 
OCR1C register value.


Beispiel-Code (PWM Output auf Pin1 des ATtiny's):

  // Timer 1
  TCCR1 = _BV (CS11) |_BV (COM1A1) | _BV (PWM1A);  //  clear OC1B on 
compare, Prescaler 2, FastPWM
  OCR1A = 10;                  // duty cycle
  OCR1C = 150;                 // frequency


Was genau passiert, wenn man zusätzlich im TCCR1 Registern das CTC1 Bit 
setzt, da ja schon nach meinem Verständnis das PWM1A Bit das CTC1 
Verhalten beinhaltet? Beziehungsweise für welchen Fall würde man sowohl 
CTC1, als auch PWM1A setzen?

Über jegliche Hilfe, beziehungsweise Hinweise würde ich mich freuen.

Gruß
Leo

von Dennis K. (scarfaceno1)


Lesenswert?

Ich bin mir gerade nicht sicher was du willst...

Deine gezeigte Konfiguration von Timer 1 ist FastPWM. Der CTCMode ist 
eine andere Betriebsart. Es gibt immer mehrere Wege sein Ziel zu 
erreichen.

Du hast aber hier keins genannt.
Ich benutze den CTC Mode um PWM Funktionen zu realisieren, bei denen ich 
bei FastPWM krumme Zahlenin der Perioden / Frequenzberechnung bekomme. 
Einfach aus Bequemlichkeit. Ich finde dort die Parametrierung einfacher.

Einen Fall in dem man beides setzen würde fällt mir jetzt auch nicht 
ein.
Es werden auch andere Register für die Timer Settings genutzt. Ggf ist 
es vom Anwendungsfall abhängig und ob man die Register für irgendetwas 
anderes noch benötigt.
Ich glaube bei deiner Methode mit der Nutzung von PWM1A wird beim 
Rücketzen auch kein Overflow Interrupt ausgelöst, beim CTC Mode schon...

Es muss einfach zur Anwendung passen.

von philipp (Gast)


Lesenswert?

Hallo,

ich hänge mich hier einmal an, da die Frage ja auch noch nicht endgültig 
geklärt zu sein scheint (zumindest für mein Verständnis).

Ich möchte den ATtin85 nutzen, um aus einem analogen 0-4,2V Signal ein 
5V PWM-Signal @ 20KHz mit einem variablen Duty-Cycle zu erzeugen.

Dafür würde ich den Timer 1 mit 64MHz betrieben und als Prescaler den 
Wert 16 wählen. OCR1C bekäme den Wert 199, denn (64MHz / 16) / (199 + 1) 
= 20,48KHz, richtig?

Mit der Map-Funktion würde ich das analoge Eingangs zwischen 0,0 und 
4,2V in einen Duty-Cycle zwischen 0 und 199 umrechnen und mit 
analogWrite() an einem PWM-Pin ausgeben.

Zwei Fragen dazu:

Wäre in meinem Fall der PWM1A oder der CTC1 Betriebsmodus der richtige?
analogWrite setzt in dem Anwedungsfall den Wert für OCR1A, oder?


Danke und Gruß!

Philipp

von Stefan F. (Gast)


Lesenswert?

Das ist anderes Thema, du hättest dafür einen einen Thread eröffnen 
sollen.

Du solltest nicht deine "eigene" Initialisierung des Timers mit 
analogWrite() vom Arduino Framework vermischen. Entweder benutzt du den 
Timer mit Arduino, oder nicht.

von philipp (Gast)


Lesenswert?

Sorry, das nächste mal ein separater Thread.

Also OCR1A = Ergebnis von map(), richtig?

Bleibt die Frage ob PWM1A oder CTC1 für diesen Fall, um auf das 
Kernthema dieses Threads zurück zu kommen?

von Stefan F. (Gast)


Lesenswert?

> Also OCR1A = Ergebnis von map(), richtig?

Klingt plausibel. Warum probierst du es nicht einfach aus? Das geht 
schneller.

> Bleibt die Frage ob PWM1A oder CTC1 für diesen Fall, um auf das
> Kernthema dieses Threads zurück zu kommen?

Weiter oben stand bereits, dass man beide Modi zum Erzeugen von PWM 
Signalen benutzen kann. Wo die feinen Unterschiede sind, liest du am 
Besten mal im Datenblatt des µC nach.

von Dennis K. (scarfaceno1)


Lesenswert?

philipp schrieb:
> Sorry, das nächste mal ein separater Thread.
>
> Also OCR1A = Ergebnis von map(), richtig?
>
> Bleibt die Frage ob PWM1A oder CTC1 für diesen Fall, um auf das
> Kernthema dieses Threads zurück zu kommen?

Ich mache es meistens so:

Wenn ich einfach nur eine x bit PWM benötige mache ich es mit OCRx und 
lasse den Timer immer bis zum Overflow laufen.
Auch wenn ich eine variable Periodendauer haben will kann ich das hier 
machen. Dann setze ich OCR1C für die Periodendauer und OCR1A für das 
toggeln des Pins.
Denn in der Beschreibung von  TCCR1 steht, dass mit OCR1A der PWM Pin 
getoggelt wird und mit OCR1C das Register zu 0 zurückgesetzt wird.

Den CTC kann ich dafür auch nutzen. Hier stelle ich dann den Pin bei 
match auf toggle und generiere mir somit durch setzen des OCR1C 
Registers meinen duty cycle mit jedem togglen neu.

Was ist besser...

Probier beides aus und entscheide welches du besser bedienen kannst oder 
dir besser gefällt.

Von der Laufzeit macht das keinen Unterschied. Unsauber wird es 
höchstens durch deine Art es in Code niederzuschreiben.
Beide Varianten sind absolut üblich und nutzbar.

My Opinion

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.