Hallo zusammen, ich hoffe, ihr könnt mir helfen. Es geht um ein Programm für den Asuro. es soll die status-LED kurz ausschalten, wenn man den Taster drückt. Das Problem ist, dass das Programm wahrscheinlich nicht zur While-schleife zurückspringt, um die LED dann wieder auf grün zu schalten. Ich lasse die LED mit Absicht in der While-schleife auf grün setzen, um herauszufinden, ob das Programm nach dem Interrupt zur Schleife zurückspringt oder nicht. #include <avr/io.h> #include <avr/interrupt.h> void init (void) { // Datenrichtung der I/O-Ports festlegen. DDRB |= (1 << PB0); //enable all interrupts GICR |= (1 << INT1); SREG |= (1 << 7); // Interrupt wird bei fallender Flanke ausgelöst MCUCR |= (1 << ISC11); MCUCR &= ~(1 << ISC10); sei(); } SIGNAL (INT1_vect) { PORTB &= ~(1 << PB0); // Grüne LED aus reti(); } int main(void) { init(); while(1) { PORTB |= (1 << PB0); // Grüne LED an } return 0; } freundliche Grüße Abi
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | |
5 | void init (void) |
6 | {
|
7 | // Datenrichtung der I/O-Ports festlegen.
|
8 | DDRB |= (1 << PB0); |
9 | |
10 | //enable all interrupts
|
11 | GICR |= (1 << INT1); |
12 | |
13 | // Interrupt wird bei fallender Flanke ausgelöst
|
14 | |
15 | MCUCR |= (1 << ISC11); |
16 | MCUCR &= ~(1 << ISC10); |
17 | }
|
18 | |
19 | ISR(INT1_vect) |
20 | {
|
21 | PORTB &= ~(1 << PB0); // Grüne LED aus |
22 | }
|
23 | |
24 | int main(void) |
25 | {
|
26 | init(); |
27 | |
28 | sei(); |
29 | |
30 | while(1) |
31 | {
|
32 | PORTB |= (1 << PB0); // Grüne LED an |
33 | }
|
34 | |
35 | return 0; |
36 | }
|
du willst keinen reti() selber aufrufen (das macht sowieso der Compiler für dich). Du willst auf das SREG nicht selber zugreifen (das macht der sei()). Du willst den sei() dezidiert vor der while Schleife haben, damit du ihn siehst (und nicht in irgendwelchen obskuren Funktionen verstecken), du willst SIGNAL nicht mehr benutzen (sondern ISR, denn dann passt auch der Name der ISR zur Verwendung)
Das Problem war wegen reti(). Wenn sie da ist, dann reagiert das Programm beim zweiten Tastendrücken nicht. ob ich auf SREG zugreife oder nicht und ob ISR oder SIGNAL, das is egal. hier ist das richtige Programm, was funktioniert, es soll die LED-Farbe zwischen Grün und Rot schalten, wenn man den Taster drückt.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | void init (void) |
5 | {
|
6 | // Datenrichtung der I/O-Ports festlegen.
|
7 | DDRB |= (1 << PB0); |
8 | DDRD |= (1 << PD2); |
9 | |
10 | PORTB |= (1 << PB0); // Grüne LED an |
11 | PORTD &= ~(1 << PD2); // Rote LED aus |
12 | |
13 | //enable all interrupts
|
14 | GICR |= (1 << INT1); |
15 | SREG |= (1 << 7); |
16 | |
17 | // Interrupt wird bei fallender Flanke ausgelöst
|
18 | |
19 | MCUCR |= (1 << ISC11); |
20 | MCUCR &= ~(1 << ISC10); |
21 | }
|
22 | |
23 | SIGNAL(INT1_vect) |
24 | {
|
25 | if (PINB & (1 << PB0)){ // Grün an ? |
26 | PORTB &= ~(1 << PB0); // Grün aus. |
27 | PORTD |= (1 << PD2); // Rot an. |
28 | |
29 | }else if (PIND & (1 << PD2)){ // Rot an ? |
30 | PORTD &= ~(1 << PD2); // Rot aus. |
31 | PORTB |= (1 << PB0); // Grün an. |
32 | }
|
33 | }
|
34 | |
35 | int main(void) |
36 | {
|
37 | init(); |
38 | |
39 | sei(); |
40 | |
41 | while(1) |
42 | {
|
43 | }
|
44 | return 0; |
45 | }
|
Dennoch solltest du nicht mehr SIGNAL benutzen. Momentan geht noch beides aber irgendwann ist SIGNAL weg. Und wenn du unbedingt SIGNAL benutzen musst, dann würde der Vector richtigerweise "SIG_INTERRUPT1" heissen Also entweder
1 | SIGNAL(SIG_INTERRUPT1) |
2 | ...
|
oder
1 | ISR(INT1_vect) |
2 | ...
|
Aber wie gesagt, letzteres ist vorzuziehen weil SIGNAL "deprecated" also veraltet ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.