Forum: Mikrocontroller und Digitale Elektronik Arduino Attiny85 PWM verdoppeln; Prescaler


von Daniel S. (Gast)


Lesenswert?

Hallo,

ich habe mich jetzt ein wenig belesen und bin zu dem Entschluss 
gekommen, das für den Port PB0 der Timer0 zuständig ist.
Genauso wie für die delay zeiten.

Desweiteren habe ich gelesen, das der Register FOC0B im Clock Select 
(CS02,CS01,CS00) mit 64 eingestellt ist.

Wenn ich diesen Clock Select nun auf 8 setze, müsste ich doch auch 8x so 
schnelles PWM bekommen (von ~491Hz auf ~3928Hz) oder habe ich hier einen 
Denkfehler?

Natürlich ist mir bewusst, das die Pausen dann auch nicht meh passen, da 
dies über den gleichen Timer laufen, das wäre für mich aber nicht 
schlimm.

Vorgestellt habe ich es mir mit dem Befehl:
TCCR0B |= (0 << CS02);
TCCR0B |= (1 << CS01);
TCCR0B |= (0 << CS00);

gibt bestimmt auch eine elegantere Lösung diese drei Bits zu setzen.

Kann das so funktionieren oder nicht?
Das Datenblatt habe ich auch versucht zu verstehen:
http://www.atmel.com/images/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf

Seite 80

Vielen Dank

von Thomas E. (thomase)


Lesenswert?

Daniel S. schrieb:
> Wenn ich diesen Clock Select nun auf 8 setze, müsste ich doch auch 8x so
> schnelles PWM bekommen (von ~491Hz auf ~3928Hz) oder habe ich hier einen
> Denkfehler?

Nein, hast du nicht. Das Ding wird dir nicht um die Ohren fliegen, also 
probiers doch einfach aus.

Aber nicht damit:

Daniel S. schrieb:
> TCCR0B |= (0 << CS02);
> TCCR0B |= (1 << CS01);
> TCCR0B |= (0 << CS00);

Daniel S. schrieb:
> gibt bestimmt auch eine elegantere Lösung diese drei Bits zu setzen.

Vor allen Dingen gibt es eine, die auch funktioniert.
Auf 64 steht er ja schon. Da muß nur das CS00-Bit gelöscht werden:

1
 TCCR0B &= (~1 << CS00);


Um ganz sicher zu gehen, kannst du auch alle Bits löschen und das CS01 
neu setzen:
1
TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00));
2
TCCR0B |= (1 << CS01);


Und ganz korrekt, hälst du den Timer an und setzt den Prescaler und den 
Counter zurück:
1
GTCCR |= (1 << TSM) | (1 << PSRSYNC);
2
TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00));
3
TCCR0B |= (1 << CS01);
4
TCNT0 = 0;
5
GTCCR &= ~(1 << TSM);

Dabei wird allerdings Timer1 ebenfalls angehalten.

: Bearbeitet durch User
von lapsus (Gast)


Lesenswert?

Daniel S. schrieb:
> Desweiteren habe ich gelesen, das der Register FOC0B im Clock Select
> (CS02,CS01,CS00) mit 64 eingestellt ist.

Register FOC0B??? ;-)

von Thomas E. (thomase)


Lesenswert?

Thomas E. schrieb:
> GTCCR |= (1 << TSM) | (1 << PSRSYNC);

Das ist für Atmega328.

Für Attiny85:
1
GTCCR |= (1 << TSM) | (1 << PSR0);

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Da muß nur das CS00-Bit gelöscht werden: TCCR0B &= (~1 << CS00);
Da muss die Klammer aber anders hin, sonst geht das schief, wenn CS00 
größer als 0 ist. Denn wenn z.B. CS00=2 ist, dann kommt das dabei raus:
1 ist  0000000000000001
~1 ist 1111111111111110
Und das 2 mal nach links geschoben ist 1111111111111000
Und damit werden dann beim VerUNDden schon 3 Bits manipuliert...  :-o

Mit TCCR0B &= ~(1 << CS00); wird dann erwartungsgemäß nur das gewünschte 
bit verbogen:
1 ist  0000000000000001
das zweimal nach links ist 0000000000000100
und das invertiert ergibt 1111111111111011
womit letztlich nach dem VerUNDen nur 1 Bit manipuliert wird.

von Thomas E. (thomase)


Lesenswert?

Lothar M. schrieb:
> Da muss die Klammer aber anders hin, sonst geht das schief, wenn CS00
> größer als 0 ist.

Kleiner Tippfehler. Gut aufgepasst. Danke.

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.