Forum: Compiler & IDEs Interrupt funktioniert nicht


von clecksi (Gast)


Lesenswert?

Hi,

Ich arbeite gerade an einer Weichensteuerung für meine 
Modelleisenbahnanlage und hänge bei der Programmierung fest.

Im Grunde soll beim Betätigen eines Tasters die Weiche umgestellt, eine 
LED eingeschaltet (zum Signalisieren des Schaltzustandes), und der 
jeweilige Schaltzustand im EEPROM gespeichert werden.

Das Problem das ich jetzt habe ist, dass wenn der Taster betätigt wird 
einfach nichts passiert.

Ich denke dass ich beim Definieren der Ein- bzw. Ausgänge und der 
Interrupts einen Fehler gemacht habe. Darum hier der Code der 
Initialisierung:
1
/*
2
  Anschlüsse:
3
                            _____
4
  Externer Taster    RST 5-|*    |-Vcc  5V
5
  Weiche abzweigen       3-|  µC |-2    LED grün
6
  Weiche geradeaus       4-|     |-1    Taster
7
  0V                   GND-|_____|-0    LED rot
8
9
*/
10
11
void init()
12
{
13
  //Weichenstatus vom EEPROM lesen:
14
15
  State = eeprom_read_byte(&eepStateAdr);
16
17
18
  //Ein und Ausgänge definieren:
19
20
  DDRB &= ~(1 << DDB1);                        //Pin 1 als Eingang
21
     DDRB |= (1 << DDB0) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4);    //Pin 0,2,3,4 als Ausgang
22
  PORTB |= (1 << DDB1);                        //Pin 1 PullUp aktivieren
23
24
25
  //Interrupts einstellen:
26
  
27
  MCUCR |= ((1<<ISC00) | (1<<ISC01));      //Int0 Interrupt auf steigende Flanke
28
  GIMSK |= (1<<INT0);              //Int0 Interrupt aktivieren
29
30
31
  //init anzeige:
32
33
  LED(EIN);            //beide LEDs ein, nach 1 sekunde wieder aus
34
  _delay_ms(1000);
35
  LED(AUS);
36
}

Was ich noch nicht ganz verstanden habe ist, wie sich der Spannungslevel 
der Pins verhaltet je nachdem wie sie definiert sind. Korrigiert mich 
bitte wenn ich falsch liege.

Wenn ein Pin als
-Ausgang gesetzt wird ist die Spannung abhängig vom Code, standardmäßig 
auf 0V.
Wenn der Pin als Eingang gesetzt ist, liegt er auf GND.

von clecksi (Gast)


Lesenswert?

...habe versehentlich auf Abschicken geklickt :/

also nochmal:

Wenn ein Pin als
-Ausgang gesetzt wird ist die Spannung abhängig vom Code, standardmäßig
auf 0V.
-Eingang gesetzt ist, liegt er auf GND.
-Eingang mit internen Pull-up Widerstand, liegt er auf GND.
-als Interrupteingang verwendet wird, kann er als Eingang oder auch als 
Ausgang definiert werden (Software löst dann Interrupt aus), dann liegt 
die Spannung auf ???


mfg clecksi

von Noname (Gast)


Lesenswert?

Nein. Ein als Eingang geschalteter Pin ist hochohmig. Der Pegel wird 
dann im nicht-beschalteten Zustand durch die Leckströme der Schutzdioden 
und/oder die sonstige Beschaltung bestimmt.

Aus Deinem Code geht nun garnicht hervor, wie Du die Tasten abfragst. 
Deswegen können wir da auch nicht helfen.
Aber "Interrupt" im Titel des Posts deutet darauf hin, das Dir Peter 
Danneggers Entprellung hier helfen könnte.

von Noname (Gast)


Lesenswert?

>Eingang mit internen Pull-up Widerstand, liegt er auf GND

Häh? Lies mal das Datenblatt und tu Dir ein paar Grundlagen der 
E-Technik an.

Nein. Ein "Pull-Up"-Widerstand wird den Ruhepegel auf "Vcc", "High" 
festlegen. Deswegen heisst er "Pull-Up".

von clecksi (Gast)


Lesenswert?

Hi,

mit dem Betätigen des Tasters wird der Pin auf GND gelegt, dies löst 
wiederum einen Interrupt aus...

Hier noch die ISR:
1
ISR(INT0_vect)            //PIN0 Interrupt, ausgelöst bei steigender Flanke auf Pin 0
2
{
3
  cli();              //Interrupts global deaktivieren
4
5
  if (State == GREEN)        //Weichenstatus wechseln
6
  {
7
    State = RED;
8
  }
9
  else
10
  {
11
    if (State == RED)
12
    {
13
      State = GREEN;
14
    }
15
    else            //Errorstatus falls kein Stat vorhanden
16
    {
17
      State = ERROR;
18
    }
19
  }
20
21
22
  Set = true;            //Stellbefehl auf wahr setzen
23
}

mfg clecksi

von clecksi (Gast)


Lesenswert?

...ja Stimmt, hab mich da ein bisschen vertan :/

Wenn der Pin als Eingang mit Pull-Up beschalten wird hat er einen High 
Pegel und darf nun über den Pull-Up direkt auf GND gelegt werden...

von Noname (Gast)


Lesenswert?

Genau.

Aber noch was: Du schreibst oben im Kommentar das Du den INT0 für 
steigende Flanke aktivierst aber unten im Interrupt, das er auf fallende 
reagieren soll.

Abgesehen davon: Prellende Tasten im Interrupt ist, wenn man keine 
Ahnung hat, eine ganz schlechte Idee. Lies Dir Peter Danneggers 
Tastenentprellung durch.

von spontan (Gast)


Lesenswert?

@clecksi
>Wenn der Pin als Eingang mit Pull-Up beschalten wird hat er einen High
>Pegel und darf nun über den Pull-Up direkt auf GND gelegt werden...

Hast Du einen Schaltplan dazu? Der obige Text ist entweder Unsinn oder 
nicht zu verstehen.

von clecksi (Gast)


Lesenswert?

Hi,

das mit der Tastenentprellung ist in meinem Fall hinfällig, da während 
des gesamten Schaltvorgangs die Interrupts global deaktiviert sind und 
dieser Schaltvorgang ein Delay von 200ms beinhaltet...also genug zeit 
damit sich der Taster wieder beruhigt.

Ob der Interrupt nun bei steigender oder fallender Flanke auslöst ist 
eigentlich nicht so tragisch, da das die wesentliche Funktion ja nicht 
beeinflusst...

Meine Frage war ja eigentlich ob ich den INT0-Pin richtig definiert habe 
und welche gründe es vielleicht noch geben könnte warum das Programm 
nicht funktioniert?
Muss ich den PIN1 als Eingang mit Pull-Up definieren oder ist es so 
richtig?

mfg

von clecksi (Gast)


Lesenswert?

@spontan

Ist ein Pin als Eingang mit Pull-Up Widerstand definiert, liegt an ihm 
ein High Signal an. Der Pull-Up erlaubt es mir dieses High Signal auf 
Masse zu legen, ohne dass ich damit einen Kurzschluss auslöse. Diese 
Spannungsänderung wird nun erkannt und löst am Eingangspin, dem INT0 Pin 
in diesem Fall, einen Interrupt aus....

mfg

von (prx) A. K. (prx)


Lesenswert?

clecksi schrieb:
> ISR(INT0_vect)            //PIN0 Interrupt, ausgelöst bei steigender
> Flanke auf Pin 0
> {
>   cli();              //Interrupts global deaktivieren

cli() an dieser Stelle nützt nichts und schadet nichts, denn die ISR 
wird bereits mit abgeschaltetem Interrupt aufgerufen.

von Noname (Gast)


Lesenswert?

>da während  des gesamten Schaltvorgangs die Interrupts global deaktiviert >sind 
und dieser Schaltvorgang ein Delay von 200ms beinhaltet

Na gut. Dann ziehe ich mich hier wieder raus. Hat ja keinen Zweck.

Also viel Erfolg noch.

von (prx) A. K. (prx)


Lesenswert?

Vorsorglich sei darauf hingewiesen, dass main() mit abgeschaltetem 
Interrupt aufgerufen wird.

von clecksi (Gast)


Lesenswert?

Danke A. K., you just solved it :)

mfg

von Peter D. (peda)


Lesenswert?

clecksi schrieb:
> das mit der Tastenentprellung ist in meinem Fall hinfällig

Du wirst Dich wundern.
Modelleisenbahn ist bestimmt keine störfreie Umgebung.

Die Testschaltung mag erstmal funktionieren. Aber wenn Du sie einbaust, 
wird sie haufenweise unmotiviert umschalten durch eingekoppelte 
Störimpulse.

Aber auch Handy-Benutzung oder Staubsaugen in der Nähe kann die 
Interrupts feuern.


Peter

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.