Forum: Mikrocontroller und Digitale Elektronik PWM und Uhr auf einem Counter


von HansMaulwurf (Gast)


Lesenswert?

Hallo,

hab hier ein Projekt, was 5 PWM Kanäle für die Beleuchtung nutzt und ein 
Control Register TCCR2B noch übrig hat. Das ganze geschieht auf einem 
ATmega168. Den Timer des übrigen Registers möchte ich jetzt für eine 
8Bit-Zeitschaltuhr nutzen.
Problem: TCCR2B gehört mit zum TCCR2A und beide nutzen das gleiche Timer 
Control Register "TCCR2A". In dem kann zwischen PWM und "Normal" Mode 
unterschieden werden, jedoch scheint der Modus für beide zu gelten.

Gibts eine Möglichkeit, unabhängig vom anderen den Modus zu ändern bzw. 
den Counter nur bis zum TOP Wert zählen zu lassen ohne das es die PWM 
beeinflusst?

Portsumklemmen kommt leider nicht mehr in Frage, zumindest 
Hardwareseitig, keine Ahnung ob es Softwareseitig geht.

Danke schonmal

von Benjamin U. (utzus)


Lesenswert?

Ich fürchte für eine Konstruktive antwort musst du beschreiben, wie 
deine PWM an diesem Timer funktioniert. Zählst du rauf oder runter?
Denn bis jetzt sehe ich noch keine Möglichkeit das zu ändern. Es läuft 
ja nur ein Timer und wenn du diesen zwecks PWM wieder zurück setzt, dann 
passiert das auch für deine Uhr.

Gib mal ein paar Infos bitte.

Grüße

von HansMaulwurf (Gast)


Lesenswert?

Okay, ich geb erstmal die Konfig an (aus Datenblatt zitiert):
Fast PWM 0xFF BOTTOM MAX (Mode 3; also 255 ist MAX)
Set OC2B on Compare Match, clear OC2B at BOTTOM,(invertiing mode)
Ob hoch oder herunter zählen bin ich grad überfragt, kommentiert hab 
ichs nicht extra im Quellcode, also wohl aufwärts zählend.

Noch ein Register interesant? Also das war eben alles fürs TCCR2A, in 
TCCR2B ist nur das letzte Bit für die Fast PWM vom TCCR2A gesetzt.

Grüße

von Benjamin U. (utzus)


Lesenswert?

Okay,

also dann scheint deine PWM doch so zu funktionieren:

Du fänst bei 0 das zählen an. Dein Ausgang ist LOW.
Nun zählt dein Timer hoch.
Und wenn er den Comparewert trifft, dann setzt er den Ausgang auf HIGH.
Nun zählt er weiter bis 255. Dann fängt er wieder bei 0 an und 'löscht' 
den Ausgang (LOW).
So, dass macht er alles für den Ausgang A also PinB 3.

Du verwendest OCR2A für die PWM oder?

Also zählt dein Timer immer bis 255.
Jetzt kannst du in das zweite Vergleichsregister (OCR2B) deine Uhr 
"implementieren". Du kannst ja beim match einen Interrupt generieren und 
dann ggf. einen neuen Wert in OCR2B schreiben. So, dass jede 
Sekunde/Millisekunde, je nach Frequenz, ein Interrupt generiert wird.

Also so wie ich mir das gerade vorstelle, müsste das machbar sein.

In welcher Sprache programmierst du??

von HansMaulwurf (Gast)


Lesenswert?

Ja, das klingt gut...
OCR2A ist die PWM und OCR2B soll die Uhr werden, also richtig erkannt ;) 
Ich programmiere in gcc.

Wenn ich das Datenblatt richtig verstanden hab, dann ist das Bit OCF2B 
in TIFR2 gesetzt, wenn ein match vorliegt?
Und mit OCIE2B aktiviere ich den Interrupt?
Mehr dazu im Datenblatt (S.157): 
http://www.atmel.com/dyn/products/product_docs.asp?category_id=163&family_id=607&subfamily_id=760&part_id=3303


Habe noch nicht wirklich viel mit den Interrupts gearbeitet.

Danke

von Benjamin U. (utzus)


Lesenswert?

Ja, genau.
Das OCF2B im TIFR2 wird vom Timer gesetzt.
Wenn jetzt noch das OCIE2B im TIMSK2 gesetzt ist und du sei(); (globales 
zulassen von Interrupts) ganz am Anfang ausgeführt hast, dann springt 
der Controller in die Interruptroutine (Vector 9, vgl. S.55):
ISR(TIMER2_COMPB_vect)
{

}

Hierdrinnen musst du nun eben das Vergleichsregister anpassen, so dass 
du auf deine Zeitbasis kommst.

Viel Erfolg.

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.