Forum: Mikrocontroller und Digitale Elektronik Interrupt durch Schalter an PD5


von Pfeiffy (Gast)


Lesenswert?

Hallo,

ich habe eigentlich ein ganz simples Problem: ich möchte ausgelöst durch 
einen Interrupt ( setzen 0 auf dem PD5) einen Interrupt auslösen und so 
eine LED zum brennen bringen, natürlich möchte ich später noch mehr 
damit machen, doch zuerst habe ich dies als Begriffsbeispiel, diesen 
Code habe ich, jedoch tut es nicht was es soll, sondern die LED fängt 
irgendwann an zu brennen, kann mir jemand helfen?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
6
ISR(INT0_vect)     //Die Interruptroutine. Kein ";" dahinter sonst Fehlermeldung beim Compilieren! 
7
                   // INT0_vect ist der Interruptvektor.
8
9
  {
10
  PORTB |= (1<<PB1);    //schaltet die LED ein.
11
  }
12
13
14
int main (void) 
15
16
{
17
18
DDRD  &= ~(1<<PD5); //setzt PD2 (INT0) und PD3 (INT1) auf Eingang
19
                                 //das sind die beiden Taster auf dem Evolutionsboard 
20
                                 //(mit einem RC-Glied gegen Prellen gesichert)
21
22
DDRB |= (1<<PB1);       //setzt PB1 auf Ausgang. Hier ist eine LED angschlossen.
23
PORTB = 0;
24
25
MCUCR |= (0<<ISC01) | (0<<ISC00);   //(Ausloesen des Interrupts bei steigende Flanke an INT0 und INT1)
26
27
GICR |= (1<<INT0);     //Aktiviert den Pin PD5 (INT0) (INT1) des Atmega8 
28
29
sei();                                                      
30
31
while(1)
32
  {
33
34
    }
35
36
return 0;                 
37
}

von Karl H. (kbuchegg)


Lesenswert?

Was für einen Prozessor hast du denn eigentlich.

Im Code steht was von einem Mega8. INT0 liegt aber beim Mega8 gar nicht 
auf PD5 sondern an PD2.
1
> MCUCR |= (0<<ISC01) | (0<<ISC00);   //(Ausloesen des Interrupts bei steigende Flanke an INT0 und INT1)
Was immer auch in deinem Datenblatt steht: Diese Operation ist eine 
No-Op, bewirkt also nichts. 0 kann man nach links schieben sooft man 
will, das Ergebnis bleibt immer 0. Und mit 0 kann man verodern sooft man 
will, das Ergebnis ändert sich dadurch nicht. Dieser Code setzt also den 
Interrupt mit Sicherheit nicht auf steigende Flanke.


Wenn du den Taster einfach nach Masse schalten lässt (so wie es üblich 
ist), dann solltest du wahrscheinlich auch einen entsprechenden 
Pullup-Widerstand an diesem Pin aktivieren. Sonst hat der Pin kein 
definiertes Potential, wenn der Taster nicht gedrückt ist.


Und zu guter letzt: Um Taster auszuwerten, braucht man keinen externen 
Interrupt. Bis auf den Fall, dass der Taster den µC aus dem Tiefschlaf 
holen muss, ist ein externer Interrupt dafür sogar eher hinderlich bzw. 
führt meistens zu schlechtem Code mit Unmengen an Delay-Schleifen (weil: 
man hat ja eh einen Interrupt)

von Pfeiffy (Gast)


Lesenswert?

Hallo,
danke für die Antwort, gut, ich hab das mit den PD2 nicht kapiert, 
sondern hab den PD5 genommen, werd ich gleich mal umlöten.
1
> MCUCR |= (0<<ISC01) | (0<<ISC00);   //(Ausloesen des Interrupts bei steigende Flanke an INT0 und INT1)
-> das hab ich auch kapiert, wenn ich hier nichts eintrage habe ich doch 
0,0 drin

besser?:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
6
ISR(INT0_vect)     //Die Interruptroutine. Kein ";" dahinter sonst Fehlermeldung beim Compilieren! 
7
                   // INT0_vect ist der Interruptvektor.
8
9
  {
10
  PORTB |= (1<<PB1);    //schaltet die LED ein.
11
  }
12
13
14
int main (void) 
15
16
{
17
18
DDRD  &= ~(1<<PD2); //setzt PD2 (INT0) und PD3 (INT1) auf Eingang
19
                                 //das sind die beiden Taster auf dem Evolutionsboard 
20
                                 //(mit einem RC-Glied gegen Prellen gesichert)
21
22
DDRB |= (1<<PB1);                //setzt PB1 auf Ausgang. Hier ist eine LED angschlossen.
23
PORTB = 0;
24
25
MCUCR |= (1<<ISC01);   //(Ausloesen des Interrupts bei steigende Flanke an INT0 und INT1)
26
27
GICR |= (1<<INT0);     //Aktiviert den Pin PD2 (INT0) 
28
29
sei();                                                        //einschalten der Interrupts. Setzt das Global Interrupt Enable Bit im Status Register. 
30
31
while(1)
32
  {
33
34
    }
35
36
return 0;                 
37
}

von Karl H. (kbuchegg)


Lesenswert?

> danke für die Antwort, gut, ich hab das mit den PD2 nicht
> kapiert, sondern hab den PD5 genommen

Ist ganz einfach: Alle Spezialpinbezeichnungen, die in der Pinübersicht 
ganz am Anfang des Datenblatts in der Zeichnung auftauchen, sind fix und 
können nicht von dir geändert werden. Wenn du einen INT1 benutzen 
willst, dann siehst du in dieser Zeichnung nach, welcher Pin das ist. 
Und der und kein anderer ist es dann.


Mach da
1
int main (void) 
2
3
{
4
5
DDRD  &= ~(1<<PD2);

noch einen Pullup Widerstand rein
1
int main (void) 
2
{
3
  DDRD  &= ~(1<<PD2);
4
  PORTD |= (1<<PD2);


> werd ich gleich mal umlöten.
D.h. Eigenbauboard?
D.h. auch 'ohne Hardware-Entprellung'.
Na denn viel Spass in weiterer Folge mit dem Taster am Interrupt.

von Pfeiffy (Gast)


Lesenswert?

auch wenn ich einen 1k vor dem Taster habe?

von Karl H. (kbuchegg)


Lesenswert?

Pfeiffy schrieb:
> auch wenn ich einen 1k vor dem Taster habe?

Was heißt 'vor dem Taster'?

Ein Pullup ist nicht vor dem Taster, sondern geht vom µC Pin entweder 
nach Vcc (dann ist es ein Pullup) oder er geht vom µC Pin nach GND (dann 
ist es ein Pulldown). Aber er liegt nicht 'vor dem Taster'.

von Pfeiffy (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Was heißt 'vor dem Taster'?
>
> Ein Pullup ist nicht vor dem Taster, sondern geht vom µC Pin entweder
> nach Vcc (dann ist es ein Pullup) oder er geht vom µC Pin nach GND (dann
> ist es ein Pulldown). Aber er liegt nicht 'vor dem Taster'.

ok, liegt nicht vor dem Taster sondern vcc+ auf 1k dann auf PIN, dann 
PIN auf 0, entschuldige die schlampige Ausdrucksweise

Wie gesagt, der Taster am Interrupt ist nur zum lernen, wie ein 
Interrupt funktioniert.

Gruß
Pfeiffy
(hatt ich bis jetzt immer vergessen) und danke natürlicg für die Hilfe

von Hannes L. (hannes)


Lesenswert?

Pfeiffy schrieb:
> der Taster am Interrupt ist nur zum lernen, wie ein
> Interrupt funktioniert.

Oder zum Lernen, dass man Taster nicht (ohne Not) mittels Interrupts 
einliest.

Viele Ausbilder neigen dazu, erstmal Blödsinn ausprobieren zu lassen, um 
dann zu zeigen, dass es anders besser geht. Sie nennen das dann 
"Didaktik".

...

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
Noch kein Account? Hier anmelden.