Interruptrotine: cli(); funzt nicht

Gast #178268
Hallo,

hab das unten aufgeführte Programm gschrieben.
Leider kann ich die Pin-changed Interruptrotine nicht disablen.
Müsste doch mit cli(); funktionieren.
Leider durchläuft er bei einem Interrupt die Rotine desöfteren.
Die Tasten sind nicht entprellt, möchte ich hinzufügen, was jedoch egal
sein müsste, da man ja beim ersten Durchlauf der ISR der Interrupt
disabled wird.

Bin über jeden Tip dankbar.

Im Voraus Danke!

Grüsse Tom

#include <avr\io.h>
#include <avr\signal.h>
#include <avr\interrupt.h>
#include <stdlib.h>
#include "init.h"
#include "display_4bit.h"

char nummer = 0;
BYTE nummer_buffer[2]={'0','0'};

INTERRUPT(SIG_PIN_CHANGE1)
    {
  cli( );
  nummer++;
    }

void Byte2Ascii(BYTE array[2],BYTE zahl)
    {
    array[0]= (zahl%10)|0x30;  // |0x30 für Ascii-Umwandlung
    array[1]= (zahl/10)|0x30;  // |0x30 für Ascii-Umwandlung
    }

void main (void)
    {
    DDRC=0x00;
    lcd_init();
    lcd_command_out(lcd_on);// Display ein
    sbi(PCICR, PCIE1); // PIN-CHASNGE-Interrupt aktivieren
    PCMSK1=0xFF;       // alle Eingängedes PortC für ISR aktivieren
    sei();         // Interrupts zulassen
    for (;;)          // Endlosschleife
        {
  lcd_string_out("Interuptnr. ",1);
        lcd_position_set(1,14);
  Byte2Ascii(nummer_buffer,nummer);
        lcd_data_out(nummer_buffer[1]); //Anzahl Durchläufe derISR
        lcd_data_out(nummer_buffer[0]); //Anzahl Durchläufe derISR
  }
    }
Angehängte Dateien:
Gast
Du solltest auch nicht das Globale-Interruptflag löschen, sondern den
Pin-Change-Interrupt ausschalten:

[..]
  PCICR &= ~(1 << PCIE1);
[..]

Und: Ja! Es gibt einen gewaltigen Unterschied zwischen INTERRUPT und
SIGNAL, steht aber genauestens in der Doku der avr-libc beschrieben...
Da steht übrigens auch, daß sbi/cbi und Co abgekündigt sind, also nicht
mehr verwenden. Lieber gleich an die "richtige" Schreibweise gewöhnen
:)
cli() funktioniert und tut genau das, was es soll: alle Interrupts
disablen.

Und es tut auch nicht einen Fatz mehr, d.h. es setzt keine
Interruptflags zurück.
Wäre ja auch schlimm, dann könnte man nämlich keine Interrupts pollen
oder würde Interrupts verlieren.


Anders gesagt, wenn ein Interruptflag ausgelöst wurde und Du führst
nach 10 Jahren ein sei() aus, dann wird der Interrupt auch schön
abgearbeitet, genau wie es sein soll.

Will man das nicht, dann muß man vor der Freigabe das Interruptflag
löschen (auf 1 setzen).


Der Pin-Change Interupt ist bei den meisten AVRs ziemlich witzlos. Man
kann nicht die Pins auswählen und auch nicht erkennen, welcher Pin ihn
ausgelöst hat.
Er eignet sich daher nur zum Aufwachen des AVRs. Und nach dem Aufwachen
sollte man ihn sofort disablen, will man nicht mit Interrupts zugebombt
werden.


Peter
Gast
> cli() funktioniert und tut genau das, was es soll: alle Interrupts
> disablen.

Klar, aber innerhalb einer ISR ist das eine teure Form eines NOPs: die
Interrupts sind bereits abgeschaltet, und sie werden beim RETI
wieder zugeschaltet, unabhängig davon, wie viele Male der
Programmierer zwischendrin das bereits gelöschte Interruptflag nochmal
gelöscht hat.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.