mikrocontroller.net

Forum: Compiler & IDEs Interruptrotine: cli(); funzt nicht


Autor: Tom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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
  }
    }

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kennst den Unterschied zwischen INTERRUPT und SIGNAL?
Falls nicht: benutze SIGNAL...

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch mit SIGNAL kein disablen möglich.
Gibs zwischen SIGNAL und INTERRUPT einen Unterschied?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

bei einem reti wird das globale Interrup Flag immer gesetzt. cli(); hat
in einer ISR deshalb keine Wirkung.

Matthias

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
:)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.