www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anweisung für Interrupt


Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wie kann ich ein Interrupt zu einem bestimmten Zeitpunkt erst starten?
z.B. nach einer Switch Anweisung.

Hab zwei Interrupts in meinem Programm. Das eine wird gestartet sobald
das UART Receive Flag gesetzt wird, also Daten ankommen. Da hab ich
dann eine Switch Anweisung das je nach ankommenden Wert etwas
ausgeführt wird. Kann ich in der Switch Anweisung auch angeben, das bei
einem bestimmten Wert erst das andere Interrupt gestartet wird....??

Autor: Bernhard S. (bernhard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kein Problem, Du gibst erst den entsprechenden Interrupt frei, wenn Du
Ihn benötigst.

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Björn,

DU startest keinen Interrupt. Nie. Sondern irgendein Hardware-Ereignis
wie eben ReceiveComplete.
In dieser Interrupt zu warten, bis irgendein ein anderes externes Gerät
etwas tut, wäre ziemlich unzweckmäßig, da wäre der Prozessor vielleicht
sehr lange in Wartestellung.

Sondern Du holst das Zeichen nur ab und bist wieder in der
Main-Routine.
Schau Dir ein paar Beispiel-Programmme an.

Ciao
Wolfgang Horn

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber mit welchem Befehl kann ich einen bestimmten Intterupt
freigeben...??

Ist bestimmt jetzt voll simpel, aber ich kapier oder weiß es
nicht.....!!

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Björn,

indem Du im UCSRnB beispielsweise RXCIEn: RX Complete Interrupt Enable
setzt.
Bei der Initialisierung muß noch mehr passieren, Du findest
Beispielprogramme im Datenblatt zu den Atmega.

Ciao
Wolfgang Horn

Autor: ecslowhand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht mit Befehlen, sondern mit setzen entsprechender Flags.

Du setzt ja auch bei der UART-Geschichte das RXCIE-Flag, also das Flag,
das einen IRQ auslöst, wenn ein Zeichen im Empfangsbuffer vorhanden
ist.

LG EC

Autor: ecslowhand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist...Wolfgang war schneller.....

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Aber mit welchem Befehl kann ich einen bestimmten Intterupt
freigeben...??"

Mit garkeinem.

Jede Interruptquelle hat in ihren Konfigurationsregistern ein
Enable-Bit, das mußt Du setzen.


Peter

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

also das mit den Flags beim UART funktioniert und hab ich auch
verstanden. Senden und empfangen klappt beides wunderbar.

Nun wollte ich noch ein Blinklicht dazu nehmen, welches bei einem
bestimmten über UART empfangenen Wert anfängt zu blinken.

Das hab ich so gemacht:

SIGNAL(SIG_OUTPUT_COMPARE1A)
{
    uint16_t count;

    // irq_count um 1 erhöhen und...
    count = 1+irq_count;

    // ...alle 1000 IRQs die LED blinken
    if (count >= INTERRUPTS_PER_SECOND)
    {
        count = 0;
        PORT_LED ^= (1 << PAD_LED);
    }

    irq_count = count;
}

Das Blinken funktioniert auch, nur leider die ganze Zeit. Die LED soll
aber erst blinken, wenn ein entsprechendes Zeichen gsendet wird!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.:

Das heißt aber nicht, daß dann erst die Interruptquelle aktiv wird.

Kam ein Interruptereignis (z.B. Byte empfangen) und Du setzt erst nach
10 Jahren das Enable-Bit, dann kriegst Du auch sofort den Interrupt auf
das Ereignis von vor 10 Jahren.

Will man das nicht, muß man unmittelbar vor der Freigabe erst das
Interrupt-pending-bit löschen, was bei den AVRs blöderweise Bit setzen
bedeutet (beliebte Fallgrube für 100% aller AVR-Anfänger).


Peter

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das Blinken funktioniert auch, nur leider die ganze Zeit. Die LED
> soll aber erst blinken, wenn ein entsprechendes Zeichen gsendet
> wird!

In dem konkreten Fall hast du 2 Möglichkeiten.

Warum blinkt denn die LED?
Weil da ein Timer läuft der stänidg hochzählt und
irgendwann das Output Compare Ereignis auslöst. Bei der
Behandlung dieses Ereignisses wird dann das Blinken
geregelt.

Möglichkeit 1:
  Wenn der Timer nicht läuft, tritt auch kein Output Compare
  auf und folgerichtig blinkt auch keine LED.

  Jetzt schau dir nochmal an, wie du den Timer initialisiert hast.
  Irgendwann hast du mal den Vorteiler für den Timer eingestellt.
  Dann nochmal Blick ins Handbuch: Es gibt eine bestimmte Stellung
  der Vorteiler-Bits, die bewirken, dass der Timer nicht läuft.
  Wenn das Programm hochfährt stellst du genau das ein: Timer
  läuft nicht -> LED blinkt nicht. Kommt dann das Zeichen über
  die UART wird der Vorteiler eingeschaltet, der Timer läuft,
  die Output Compare Ereignisse kommen durch -> LED blinkt

Möglichkeit 2:
  Mann muss ja nicht gleich mit Kanonen auf Spatzen schiessen.
  Der Timer kann ja durchaus laufen, nur sollen halt die Output
  Compare Ereignisse keinen Interrupt auslösen.
  Wieder: Beim Hochfahren hast du irgendwann das Bit im
  Konfigurationsregister gesetzt, dass dem µC mitteilt, dass er
  bei Auftreten des Output Compare Ereignisses die Interrupt
  Funktion anspringen soll.
  Das nimmst du dort weg und setrzt dieses Bit erst dann, wenn über
  die UART das entsprechende Zeichen angekommen ist.

Eigentlich ganz einfach, oder?

  Vorteiler

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, war echt ganz einfach....!!!

Hat sofort geklappt....!!

Nur soll die LED, wenn die Taste erneut gedrückt wird auch wieder
ausgehen.....

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nur soll die LED, wenn die Taste erneut gedrückt wird auch wieder
> ausgehen.....

Das sollte jetzt aber kein Problem mehr sein :-)
Du machst einfach alles rückgängig, was du beim Einschalten
gemacht hast.

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, ne if Abfrage und nun klappt alles bestens.....!!!

Wie kann ich diese Stück umschreiben?

void moveservo(char pos)
{
  for(int yy=0;yy<7;yy++)
  {
    PORTB=1;              for(int i=0;i<pos;i++)
    delay_20us();

    PORTB=0;
    for(int i=0;i<(1500-pos);i++)              delay_20us();
       }
}

Krieg immer ne Fehlermeldung.....

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> for(int i=0;i<pos;i++)
In ANSI-C müssen Variablen am Anfang eines Blocks deklariert werden.
Also besser:
void moveservo(char pos)
{
    int i, yy;
    for(yy = 0; yy < 7; yy++)
    {
        PORTB = 1;
        for(i = 0; i < pos; i++)
            delay_20us();
    //usw...
    }
}

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke,

bekomme aber immer noch diese Fehlermeldung:

../Servo.c:83: Fehler: Anfangsdeklaration in »for«-Schleife
außerhalb C99-Modus verwendet

Hab schon versucht das Makefile zu ändern..... klappt aber nicht...!!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst aus allen for-Schleifen die Variablendeklarationen rausnehmen
oder im Makefile c99 einstellen, dann gehts auch so...

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.