Interrupt wird immer ausgelößt

  • Hallo


    Ich arbeite zur Zeit an einem Projekt, in dem ich die beiden Interrupts des ATmega32 benutze, um ein Programm durch zu schalten. Ich habe die beiden Taster mit einem Pull-down widerstand An die Pins D2 und D3 angeschlossen und in meinem Bascom Programm beide Interrupts eingeschaltet und Konfiguriert. Jetzt habe ich jedoch das Problem, dass die Interrupt die ganze zeit ausgelößt werden, das heißt er zählt die Programme ständig durch, obwohl an den Pins 0V anliegen. Durch das Betätigen der Taster lässt sich das auch nicht stoppen. An den Pins D4, D6 und D6 habe ich ebenfalls Taster mit einem Pull-Down widerstand angeschlossen, mit denen kann ich aber nur was erreichen, wenn ich den Interrupt ausgeschaltet habe. Und die Funktionieren ganz normal. Mit einem zweiten ATmega32 habe ich das Programm auch schon getestet, mit dem selben Ergebnis.


    Hier sind nochmal alle relevanten teile aus meinem Code:




    Edit: habe die Zeilen Config Int0 und Config Int1 hinzugefügt. Jetzt zählt er aber jeden Tasterdruck 2mal.

  • und in meinem Bascom Programm beide Interrupts eingeschaltet und Konfiguriert

    In dem Programm ist keine einzige Config Zeile ?(
    Schau doch besser noch mal in die Hilfe wie der Interrupt konfiguriert wird ;)

  • Wenn er jeden Tastendruck zweimal zählt, dann programmier das doch einfach weg.


    Programm 1 wird bei I = 0 aufgerufen
    Programm 2 wird bei I = 2 aufgerufen
    Programm 3 wird bei I = 4 aufgerufen
    ....
    Programm 6 wird bei I = 10 aufgerufen


    Jeder Druck auf einen Taster löst zwei "Tastendrücke" aus. Bei jedem Tastendruck wird I um 1 erhöht.
    Du drückst einmal und I springt von 0 auf 2, schon springt er zu Programm 2, du drückst wieder und I springt von 2 auf 4...


    Aber egal was du machst, su solltest noch Grenzen festlegen. Zum Besispiel wenn du jetzt paar mal auf deinen Decr-Taster drückst, dann zählt er ja einfach nach unten weiter. Sprich wenn du im Programm 1 bist und den Decr Taster paar mal drückst, dann zählt er I "heimlich" weiter runter auf, sagen wir mal 240. Wenn du jetzt wieder nach oben willst, dann müsstest du erst wieder in paar mal auf dem Incr Taster hämmern, damit du irgendwann wieder mal bei 0 ankommst und ganz normal nach oben schalten kannst. Das gleiche gilt natürlich auch fürs nach oben zählen.


    If I < 0 Then I = 0
    If I > 10 Then I = 10


    Wenn du jetzt im Programm 6 bist, kannst du so oft auch den Incr Taster drücken wie du willst, es passiert nichts.


    Ach ja, vllt solltest du auch noch deine Variable Programm definieren. Fehlt oben. Also das was bei mir jetzt I heißt, heißt ja bei dir Programm.


    Dim I As Byte, so zum Beispiel.

  • Also es Funktionieren jetzt beide Interrupts so wie sie sollen, jedoch ist immernoch das Problem, dass er zu viele zählt. Es ist auch nicht so dass er IMMER doppelt zählt sondern alle vielleicht 20 tasten drücke auch mal nur einen.


    Und die Grenzen für den Interrupt habe ich im Hauptprogramm festgelegt, dass habe ich hier aber rausgelassen, da dort nichts wichtiges steht, ausser die Grenzen.
    Und den anderen Interrupt abschalten hilft auch nicht.

  • Gut, wollte das mit die Grenzen auch nur erwähnen.


    Wie hast du denn die Taster entprellt? Also bei Interrupts hat sich ein externer 10kOhm Widerstand in Verbindung mit einem parallel geschaltetem 10nF Keramikkondensator zum Taster gut bewährt. Ansonsten eben noch ein kleines waitms 30 an passender Stelle.


    Code
    Prgup:
    waitms 30
    Incr Programm


    Code
    Prgup:
     waitms 30
     Decr Programm
  • Bei Interrupts die 2x auslösen hilft es vielleicht das Interrupt Flag beim verlassen der ISR zu löschen.
    wenn während der Arbeit in der ISr ein weiterer Interrupt auftrit(Tastenprellen) wird das Flag gesetz
    und nach verlassen der ISR abgearbeitet-->nochmal ISR.


    EDIT:
    If I < 0 Then I = 0
    kleiner als 0 wird nicht funktionieren

  • also wenn ich hatte vorher die zeit vor dem Return und wenn ich sie nun direkt nach dem Sprung Label schreibe, dauert es halt etwas bis er zwei mal zählt. er braucht für das zweite mal zählen aber etwas.
    Und nach einigen Tests stelle ich auch fest, dass er so IMMER 2 hoch zählt, also wäre das schonmal eine Möglichkeit das Problem zu lösen.
    Und zum Entprellen ahbe ich wie im ersten Beitrag geschrieben Pull-Down widerstände benutzt mit 10kOhm. Ohne Kondensatoren oder so sondern nur die Widerstände.


    Edit: Snowfly: Du hattest die rettende Lösung. Mit dem Befehl Gifr.intf1 = 1 habe ich kurz vor dem Beenden der Routiene das Interrupt Flag gelöscht und nun zählt er brav einen nach dem anderen :)


    Danke!

  • Ich muss dich mal was zu deinem Quellcode fragen.
    Mir ist da was aufgefallen und zwar taktest du den µC mit dem internen RC-Oszillator auf 16 Mhz.
    Ich jedoch kann meinen Mega32 nur auf 8 Mhz taktet. Diese Seite unterstützt meine These.
    Wäre nett, wenn du mich aufklären könntest.

    Theorie ist wenn man alles weiß, aber nichts funktioniert. Praxis ist wenn alles funktioniert, aber niemand weiß warum.
    Microsoft vereint Theorie und Praxis: Nichts funktioniert und niemand weiß warum. :D

  • Mit einem externen. Das ist mir auch klar.
    Du schreibst aber in deinem Quellcode, dass du den internen nutzt. Den gibt es jedoch nicht. Der geht nur bis 8 Mhz.

    Theorie ist wenn man alles weiß, aber nichts funktioniert. Praxis ist wenn alles funktioniert, aber niemand weiß warum.
    Microsoft vereint Theorie und Praxis: Nichts funktioniert und niemand weiß warum. :D

  • Hallo,


    mit einem Widerstand alleine entprellt man nicht, da setzt man nur definierte Pegel fest. Um zu entprellen brauchst du zwingend entweder einen passenden Kondensator parallel zum Pulldown, oder du entprellst in Software. Soweit ich weiß (ich selber programmiere nicht in Bascom) gibt es in Bascom eine eigene Funktion zum Tasten entprellen.


    Grüße


    Fasti

  • Hallo,


    das is natürlich schlecht. Aber man könnte es ja anders machen, man wertet im, ich nenne es jetzt einmal Taster-Interrupt, den Tastendruck aus, mit Zähler und allem sonstigen pipapo und nutzt einen zB freien Timer Interrupt dann, um das eigentlich gewünschte zu tun. Man setzt quasi am Ende der Tastenauswertung das Interrupt-Flag und macht den eigentlichen Programmablauf in dem "missbrauchten" Interrupt.


    Grüße


    Fasti


    PS: Konventionelle Methoden gibt es da ja auch noch zu Hauf.