Forum: Mikrocontroller und Digitale Elektronik Toggle OC1B bei Vergleichswert in OCR1B ohne Interrupt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sebastian S. (dualsbiker)


Bewertung
0 lesenswert
nicht lesenswert
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 ?

von TM F. (p_richner)


Bewertung
0 lesenswert
nicht lesenswert
Könntest du mal das ganze Programm reinstellen, so dass man etwas sieht 
und versteht?

Und warum ohne Interrupt?

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> 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.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> 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.

von Sebastian S. (dualsbiker)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian S. schrieb:
> Aber ohne Interrupt.

Sebastian S. schrieb:
> Ich musste noch das OCIE1B Bit in TIMSK1
> setzen.

Also nun doch mit Interrupt.

von Sebastian S. (dualsbiker)


Bewertung
0 lesenswert
nicht lesenswert
Na geht es denn nicht ohne ? Ich musste auch keine ISR schreiben bzw. 
die globalen Interrupts aktivieren.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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?

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Korrupter Interrupter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Sebastian S. (dualsbiker)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Korrupter Interrupter (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von S. Landolt (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Vielleicht ist Sebastian Schulz mit einem kleinen Muster gedient:
1
 int main(void)
2
 {
3
  DDRB = (1<<PB2);
4
  OCR1B = 0;
5
  TIMSK1= 0;
6
  TCCR1A = (1<<COM1B0);
7
  TCCR1B = (1<<WGM12) | (1<<CS12);
8
9
  OCR1A = 50;    // hier die gewuenschte Frequenz an OC1B==B2 einstellen
10
11
 while(1){
12
 }
13
 }

von Sebastian S. (dualsbiker)


Bewertung
0 lesenswert
nicht lesenswert
Habt ihr das auch ausprobiert ?

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ja.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Umgekehrt gefragt: Sie haben doch sicher mein Muster ausprobiert, was 
kam denn dabei heraus?

von M. K. (sylaina)


Bewertung
1 lesenswert
nicht lesenswert
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 ;)

von Korrupter Interrupter (Gast)


Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Korrupter Interrupter schrieb:
> Siehe oben.

Was gefällt Dir an dem Bild nicht?
Es stimmt doch alles.

von Korrupter Interrupter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
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.

von M. K. (sylaina)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab grad mal was runter getippt:
1
int main(void){
2
    DDRB |= (1 << PB2);
3
    OCR1B = 0xff;
4
    OCR1A = 0xffff;
5
    TCCR1A |= (1 << COM1B0);
6
    TCCR1B |= (1 << WGM12)|(1 << CS10);
7
    for(;;){
8
        
9
    }
10
    return 0;
11
}

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.

von Korrupter Interrupter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von M. K. (sylaina)


Bewertung
1 lesenswert
nicht lesenswert
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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
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

von TM F. (p_richner)


Bewertung
0 lesenswert
nicht lesenswert
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.

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.