PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt Problemchen



semicolon
18.06.2006, 19:12
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.



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();
}

Dies ist meine ISR: Sie soll einfach den Text ans Display ausgeben.

Main

int main(void)
{

sei();
lcd_clear();
lcd_home();
lcd_out("waiting...");
delay_3();
}

Ist irgendetwas falsch an meinem Code?

PasstScho
18.06.2006, 21:40
Hallo,
Du musst die Interrupt Register so einstellen, dass der Interrupt auch passiert wenn du willst.

z.B.:


GIMSK |= (1 << INT0);
MCUCR |= (1 << ISC00);


MfG Alex

Sternthaler
18.06.2006, 22:43
Hallo semicolon,
du solltest im main() auch noch eine Endlosschleife spendieren.
Dabei natürlich die Interrupt-Enable-Funktion von PasstScho mit einbauen.

z.B.:


int main(void)
{
GIMSK |= (1 << INT0);
MCUCR |= (1 << ISC00);

sei();

while (1)
{
lcd_clear();
lcd_home();
lcd_out("waiting...");
delay_3();
}
}


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.

Kleiner Tipp:
Interrupt-Funktionen IMMER schnell halten. Soll heissen: Keine delay's einbauen.

SprinterSB
19.06.2006, 08:15
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.

Sternthaler
19.06.2006, 18:04
In der ISR brauchst du kein cli zu machen, ...
Eine Frage hierzu: Ich kenne die AVR-Programmierung nur durch den ASURO. In der dortigen C-Entwicklungsumgebung wird ein angepasster gcc als Compiler genutzt.
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.

ogni42
19.06.2006, 18:17
SIGNAL/INTERRUPT wird vom "alten" gcc verwendet
ISR vom "neuen" (ca. seit Anfang 2006)

SprinterSB
20.06.2006, 08:15
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.

Sternthaler
20.06.2006, 13:43
Danke für die Info.