Hallo,
Du musst die Interrupt Register so einstellen, dass der Interrupt auch passiert wenn du willst.
z.B.:
MfG AlexCode:GIMSK |= (1 << INT0); MCUCR |= (1 << ISC00);
Ich möchte gerne mittels Taster, der an PortD2 angeschlossen ist, einen Interrupt auslöst.
Atmega32
Taster ist mittels GROUND verbunden, was heisst, das er den Pin PORTD2 auf Masse zieht.
Dies ist meine ISR: Sie soll einfach den Text ans Display ausgeben.Code:ISR (INT0_vect) { //Interrupt deaktivieren cli(); lcd_clear(); lcd_home(); lcd_out("Taster wurde"); second_row(); lcd_out("gedrückt!"); delay_3(); delay_1(); //Interrupt aktivieren sei(); }
Main
Ist irgendetwas falsch an meinem Code?Code:int main(void) { sei(); lcd_clear(); lcd_home(); lcd_out("waiting..."); delay_3(); }
Hallo,
Du musst die Interrupt Register so einstellen, dass der Interrupt auch passiert wenn du willst.
z.B.:
MfG AlexCode:GIMSK |= (1 << INT0); MCUCR |= (1 << ISC00);
Hallo semicolon,
du solltest im main() auch noch eine Endlosschleife spendieren.
Dabei natürlich die Interrupt-Enable-Funktion von PasstScho mit einbauen.
z.B.:
Wenn dein delay_3() ca 3 Sekunden Pause macht, dann solltest du mit dem Tastendruch zwischen den "waiting..."-Ausgabe auch mal die Ausgabe aus deiner Interruptfunktion ins Display bekommen.Code:int main(void) { GIMSK |= (1 << INT0); MCUCR |= (1 << ISC00); sei(); while (1) { lcd_clear(); lcd_home(); lcd_out("waiting..."); delay_3(); } }
Kleiner Tipp:
Interrupt-Funktionen IMMER schnell halten. Soll heissen: Keine delay's einbauen.
Lieber Asuro programieren als arbeiten gehen.
In der ISR brauchst du kein cli zu machen, Interrupts werden durch die Hardware während Ausführung der ISR deaktiviert.
Das sei am Ende ermöglicht geschachtelte Interrupts! Das willst du sicher nicht. Wirf das raus.
Disclaimer: none. Sue me.
Eine Frage hierzu: Ich kenne die AVR-Programmierung nur durch den ASURO. In der dortigen C-Entwicklungsumgebung wird ein angepasster GCC als Compiler genutzt.Zitat von SprinterSB
Um damit eine ISR zu schreiben gibt es zwei Varianten um eine ISR einzuleiten:
1: SIGNAL (Interrupt-Name)
Das ist die Regel bei den mir bekannten ASURO-Sourcen. Hier werden tatsächlich innerhalb der ISR keine weiteren Interrupt behandelt. Erst nachdem eine ISR fertig ist, prüft die CPU ob eine weitere ISR aufgerufen werden muss.
2: INTERRUPT (Interrupt-Name)
Hier können laut Doku auch innerhalb der ISR-Funktion noch weitere Interrupts kommen, und werden auch sofort bearbeitet solange der zweite Interrupt eine höhere Proiorität hat. (Prio. ist durch die Hardware festgelegt.)
P.S.: Ich hoffe, dass es INTERRUPT (..) heisst, bin aber 100%-sicher, das es diese Variante gibt.
Nun zur Frage:
semicolon nutzt zur ISR-Einleitung ISR (INT0_vect). Ist hier eine andere Compiler-Variante im Spiel? Und wenn ja, gibt es eventuell auch hier die beiden oben aufgeführten Möglichkeiten? Was macht dann aber ISR() genau? (mit/ohne unterbrechbarkeit)
@semicolon
Ich bin nur neugierig. Dieser Eintrag hat nicht allzuviel mit deiner Aufgabenstellung zu tun.
Lieber Asuro programieren als arbeiten gehen.
SIGNAL/INTERRUPT wird vom "alten" GCC verwendet
ISR vom "neuen" (ca. seit Anfang 2006)
BTW: Auch der "alte" GCC wird weiterentwickelt, auch nach der Release des "neuen".
Das ISR in GCC 4.x entspricht dem SIGNAL in der 3.x.
Syntactic sugar, mehr nicht.
Das Analogon zu INTERRUPT muss man händisch mit Attributen codieren. Einfach ins Precompile schauen und das signal-Attribut durch ein interrupt-Attribut austauschen. Ausserdem steht's in RN-Wissen unter avr-gcc.
Disclaimer: none. Sue me.
Danke für die Info.
Lieber Asuro programieren als arbeiten gehen.
Lesezeichen