Forum: Mikrocontroller und Digitale Elektronik Atmel: Register setzen und rücksetzen


von Mike (Gast)


Lesenswert?

Hallo zusammen, ich habe eine Frage bezüglich der Register.

Im Moment programmiere ich auf einem ATtiny eine LED-Dimmung. Hier gibts 
das Problem, das ganz aus ja nicht realisiert werden kann mit OCR =0x00 
- ein peak bleibt ja.

Ich habe dass jetzt so programmiert, dass bei "Licht aus" die PWM 
abgeschaltet wird und der Port ein normaler I/O ist. Bei Einschalten der 
LED findet dann wieder eine PWM statt.

Timer ist bereits initialisiert (Hier Beispiel Timer 0)
PWM einschalten ganz normal: TCCR0A = (1<<COM0A1)

Aber wie schalte ich in ähnlicher Schreibweise die PWM aus?
Bisher helfe ich mir so:
TCCR0A &= ~(0x80)

jetzt muss ich aber immer in das Datenblatt schauen, an welcher Poition 
COM0A1 ist, damit ich auf 0x80 komme.
Ich möchte aber gerne bei der Schreibweise bleiben, denn dann weiß ich 
auch noch in einem halbe Jahr, dass ich COM0A1 ausschalte und muss nicht 
im Datenblatt schauen was an Position 0x80 ist. Wie gehe ich vor?

a) (0<<COM0A1)?
b) TCCR0A &= ~(1<<COM0A1)?
c) oder ganz anders?

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Mike schrieb:
> b) TCCR0A &= ~(1<<COM0A1)

b) ist richtig.

von spess53 (Gast)


Lesenswert?

Hi

>Im Moment programmiere ich auf einem ATtiny eine LED-Dimmung. Hier gibts
>das Problem, das ganz aus ja nicht realisiert werden kann mit OCR =0x00
>- ein peak bleibt ja.

Nicht ganz deine Frage, aber bei invertierter PWM gibt es keinen Peak.

MfG Spess

von Mike (Gast)


Lesenswert?

spess53 schrieb:
> aber bei invertierter PWM gibt es keinen Peak.

Richtig, aber ich habe logarithmische Tabellen angelegt, die Werte sind 
dort nicht-inverteiert.

von Dominik S. (dasd)


Lesenswert?

Mach dir klar was (1<<COM0A1) bedeutet.

"1" steht für 0b00000001, also eine binäre eins.
"<<" ist eine Schiebeoperation, schiebt eine Zahl also nach links.
"COM0A1" ist eine symbolische Konstante für die Bitnummer, hier also 7.

0b0000001 sieben mal nach links schieben -> es kommt heraus: 0b100000000 
-> gleichbedeutend mit 0x80.

Mit der Erklärung sollte eigentlich auch klar sein, dass b) richtig ist 
und a) keinen Sinn macht. :)

(0<<COM0A1) würde 8 Nullen 7 mal nach links schieben und ist somit immer 
noch 0.

von spess53 (Gast)


Lesenswert?

Hi

>Richtig, aber ich habe logarithmische Tabellen angelegt, die Werte sind
>dort nicht-inverteiert.

Macht es so viel Arbeit das OC-Register mit Top-Tabellenwert zu laden?

MfG Spess

von Peter D. (peda)


Lesenswert?

Mike schrieb:
> Richtig, aber ich habe logarithmische Tabellen angelegt, die Werte sind
> dort nicht-inverteiert.
1
OCR0A = ~wert;

Kostet natürlich einen ganzen CPU-Zyklus Rechenzeit und 2 Byte Code.
Schafft das Dein AVR noch?


Peter

von Mike (Gast)


Lesenswert?

Dominik S. schrieb:
> (0<<COM0A1) würde 8 Nullen 7 mal nach links schieben und ist somit immer
> noch 0.

Aus deiner Erklärung könnte ich es auch so verstehen:
"0" steht für 0b00000000, also eine binäre null.
"<<" ist eine Schiebeoperation, schiebt eine Zahl also nach links.
"COM0A1" ist eine symbolische Konstante für die Bitnummer, hier also 7.

0b0000000 sieben mal nach links schieben -> es kommt heraus: 0b000000000
-> gleichbedeutend mit 0x00.
Schlussfolgerung:
Und somit würde bei eingeschalteter PWM 0x80, "0" geschoben, eine 0x00 
als Ergebnis und somit PWM aus sein.

Jetzt aber noch einmal zu meinem Verständnis:
(1<<COM0A1) bzw. (0<<COM0A1) ändert aber nur das Bit COM0A1, die anderen 
bleiben unberührt.

@Spess:

spess53 schrieb:
> aber bei invertierter PWM gibt es keinen Peak.

spess53 schrieb:
> OC-Register mit Top-Tabellenwert zu laden

Ich lasse diese Überlegung nicht außen vor, aber ich möchte erst mal die 
Antwort von meiner Frage verstehen.
Zu deinem Hinweis:
Das erfordert natürlich eine HW-Änderung, die ich jetzt nicht mehr 
vornehmen kann (Platine ist vorhanden).

von Dietrich L. (dietrichl)


Lesenswert?

Mike schrieb:
> Jetzt aber noch einmal zu meinem Verständnis:
> (1<<COM0A1) bzw. (0<<COM0A1) ändert aber nur das Bit COM0A1, die anderen
> bleiben unberührt.

Aber nur, wenn Du diesen (konstanten) Wert dann "richtig" in das 
Register läds.
Wenn Du im Register sonst nicht verändern willst, muss Du unterscheiden:
- eine "1" musst Du zum Registerinhalt hinzu"ODER"n (|)
- eine "0" musst Du zum Registerinhalt hinzu"UND"en (&)

Gruß Dietrich

von Dominik S. (dasd)


Lesenswert?

Mike schrieb:
> Schlussfolgerung:
> Und somit würde bei eingeschalteter PWM 0x80, "0" geschoben, eine 0x00
> als Ergebnis und somit PWM aus sein.

Ich verstehe leider nicht ganz, was du damit sagen willst.


> Jetzt aber noch einmal zu meinem Verständnis:
> (1<<COM0A1) bzw. (0<<COM0A1) ändert aber nur das Bit COM0A1, die anderen
> bleiben unberührt.

Verstehe ich auch nicht so ganz...
Die beiden Klammern ändern an dem Bit COM0A1 im Register allein noch gar 
nichts.
Die stehen lediglich für (1<<7) bzw. (0<<7), was nach Ausführung wie 
gesagt 0x80 bzw. 0 ergibt.

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.