Anweisung für Interrupt

Gast #351495
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....??
Gast #351497
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
Gast #351499
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
Gast #351500
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
Gast #351503
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!
#351504
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
#351505
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
Gast #351508
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.....
Gast #351509
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...
    }
}
Gast #351510
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...!!

Antwort schreiben

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.

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.