C 16 Bit Timer generiert keine Interrupts

MrPepi

Neues Mitglied
11. Jan. 2014
10
0
0
Sprachen
Hallo Forum,

ich habe ein Problem:

wenn ich den 16 Bit-Timer Timer1 vom mega644PA im Atmel Studio 6 simuliere, und in den beiden ISRs (TIMER1_COMPA_vect & TIMER1_COMPB_vect) ein Bit setzte bzw. lösche, sehe ich das nicht in der IO-View.

Die Bits OCIE1A & OCIE1A sind gesetzt und die globalen Interrupts sind auch aktiviert.

Woran kann das liegen?

Hier meine Timer-Initialisierung:

[CCODE]
TCCR1A |= 1 << COM1B1;
TCCR1B |= 1 << WGM12;

TCCR1B |= 1 << CS10;
TCCR1B |= 1 << CS11;

TIMSK1 |= 1 << OCIE1A;
TIMSK1 |= 1 << OCIE1B;

OCR1A = 37500; //= 120 ms
OCR1B = 3; //= 9,6us

TCNT1 = 0;[/CCODE]

MfG
MrPepi

PS: Was ist eigentlich der unterschied zwischen den "normalen" Interrupt Vektoren und denen mit "_num" hinten dran?
 
Wie meinst Du das mit der Simulation und der Aktualisierung der I/O-View? Wenn Du das Programm im Simulator durchlaufen läßt, wird da in der Darstellung doch gar nichts geändert, erst wenn man das pausiert, oder? Und wenn Du das schrittweise durchklickerst, hast Du bei Prescaler=64 und CTC bis 37500 'ne Sehnenscheidenentzündung. Hast Du den Cursor mal in die erste Zeile der OC1B-ISR gesetzt, und den Simulator mit "Run To Cursor" bis dahin laufen gelassen - um zu sehen, ob er die ISR überhaupt mal erreicht?

Für den Simulator könntest Du den Prescaler auch einfach mal auf 1 setzen.
 
Hier meine ISRs:

[CCODE]
ISR(TIMER1_COMPA_vect){
PORTA |= 1 << PA1;
}

ISR(TIMER1_COMPB_vect){
PORTA &= ~(1 << PA1);
}[/CCODE]

Das mit dem PS und 37500 ist kein Problem, da ich den Wert während des Debuggens verändern kann (durch klicken auf die Bits im Register).

In der IO-View beim Timer setzt er das OCF1A & OCF1B Flag nicht, wenn er eine Compare Match erreicht, obwohl ich sie aktiviert habe.
 
Hmm...
Eigentlich 'ne DAU-Frage, aber:
...In der IO-View beim Timer setzt er das OCF1A & OCF1B Flag nicht, wenn er eine Compare Match erreicht, obwohl ich sie aktiviert habe.
Datenblatt Seite 120 schrieb:
16.7Output Compare Units The 16-bit comparator continuously compares TCNTn with the Output Compare Register (OCRnx). If TCNT equals OCRnx the comparator signals a match. A match will set the Output Compare Flag (OCFnx) at the next timer clock cycle. If enabled (OCIEnx = 1), the Output Compare Flag generates an Output Compare interrupt.
Hast Du den weiterlaufen lassen?

P.S.: Das was Du da machst, ist ja PWM oder? Das kann der Timer natürlich auch komplett allein im Hintergrund, ohne Interrupts usw (OCRnA-frequenzkorrigierter fastPWM, Waveform Generation Mode=15) - aber Du machst das zur Übung, oder?
 
Nope, ich Debugge per Alt + F5 (Debug and Break), dan schalte ich mit F10 bzw. F11 durch, also kann ich jede Zeile überprüfen bzw. durchlaufen.

Und nein, ich mache keine PWM, denn es ist mir bewusst, das das der Timer allein kann.
Ich Werte einen Ultraschallsensor Aus:

Alle 120ms wird ein Pin auf HIIG gesetzt, (OCR1A) und dann, nach ca. 10us (OCR1B) wieder auf Low.
Das it das Triggersignal, das er benötigt um zu starten.
 
Hast Du verstanden, was ich Dir da oben sagen wollte? Die Compare-Flags werden nicht gesetzt wenn OCRxn=TCNTx wird, sondern einen Timer-Takt später (also in Deinem Beispiel soll bei TCNT 2->3 noch nichts passieren, erst bei TCNT 3->4 wird das OCB-Flag gesetzt, und ggf der IRQ angefordert). Hast Du das mal bis dahin ausprobiert?
...Und nein, ich mache keine PWM, denn es ist mir bewusst, das das der Timer allein kann.
Ich Werte einen Ultraschallsensor Aus:

Alle 120ms wird ein Pin auf HIIG gesetzt, (OCR1A) und dann, nach ca. 10us (OCR1B) wieder auf Low.
Das it das Triggersignal, das er benötigt um zu starten.
Aber genau das macht doch der fastPWM (mit OCRxA frequenzkorrigiert). Der Timer wird automatisch beim OCRxA-Match (also einen Timer-Takt nach TCNTx=OCRxA) auf 0 zurückgesetzt, KanalB könnte nach Tabelle 16-3 (Seite 133) im Compare Output Mode=2 bei jedem zurücksetzen (OCRxA-Match - alle 120ms) gesetzt werden, und im OCRxB-Match (immer 10µs danach) wieder gelöscht. Einmal so eingestellt läuft das dann ewig durch. Du modullierst dann halt die Pulsweite nicht, sondern läßt sie so mit 10µs von 120ms fest stehen. Im Vordergrund kann der Controller irgendwas anderes machen, oder schlafen geschickt werden...
 
Ja, das habe ich verstanden, aber er setzt es nicht 1 Takt, 2 Takte oder auch 100 Takte später.
Daran hänge ich ja, und DBL lesen kann ich selbst auch....

OK, ich werde es mal mit fastPWM ausprobieren
 
...aber er setzt es nicht 1 Takt, 2 Takte oder auch 100 Takte später...
Hmm... sollte er aber - genau genommen 64 Prozessortakte später, eben einen Timertakt...
könnte natürlich auch ein Simulator-Bug sein.

Zu der Sache mit den IRQ-Vektornamen kann ich Dir als Assembler-Programmierer nichts weiter sagen - ebenso finde ich Deine Registerzuweisungen unnötig aufwändig (Insbesondere bei TCCR1B werden die 3 Bits nacheinander und je mit einem Read-Modify-Write-Zyklus gesetzt).
Aber da muß ein "C-Mensch" was zu sagen...
 
Hallo zusammen!
Zu der Sache mit den IRQ-Vektornamen kann ich Dir als Assembler-Programmierer nichts weiter sagen - ebenso finde ich Deine Registerzuweisungen unnötig aufwändig (Insbesondere bei TCCR1B werden die 3 Bits nacheinander und je mit einem Read-Modify-Write-Zyklus gesetzt).

TIMER1_COMPA_vect zum Beispiel ersetzt den Parameter durch ein Macro mit Vector-Nummer des Interrupts als Parameter.
TIMER1_COMPA_vect -> _Vector(1) ->__vector_1 (die Zahl stimmt nicht, ist hier nur ein Beispiel)
__vector_1 wird dann in der Compile-Zeit verarbeitet, wie genau weiß ich nicht.

TIMER1_COMPA_vect_num ist nur die Nummer des Interrupts.


Die Sache mit dem Read-Modify-Write-Zyklus ist hier eigentlich in der Hochsprache uninteressant...muss man nicht wissen. Man kann hier natürlich einiges zusammenfassen, dies spart minimal Zeit und minimal Flash Memory und wird vielleicht auch übersichtlicher.

Was eher wichtiger ist:
Konfiguriert man einen Timer, sollte man erst zum Schluss der Konfiguration Prescalerbits setzen und dann dies möglichst in einem Schritt. Sonst läuft der Timer ja bereits und je nachdem, was man danach noch einstellt, könnte es unbeabsichtigte Wirkung haben.

Dirk :ciao:
 
Danke für die Antworten :)

Ich habe jetzt mit einem Freund gesprochen, und der sagt das es an den Einstellungen liegt...

Aber das mit den Prescaler-Bits ist eigentlich logisch :D

Und Danke für die erklärung zu dem Unterschied ^^
 
...Die Sache mit dem Read-Modify-Write-Zyklus ist hier eigentlich in der Hochsprache uninteressant...muss man nicht wissen...Was eher wichtiger ist:
Konfiguriert man einen Timer, sollte man erst zum Schluss der Konfiguration Prescalerbits setzen und dann dies möglichst in einem Schritt. Sonst läuft der Timer ja bereits und je nachdem, was man danach noch einstellt, könnte es unbeabsichtigte Wirkung haben...
Hmm... ok, hier ist es jetzt sicher nicht kritisch, aber er setzt ja nacheinander die beiden Prescaler-Bits - der Timer beginnt also erstmal mit Prescaler=1 (CS10=1) zu laufen, während das zweite Bit gesetzt wird (LDS, ORI, STS) vergehen 5 Takte (bis dahin also auch 5 Timer-Takte), bevor der gewünschte Prescaler greift (CS11=1)

Bei einigen I/O-Registern kann sowas aber auch arg nach hinten losgehen - beim TWI zB...

Wird statt des CTC (nonPWM) zB der fastPWM verwendet, sind die OC-Register gepuffert - eine Änderung wird dann erst nach dem nächsten Überlauf/Zurücksetzen wirksam.
 
Hi LotadaC,
Hmm... ok, hier ist es jetzt sicher nicht kritisch, aber er setzt ja nacheinander die beiden Prescaler-Bits - der Timer beginnt also erstmal mit Prescaler=1 (CS10=1) zu laufen, während das zweite Bit gesetzt wird (LDS, ORI, STS) vergehen 5 Takte (bis dahin also auch 5 Timer-Takte), bevor der gewünschte Prescaler greift (CS11=1)

genau das hatte ich ja auch in meinem Beitrag zuvor "bemängelt" ;-)

-> Prescaler Bits zum Schluss setzen und dann möglichst in einem Schritt.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)