www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ISR(TIMER1_COMPA_vect) und OCR1A


Autor: Alexander G. (grossmann200)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
nach dem Studium einiger Tutorials und Internetsuche habe ich mich nun 
daran gewagt meinen ersten Interrupt zu programmieren.

Ich habe mal meine Frage in zwei Versionen aufgeführt. Irgendwie dachte 
ich die Langversion ist zu kompliziert und zu lang, und die Kurzversion 
erklärt's vielleicht nicht richtig.


Meine Frage in Kurzversion:
Ist in ISR(TIMER1_COMPA_vect) der richtige Vektor gewählt, wenn ich die 
Routine jedesmal aufrufen will, wenn mein Vergleichswert in OCR1A 
erreicht wird.

Meine Frage in Langeversion:
In meinem Progrämmchen (zur PWM - dass dank Forenhilfe auch flutscht) 
wird der Zähler mit dem Vergleichwert (OCR1A) verglichen. Wenn ich das 
Atmel-Datenblatt richtig verstanden habe, dann wird bei jeder 
Übereinstimmung von Vergleichswert mit Zählwert ein Output Compare 
Interrupt Request (OCF1A/B) ausgelöst. An anderer Stelle fand ich eine 
Tabelle mit Interrupt-Vektoren. Da auch das AVR-Tutoral von Vektoren als 
Argumenten für ISR spricht, habe ich dann mal

ISR(TIMER1_COMPA_vect) { //Anweisungen }

gewählt. In main() habe ich dann auch mit sei() brav den Global 
Interrupt Enable Bit gesetzt. Beim compilieren gibt's auch keine Fehler. 
Ich dachte jetzt, dass jedesmal wenn Zählwert = Vergleichswert eintrifft 
meine Interrupt-Routine ausgelöst wird ... tut's allerdings nicht. Da es 
von mir eine Annahme war, dass TIME1_COMPA_vect der richtige Vektor sei, 
frage ich mal hier, ob dem so ist (leider steht im Datenblatt nichts 
näheres dazu ... oder ich raff's einfach nicht.

Grüße
Der Alexander

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weis nicht welchen Kontroller du hast aber ich denke mal dir fehlt 
noch der Eintrag im TIMSK-Register für OCIE1A. Im Datenblatt unter 
Output Compare Units.

Autor: ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip stimmt das!
Es könnte sein, dass du ISR(TIMER1_COMPB_vect) verwenden musst.
Wichtig ist, dass nicht nur die globalen Interrupts eingeschaltet sind, 
sondern auch der für diesen Betriebsmodus. Natürlich muss auch der Timer 
in den gewünschten Modus gebracht werden. Das steht aber im Datenblatt 
geschrieben. Poste sonst mal den ganzen Code...

Autor: Alexander G. (grossmann200)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR(TIMER1_COMPB_vect) hat leider auch nicht funktioniert.

Neben den Global Interrupt Enable Bit habe ich schon geschaut, ob sonst 
noch was aktiviert werden muss. Ich habe auch unter 
http://www.mikrocontroller.net/articles/AVR-Tutori... etwas 
für die beiden externen Interrupts gefunden (GICR Register), jedoch 
nichts für den Fall, wenn der Zähler den Vergleichwert erreicht. Aber 
anscheinend habe ich hier tatsächlich was übersehen und dies wäre des 
Problems Lösung. Hier mal mein Code:

#include <avr/io.h>
#include <avr/interrupt.h>


ISR(TIMER1_COMPB_vect) // Schaltet LED an PB0 ein
{
  DDRB = DDRB | (1 << PB0);
  PORTB = PORTB | (1 << PB0);
}


int main(void)
{
// PWM: Bringt LED an PB1 zum blinken
DDRB = DDRB | (1 << PB1);
TCCR1B = TCCR1B & ~(1 << WGM13);
TCCR1B = TCCR1B | (1 << CS10);
TCCR1B = TCCR1B | (1 << CS12);
TCCR1A = TCCR1A | (1 << WGM10);
TCCR1A = TCCR1A | (1<< WGM11);
TCCR1A = TCCR1A | (1 << COM1A1);
TCCR1A = TCCR1A | (0 << COM1A0);
OCR1A = 400;

//Interrupts aktivieren
TIMSK = TIMSK | (1 << OCIE1A);
sei();

while(1)
  {
  };
}


Ach ja, ich habe einen ATMega8.

Autor: Hubert.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du ISR(TIMER1_COMPB_vect)verwendest musst du auch OCIE1B im TIMSK 
setzen und nicht OCIE1A oder umgekehrt.

Autor: Alexander G. (grossmann200)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verdammt. Klar, des isses. Ist mir jetzt auch irgendwie peinlich. Vor 
lauter hin- und herspringerher zwischen Tutorials, Datenblatt, Foren, 
Internetsuche habe ich da echt den Überblick verloren. Im Code isses mir 
dann auch nicht aufgefallen, da dieser im Original etwas unübersichtlich 
wurde da ich mir hinter jeder Zeile eine mehrzeilige Kommentierung 
geschrieben habe.

Eines würde mich als Anfänger dann doch noch interessieren. Wie auch 
???(Gast) schon angemerkt hat, muss auch im TIMSK-Register das OCIE1A 
Bit gesetzt werden. Ich bin im Datenblatt da eher zufällig drüber 
gestolpert (steht auf S.72). Während das setzen der Vektoren irgendwo 
ganz am Anfang steht. Gibt es hier sowas wie eine Regel, anhand der man 
erkennt, was man alles setzen muss ... oder muss man sowas einfach nur 
wissen. Sprich man lernt es mit der Zeit. Da es mir auch etws unangnehm 
ist in Foren sowas doch recht einfaches zu fragen, war ich gestern im 
Buchladen und hoffte eine übersichtliche Literatur zu finden, habe 
jedoch nix gefunden. Kannst du hier etwas empfehlen.

Also nochmals danke, und hoffe ihr verzeiht mir, dass ich durch meine 
Schlamperei eure Zeit beansprucht habe.

Grüße
Der Alexander

P.S. Vielleicht sollte man, wenn's mal nicht funktioniert, einfach mal 
ne' Pause machen.

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für jeden Interrupt, den du benutzen willst brauchst du eine ISR (der 
exakte Name hängt vom compiler ab), musst diesen Interrupt aktivieren- 
beim AVR fast immer ein Bit mit der Bezeichnung xxxIE (-interrupt 
enable) und musst die Interrupte mit "sei" global aktivieren.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.