Forum: Mikrocontroller und Digitale Elektronik ATmega88 Timer1, OCR1A, OCR1B


von Holler (Gast)


Lesenswert?

Hallo zusammen,

ich nutze beim ATmega88 den Timer1 als Waveform-Generator im CTC-Mode 
(Clear Timer on Compare) mit OCR1A als TOP-Wert und am Pin OC1B nehme 
ich das Signal ab.
Funktioniert gut, das Rechteck auf dem Oszi entspricht der Erwartung.

Das Problem:
Bei Erreichen des Zählerwertes OCR1B, der kleiner als OCR1A ist, soll 
ein Interrupt ausgelöst werden. Der Interrupt kommt auch, aber erst bei 
OCR1A: d.h. wenn der Zähler löscht und von vorn anfängt.

Warum wird OCR1B ignoriert? Ich dachte dass das zweite Output-Compare 
Register sich dafür eignet?

Codeauszug:

; 16 Bit Timer/Counter 1 Initialisierung für das Signal

ldi temp, 0b00010000 ; Toggle OC1B on compare match
sts TCCR1A,temp
ldi temp, 0b00001001 ; CTC mit OCR1A als TOP-Wert, ohne prescale
sts TCCR1B,temp
ldi temp, 0x7F       ; Der Umschaltwert des 16 Bit Timers
ldi temp2,0
sts OCR1AH, temp2
sts OCR1AL, temp
ldi temp, 0x70       ; Interrupt kurz vor der Flanke zum Abtasten
sts OCR1BH, temp2
sts OCR1BL, temp
ldi temp, 0b00000100 ; Bit 2 OCIE1B: Timer/Counter1 Output Compare
sts TIMSK1,temp

; Zur Kontrolle mit dem Oszi die LED kurz ein/aus

OC1B_ISR:
in  save_sreg, SREG
sbi PORTB,LED1
cbi PORTB,LED1
out SREG, save_sreg
reti

Die LED im Interrupt wird immer kurz nach dem Flankenwechsel geschaltet, 
leider unabhängig von OCR1B.

Vielleicht bringe ich den Output-Compare Pin B mit dem Output-Compare B 
Register durcheinander, aber nach meiner Interpretation des Datenblatts 
werden Compare-Register und Pin separat gesteuert.

von Karl H. (kbuchegg)


Lesenswert?

Holler schrieb:

> Vielleicht bringe ich den Output-Compare Pin B mit dem Output-Compare B
> Register durcheinander, aber nach meiner Interpretation des Datenblatts
> werden Compare-Register und Pin separat gesteuert.

Schon.
Aber du schaltest (laut Kommentar) den OC1B Pin. Und der hängt vom nun 
mal nur vom OCR1B Compare Match ab.
D.h. was du am Oszi maximal siehst, ist die Zeitverzögerung vom 
Auftreten des B-Compare Match (der den OC1B Pin toggelt) bis du dann in 
der ISR landest, in der du den LED Pin toggelst.

von Karl H. (kbuchegg)


Lesenswert?

> ldi temp, 0b00000100 ; Bit 2 OCIE1B: Timer/Counter1 Output Compare

Mach doch nicht so einen Scheiss.
Wenn du OCIE1B setzen willst, dann schreib das als

   ldi temp, 1<<OCIE1B ; OCIE1B: Timer/Counter1 Output Compare

ist eine Information weniger, die falsch sein kann. Bei dir muss ich 
erst recht wieder kontrollieren, ob OCIE1B tatsächlich das Bit 2 ist. So 
muss ich nur darauf aufpassen, ob OCIE1B tatsächlich im Register TIMSK1 
ist.

von Karl H. (kbuchegg)


Lesenswert?

> Warum wird OCR1B ignoriert?

Die Pulse an der LED beweisen, dass er nicht ignoriert wird.
Du hast irgendwo einen Denkfehler.

Was siehst du am Oszi und was hättest du erwartet das du siehst?

An deinem Code kann ich nicht erkennen, wie du diese Behauptung
> Der Interrupt kommt auch, aber erst bei OCR1A: d.h. wenn der
> Zähler löscht und von vorn anfängt.
überprüfen könntest. Wenn der OCR1A auslöst, siehst du das nicht (es sei 
denn der Kommentar
   ldi temp, 0b00010000 ; Toggle OC1B on compare match
ist falsch. Ich hab jetzt aber ehrlich gesagt keine Lust mir im 
Datenblatt rauszusuchen, wie das Bit an dieser Position heißt und ob das 
zu A oder B gehört. Schreib nächstes mal den Bitnamen hin, dann braucht 
man nicht im Datenblatt suchen.

von Holler (Gast)


Lesenswert?

Nein, das Toggeln des Pins ist im CTC-Mode ausschlieslich vom Wert im 
OCR1A abhängig. Da hat OCR1B keinen Einfluß.

Welcher Pin dann toggelt steht im TCCR1A, Bit COM1A1, COM1B1, COM1A0, 
COM1B0.
Ich habe nur COM1B0 gesetzt, das führt zum Toggeln des Pins OC1B.

von Stefan E. (sternst)


Lesenswert?

Holler schrieb:
> Nein, das Toggeln des Pins ist im CTC-Mode ausschlieslich vom Wert im
> OCR1A abhängig. Da hat OCR1B keinen Einfluß.

Sorry, aber das ist Unsinn. Der Pin OC1A reagiert bei Timer=OCR1A und 
der Pin OC1B reagiert bei Timer=OCR1B, egal welchen Modus du einstellst.

von Holler (Gast)


Angehängte Dateien:

Lesenswert?

Sicher muss der Fehler irgendwo liegen. Aber der B-Pin toggelt ganz 
sicher in Abhängigkeit von OCR1A. Natürlich kann man das auch auf den 
A-Pin mappen, muss man aber nicht.
Und der CTC-Mode geht meiner Meinung nach nur mit Steuerung über OCR1A, 
siehe angehängten Datenblattauszug.

Wie schon gesagt, der OC1B toggelt perfekt. Mit OCR1A kann ich dessen 
Frequenz einstellen.

Wo es klemmt, ist ein Interrupt zum Zeitpunkt bevor der Zähler OCR1A 
erreicht. Das wollte ich mit OCR1B auslösen, klappt aber nicht. Der 
ausgelöste Interrupt hat nichts mit dem Wert in dem Register zu tun.

@ Karl Heinz Buchegger:
sorry für die Bitmaps, werde zukünftig sowas wie  ldi temp, 1<<OCIE1B 
schreiben.

von Karl H. (kbuchegg)


Lesenswert?

Holler schrieb:
> Sicher muss der Fehler irgendwo liegen. Aber der B-Pin toggelt ganz
> sicher in Abhängigkeit von OCR1A.

Lies es von unseren Lippen ab.

Ganz sicher NICHT


Es ist eigentlich ganz einfach:
Alle Dinge mit einem B drinnen gehören zusammen und bilden eine Einheit.
Alle Dinge mit einem A drinnen gehören zusammen und bilden eine Einheit.

Es gibt da keine kanalübergreifende Funktionalität.


> Und der CTC-Mode geht meiner Meinung nach nur mit Steuerung
> über OCR1A, siehe angehängten Datenblattauszug.

Das stimmt schon. Aber den OC1B Pin interessiert OCR1A nicht. (bzw. nur 
indirekt)

> Mit OCR1A kann ich dessen Frequenz einstellen.

Logisch kannst du das. Denn die Frequenz hängt aussschlisslich von OCR1A 
ab. Mit dem Compare Match in B kannst du eine Phasenverschiebung 
erreichen. Mehr aber auch nicht. Da du aber am OC1B nicht ablesen 
kannst, wann der Timer auf 0 zurückgesetzt wurde, hast du auch keinen 
Bezug für einen eventuellen Phasenversatz. Ergo bleibt nur die 
Frequenzänderung über OCR1A übrig.

von Karl H. (kbuchegg)


Lesenswert?

Analogie: Uhr
Deine Uhr tickt im Sekundentakt

in OCR1A steht 59 drinnen. d.h. dein Timer (Uhr) zählt von 0 bis 59 
(also 1 Minute lang.

in OCR1B steht 15 drinnen. D.h. in jeder Minute, zur Sekunde 15, wird 
der Pin getoggelt. Schreibst du in OCR1B eine 28 rein, dann wird zur 
Sekunde 28 der Pin getoggelt.
Aber: Von einem Toggeln zum nächsten vergeht nach wie vor 1 Minute. Denn 
dieser Zeitraum ist nicht von OCR1B abhängig. Der wird aussschliesslich 
von OCR1A (= den 59) gesteuert. Mit OCR1B kannst du den Zeitpunkt 
innerhalb dieser Minute festlegen, wann der Pin toggeln soll, aber nicht 
seine Frequenz.

D.h. von aussen gesehen, wenn du nicht weißt, wann die Uhr ihr 60 
erreicht hat und zurück gesetzt wird, siehst du an OC1B nur Pulse, die 
in 1 Minuten Intervallen kommen. Du hast keinen Bezug zu 0. Du müsstest 
dir den OC1A Pin freischalten um diesen 0-Bezug zu kriegen. Dann kannst 
du durch vergleich von OC1A und OC1B auch feststellen, zu welchem 
Zeitpunkt innerhalb der (durch OCR1A eingestellten) Minute der 
B-Interrupt kommt und der Pin getoggelt wird.

von Holler (Gast)


Angehängte Dateien:

Lesenswert?

Es könnte ja so einfach sein: warum habe ich nicht einfach den Pin 13, 
also OC1A angelötet. Hab aber nun mal Pin 14 genommen, der heisst OC1B.
Habe gerade nochmal kontrolliert. Hier ist (leider) kein Fehler.

Anbei das Oszi-Bild: der Kanal 1 (gelb) hängt an OC1B, Kanal 2 (blau) an 
der LED der Interruptroutine: kann an OCR1B soviel drehen wie ich will, 
nichts verändert sich.

Die Frequenz des Signal ist plausibel:
Fsig = CPUclk / OCR1A = 128 kHz / 255 = 500 Hz.

Der AVR läuft im extrem-Stromsparmode mit nur 128 kHz.

von Stefan E. (sternst)


Lesenswert?

Holler schrieb:
> Anbei das Oszi-Bild: der Kanal 1 (gelb) hängt an OC1B, Kanal 2 (blau) an
> der LED der Interruptroutine: kann an OCR1B soviel drehen wie ich will,
> nichts verändert sich.

Wenn du eine Veränderung sehen willst, dann ändere den Interrupt von B 
nach A. Dann siehst du, wie sich durch Verändern von OCR1B die Signale 
zueinander verschieben.

von Holler (Gast)


Lesenswert?

@ Karl Heinz Buchegger
Ich denke mal über die Analogie zur Uhr nach, aber heute schaffe ich das 
nicht mehr.
Morgen Abend geht es weiter.
Vielen Dank erst mal!

von Karl H. (kbuchegg)


Lesenswert?

Holler schrieb:
> Es könnte ja so einfach sein: warum habe ich nicht einfach den Pin 13,
> also OC1A angelötet. Hab aber nun mal Pin 14 genommen, der heisst OC1B.
> Habe gerade nochmal kontrolliert. Hier ist (leider) kein Fehler.

Der Fehler ist in deinem Kopf.
Mit diesem Setup ist auch nicht zu erwarten, dass sich irgendwas am 
Verhältnis der beiden Signale verändert. Deine Erwartungshaltung ist 
falsch.
Das Oszi Bild spiegelt genau das wieder, was zu erwarten ist. Die blauen 
Pulse hängen zeitlich ein wenig hinter den gelben Flanken nach. Das ist 
der Zeitversatz, der vom Auftreten des Interrupts bis zum Anspringen der 
ISR und abarbeiten des Codes bis zum LED-Pintoggeln vergeht. Aber: Alle 
beiden Ereignisse sind an OCR1B gekoppelt (und indirekt an OCR1A, dieses 
Register steuert aber nur die Wiederholfrequnz. Mit einem zeitlichen 
Versatz der beiden Signale hat es nichts zu tun).

von Holler (Gast)


Angehängte Dateien:

Lesenswert?

Stefan Ernst schrieb:
> Wenn du eine Veränderung sehen willst, dann ändere den Interrupt von B
> nach A. Dann siehst du, wie sich durch Verändern von OCR1B die Signale
> zueinander verschieben.

Habe jetzt sowohl Interrupt A als auch Interrupt B durch ein kurzes 
Pintoggeln markiert.

Richtig: wenn ich OCR1B ändere, verschiebt sich der Zeitpunkt des 
Interrupts A.
Mir ist klar, dass es sich um eine relative Verschiebung handelt.
Ihr habt wohl Recht, dass OCR1A auf Pin A und OCR1B auf den 
Compare-Match des Pin B wirkt. So war es eine ungünstige Wahl den Pin B 
zu verwenden: geht zwar, ist aber irgendwie schwer nachzuvollziehen:

- OCR1A muss wegen der Frequenz 0x7F sein.
- wenn OCR1B = 0x7F oder 0 ist, löst der Interrupt A praktisch 
zeitgleich mit Interrupt B und dem Flankenwechsel an Pin B aus.
- vergrößere ich OCR1B lansam von 0 beginnend, wandert der Interrupt A 
nach links.

Ist nachvollziehbar, muss aber ziemlich um die Ecke denken.

Anbei noch ein Oszi-Bild mit OCR1A=0x7F und OCR1B=0x10

CH1 (gelb) der Toggelnde Pin B
CH2 (blau) der Interrupt B
CH3 (lila) der Interrupt A

Letzteren muss ich zum Abtasten nehmen, dann klappts!

Vielen Dank, Problem erledigt!

von spess53 (Gast)


Lesenswert?

Hi

Mal ne dumme Frage: Warum muss es OCR1B sein. Der Interrupt von OCR1A 
würde  in der gleichen Frequenz auslösen. Und einen Pin togglen kann 
OCR1A auch.

MfG Spess

von Holler (Gast)


Lesenswert?

Für meine Schaltung brauche ich beide OCR1-Register: ich benötige einen 
Rechteck von bestimmter Frequenz (hier 500 Hz) und kurz vor der 
fallenden Flanke möchte ich ein externes Signal abtasten. Dazu eignet 
sich ein präzise ausgelöster Interrupt.

- OCR1A definiert einen TOP-Wert, bei dem der Zähler löscht und von 0 
wieder hochzählt.

- OCR1B kann einen Interrupt B auslösen und zeitgleich Pin B (OC1B) 
toggeln.
- OCR1A kann einen Interrupt A auslösen und zeitgleich Pin A (OC1A) 
toggeln.

Da ich mein Rechecksignal an Pin B abnehme, muss ich Interrupt B 
verwenden um eine zeitliche Ablage zu erreichen.

Hätte ich Pin A (OC1A) verwendet, hätte ich zum Abtasten den Interrupt B 
nehmen müssen und hätte mir das "um die Ecke denken" erspart.


Wenn man sich das letzte Oszi-Bild ansieht passiert folgendes:

- bei den lila Nadeln erreicht der Zähler 1 den Wert 0x7F des OCR1A, 
Interrupt A löst aus, der Zähler löscht => 0x0

- bei den blauen Nadeln hat der Zähler 0x10 erreicht, der Pin B toggelt, 
Interrupt B löst aus.

von Karl H. (kbuchegg)


Lesenswert?

Holler schrieb:

> Hätte ich Pin A (OC1A) verwendet, hätte ich zum Abtasten den Interrupt B
> nehmen müssen und hätte mir das "um die Ecke denken" erspart.

Noch ist Zeit.
Messerchen, Fädeldraht, und die Hardware ist geändert.
(Und gleich im Schaltplan für die Version 0.99 nachziehen)

Es ist nicht ungewöhnlich, dass beim ersten Protoypen ein paar 
Fädeldrähte auftauchen. Der Schaltung tut das ja keinen Abbruch. Den 
Draht schön eng anlegen und so fixieren, dass man ihn nicht irrtümlich 
runterreißt.

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.