Hallo,
ich versuche gerade den Pin OC1B am MEGA328 zu bei einem Vergleichswert
in OCR1B zu togglen. Aber ohne Interrupt.
Der Pin macht auch was er soll, nur leider wird nicht auf OCR1B
reagiert. Egal welchen Wert ich einstelle, die Frequenz bleibt immer
dieselbe.
Folgendes habe ich geschrieben:
DDRB |= (1<<PB2);
OCR1B = 0x00FF;
TCCR1B |= (1<<WGM12);
TCCR1B |= (1<<CS12);
TCCR1A |= (1<<COM1B0);
Wie gesagt, der Pin togglet, nur leider unabhängig von OC1B.
Geht es doch nicht ohne Interrupt ?
> Wie gesagt, der Pin togglet, nur leider unabhängig von OC1B.
?
OC1B ist der Pin.
Mit
> TCCR1B |= (1<<WGM12);
wird CTC mit TOP=OCR1A gewählt, also bestimmte OCR1A die Frequenz, wenn
es denn gesetzt wäre; OCR1B legt das Tastverhältnis fest.
> OCR1B legt das Tastverhältnis fest
Das war ein Irrtum von mir, das Tastverhältnis ist ja immer 50 %, der
Wert von OCR1B spielt in diesem Fall eigentlich gar keine Rolle, OCR1A
muss gesetzt werden.
Ich hab es jetzt hinbekommen. Ich musste noch das OCIE1B Bit in TIMSK1
setzen. Und OC1B reagiert wirklich auf OCR1B. Das ist auch in der Grafik
im Anhang gut zu erkennen.
Da gibt es doch einige Ungereimtheiten:
1. Mit dem eingangs gezeigten Programmteil tut sich an OC1B nichts, "der
Pin togglet" eben nicht
2. Was sollte ein gesetztes OCIE1B bewirken ohne globale
Interruptfreigabe?
3. Im Falle einer solchen Freigabe fehlte dann die ISR ("musste auch
keine ISR schreiben"!?)
4. Wenn es sich noch immer um den eingangs gewählten Modus 4 sowie
gesetztes COM1B0 handelt, dann bewirkt ein Ändern von OCR1B nur ein
totales Ein- oder Ausschalten des Signals an OC1B, je nachdem, ob OCR1B
größer oder kleinergleich OCR1A ist.
Handelt es sich vielleicht um eine Arduinoumgebung?
Sebastian S. schrieb:> Ich musste auch keine ISR schreiben bzw.> die globalen Interrupts aktivieren.
Muss man für Interrupts auch nicht.
Aber gehen wir mal durch
1
DDRB|=(1<<PB2);
Hiermit schaltest du den OC1B auf Ausgang.
1
OCR1B=0x00ff;
Hier setzt du den Registerwert auf 255, auch OK.
1
TCR1B|=(1<<WGM12);
Hiermit setzt du den CTC-Mode mit OCR1A als Top-Value...da aber OCR1A
nicht gesetzt wird ist das immer 0, OCR1B wird also nie erreicht.
1
TCCR1B|=(1<<CS12);
Vorteiler des Timers auf 256...ist das auch so gewollt? Immerhin läuft
der Timer damit.
1
TCCR1A|=(1<<COM1B0);
Und damit aktiviert man den Compare Output Mode, in diesem Falle das
Togglen von OC1B, also eigentlich das, was du möchtest.
Aber wie schon gesagt, da OCR1A nicht gesetzt ist ist das 0
(Initialisierungswert) womit OCR1B mit 255 nie erreicht wird, also wirst
du an OC1B auch keinen Effekt sehen.
Du hast auch dann keinen Effekt an OC1B selbst wenn du OCIE1B in TIMSK1
setzen würdest, denn OCR1B ist ja immer noch kleiner als OCR1A womit
OCR1B immer noch nie erreicht wird. Wenn das bei dir jetzt doch einen
Effekt hat, dann nur weil du noch Code bei dir im Quelltext hast, den du
nicht angegeben hast.
M.Köhler schrub:
> Du hast auch dann keinen Effekt an OC1B selbst wenn du OCIE1B in TIMSK1> setzen würdest, denn OCR1B ist ja immer noch kleiner als OCR1A womit> OCR1B immer noch nie erreicht wird.
Wenn OCR1A nicht angerührt wird, steht da "Null" drin. Da aber mit TCNT
verglichen wird, ist bei jedem Überlauf von TCNT und Neubeginn bei Null
die Bedingung erfüllt, daß beide Register gleich sind und OC1A würde
umschalten.
Aber: Die Erfahrung lehrt: Das kann funktionieren, muß aber nicht.
Timereinstellungen sind ein beliebtes Würfelspiel.
Korrupter Interrupter schrieb:> Timereinstellungen sind ein beliebtes Würfelspiel.
Aber nur, wenn man nicht im Datenblatt lesen mag.
Wenn man nach Datenblatt programmiert, dann macht der Timer auch genau
das, was er soll.
Ich hab wirklich nicht mehr Code. Ich habe selbst beim Setzen von OCR1A
keinen Effekt auf OC1B wenn das OCIE1B nicht gesetzt ist. Und in der
Grafik im Anhang ist auch ersichtlich, dass OC1B beim Vergleich mit
OCR1B geschaltet wird. Ich habe selbst an OC1A keinen Effekt wenn ich
alles darauf einstelle.
Sebastian S. schrieb:> Egal welchen Wert ich einstelle, die Frequenz bleibt immer> dieselbe.
Das muß auch so sein, denn OCR1B bestimmt nicht den TOP-Wert des Timers,
sondern nur den Zeitpunkt der Flanke.
Im Datenblatt ist doch einen schöne Tabelle, in welchem Mode welcher
TOP-Wert gültig ist, OCR1B steht da nirgends.
Nur mit Interrupt kann man Perioden erzeugen, die kleiner als der
TOP-Wert sind.
Peter D. schrieb:> Korrupter Interrupter schrieb:>> Timereinstellungen sind ein beliebtes Würfelspiel.>> Aber nur, wenn man nicht im Datenblatt lesen mag.> Wenn man nach Datenblatt programmiert, dann macht der Timer auch genau> das, was er soll.
Das ist doch nicht wahr. Laut oben angeführter Zeichnung aus dem
Datenblatt verhält es sich genau so, wie ich oben schrieb:
Da aber mit TCNT
verglichen wird, ist bei jedem Überlauf von TCNT und Neubeginn bei Null
die Bedingung erfüllt, daß beide Register gleich sind und OC1A würde
umschalten.
Du siehst also: Auch das Lesen des Datenblatts nützt Nichts, wenn sich
Zeichnungen und Tabellen widersprechen.
Die Erfahrung des TO spricht auch dafür.
Korrupter Interrupter schrieb:> Wenn OCR1A nicht angerührt wird, steht da "Null" drin. Da aber mit TCNT> verglichen wird, ist bei jedem Überlauf von TCNT und Neubeginn bei Null> die Bedingung erfüllt, daß beide Register gleich sind und OC1A würde> umschalten.
Hier gehts aber nicht um OC1A sondern um OC1B ;)
Peter D. schrieb:> Nur mit Interrupt kann man Perioden erzeugen, die kleiner als der> TOP-Wert sind.
So schauts aus, das steht auch im Datenblatt, bzw. da steht, dass ohne
Interrupt OCR1A für die Periodendauer verantwortlich ist (vgl. Page 164
ff., Datasheet ATmega328/P)
Korrupter Interrupter schrieb:> Du siehst also: Auch das Lesen des Datenblatts nützt Nichts, wenn sich> Zeichnungen und Tabellen widersprechen.
Wo genau widerspricht sich Zeichnung, Tabelle und Text? Bitte mit
Referenz auf das aktuelle Datenblatt des ATmega328/P. Da könnte man ja
Mikrochip einen Tipp geben ;)
M. K. schrieb:> Korrupter Interrupter schrieb:>> Wenn OCR1A nicht angerührt wird, steht da "Null" drin. Da aber mit TCNT>> verglichen wird, ist bei jedem Überlauf von TCNT und Neubeginn bei Null>> die Bedingung erfüllt, daß beide Register gleich sind und OC1A würde>> umschalten.> Hier gehts aber nicht um OC1A sondern um OC1B ;)
das ist bei OCR1A oder B das Gleiche, wie man in dem angefügten
Bildausschnitt sehen kann: Beide können den Inhalt von TCNT mit ihrem
Inhalt vergleichen und dann das (interne) Bit oder (wenn gesetzt) den
physischen Ausgang schalten.
> Wo genau widerspricht sich Zeichnung, Tabelle und Text? Bitte mit> Referenz auf das aktuelle Datenblatt des ATmega328/P. Da könnte man ja> Mikrochip einen Tipp geben ;)
Siehe oben.
Peter D. schrieb:> Korrupter Interrupter schrieb:>> Siehe oben.>> Was gefällt Dir an dem Bild nicht?> Es stimmt doch alles.
Du mußt Dir schon mal die Mühe machen, ALLES zu lesen -nicht nur
selektiv das, was Dir schön erscheint.
Es geht nicht darum, was mir an dem Bild nicht gefällt. Das Bild
stimmt nämlich mit der Realität überein.
Im Gegensatz zu dem hier:
>> Peter D. schrieb:> Nur mit Interrupt kann man Perioden erzeugen, die kleiner als der> TOP-Wert sind.>> So schauts aus, das steht auch im Datenblatt, bzw. da steht, dass ohne>> Interrupt OCR1A für die Periodendauer verantwortlich ist (vgl. Page 164>> ff., Datasheet ATmega328/P)
Das ist nicht richtig -und das wiederspricht auch der Zeichnung.
Korrupter Interrupter schrieb:> Das ist nicht richtig -und das wiederspricht auch der Zeichnung.
Was stimmt denn daran nicht?
Im CTC-Modus zählt der Timer bis OCR1A (Waveform-Generation Mode 4). Ich
sehe nicht, was da nicht stimmen soll.
An OC1B hat man dann das Signal (ATmega328/P mit 16 MHz Resonator), das
im Anhang gezeigt ist.
Und wie schon gesagt, wenn OCR1B größer OCR1A ist dann tut sich auch an
OC1B nix da ja OCR1B nie erreicht wird. Und das steht auch so im
Datenblatt, ich seh einfach nicht, was da im Datenblatt nicht stimmen
soll.
M.Köhler schrieb:
>Und wie schon gesagt, wenn OCR1B größer OCR1A ist dann tut sich auch an>OC1B nix da ja OCR1B nie erreicht wird. Und das steht auch so im>Datenblatt, ich seh einfach nicht, was da im Datenblatt nicht stimmen>soll.
Doch, tut sich. Wenn man sich das Ganze als Ring vorstellt, dann kommt
OCR1A irgendwann an OCR1B "vorbei", selbst wenn eines davon auf Null
steht.
Auf diese Weise kann man z.B. ein Signal in der Art eines Servotesters
erzeugen, ohne Interrupt und ohne den Kontroller mit irgendwelchen
Rechnereien zu belasten.
Dadurch erklärt sich auch, was der TO selbst feststellte:
> Ich hab wirklich nicht mehr Code. Ich habe selbst beim Setzen von OCR1A> keinen Effekt auf OC1B wenn das OCIE1B nicht gesetzt ist. Und in der> Grafik im Anhang ist auch ersichtlich, dass OC1B beim Vergleich mit> OCR1B geschaltet wird. Ich habe selbst an OC1A keinen Effekt wenn ich> alles darauf einstelle.
Ich belasse es nun dabei. Jeder muß da seine eigenen Erfahrungen
sammeln.
Korrupter Interrupter schrieb:> Doch, tut sich. Wenn man sich das Ganze als Ring vorstellt, dann kommt> OCR1A irgendwann an OCR1B "vorbei", selbst wenn eines davon auf Null> steht.
Nein, eben nicht. Wenn OCR1A < OCR1B ist und man den CTC-Modus mit OCR1A
als Top-Value einstellt dann wird OCR1B nie erreicht wenn OCR1B > OCR1A
ist weil ja der TCNT ständig auf 0 gesetzt wird wenn OCR1A erreicht
wird. Das ist doch der Witz am CTC-Modus: Man muss sich nicht mehr drum
kümmern, dass der Counter zurückgestellt wird.
Korrupter Interrupter schrieb:> Jeder muß da seine eigenen Erfahrungen> sammeln.
Mein Erfahrungen sind, wenn man nach Datenblatt programmiert,
funktioniert es sofort.
Und auch die TOP-Werte für alle 16 Modi stimmen in der Tabelle:
Table 20-6. Waveform Generation Mode Bit Description
M. K. schrieb:>> Doch, tut sich. Wenn man sich das Ganze als Ring vorstellt, dann kommt>> OCR1A irgendwann an OCR1B "vorbei", selbst wenn eines davon auf Null>> steht.>> Nein, eben nicht. Wenn OCR1A < OCR1B ist und man den CTC-Modus mit OCR1A> als Top-Value einstellt dann wird OCR1B nie erreicht wenn OCR1B > OCR1A> ist weil ja der TCNT ständig auf 0 gesetzt wird wenn OCR1A erreicht> wird. Das ist doch der Witz am CTC-Modus: Man muss sich nicht mehr drum> kümmern, dass der Counter zurückgestellt wird.
Ihr habt beide Recht. Nur sprecht ihr nicht vom selben.
Der obere Threat entspricht dann, wenn TOP 255 (8bit) ist.
Der untere Threat entspricht dann, wenn TOP OCR0A ist, d.h., einen Wert
zwischen 0 und 255.
Aber solange TOP auf 255 gesetzt ist, erreicht der Counter IMMER OCR0A
UND OCR0B.
Hoffe das klärt es.
TM F. schrieb:> Aber solange TOP auf 255 gesetzt ist, erreicht der Counter IMMER OCR0A> UND OCR0B.
Richtig, aber der TE hatte ja den Mode 4 gewählt ganz oben und da wird
halt nur bis OCR1A gezählt und wenn OCR1B dann größer OCR1A ist tut sich
halt an OC1B auch nix. Ich bin halt immer noch vom Problem des TEs
ausgegangen.