www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Zeichenkette empfangen aber ohne pollen


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich habe zwei AVRs - ein Controller soll dem anderen Controller seine 
Meßwerte übermitteln, damit dieser sie auf sein Display schreiben kann. 
Ein Telegramm soll dabei ungefähr aussehen STX[Meßwert]ETX.
Alla gud - das senen der Info kein Problem, klappt auch nur am Empfang 
beiß ich mir schier die Zähne aus, WEIL der µC mit dem Display, der die 
Info empfangen soll auch noch Tasten, LEDs und so bedienen soll. Sprich 
ich kann nicht im Hauptprogramm einfach warten bis ein STX weil das ja 
dann alls blockieren würde. Also hab ich versucht im Interrupt des UART 
auf ein STX zu warten und dann jedes weiter neue Zeichen in ein Array zu 
schreiben bis ein ETX kommt ... das macht wenn es etwas macht nur 
komische Sachen.
Hat jemand eine praktische Idee wie man eine Zeichenkette empfängt und 
dabei auch noch etwas anderes tun kann, vielleicht mit Beispiel :)?
Danke vorab.
Gruß Jens

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das macht wenn es etwas macht nur komische Sachen.
Dann solltest Du das Teil mal zügeln.

Im Grunde ist das mit den Interrupts der richtige Ansatz. Was besseres 
gibt es nicht. Vielleicht sollte man aber diese Prüfung auf STX/ETX 
nicht im Interrupt machen. Protokoll hat erstmal nichts mit dem Empfang 
zu tun.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay, das mit dem zügeln hört sich gut an:

meine ISR:

SIGNAL(UART1_RECEIVE_INTERRUPT)
{
  if (UART1_DATA == 0x02)
    {
      RX1_index = 0;
    }

  RX1_buf[RX1_index] = UART1_DATA;
  RX1_index++;

  if (UART1_DATA == 0x03)
    {
      RX1flag = 1;
    }

im HP:

    if (RX1flag == 1)
  {
           _delay_ms(4);
    for (i = 0; i < 32; i++)
      {
                   uart1_putc(RX1_buf[i]);
                   RX1_buf[i] = 0;
             }
   RX1flag = 0;
   _delay_ms(500);
  }

ich sende mit hterm STX 0 1 2 3 ETX
als Antwort bekomme ich
ETX STX 0 1 2 3 NULL NULL ... NULL
das is das 1. komische Phänomen ... drüberhinaus nach einem Reset bleibt 
das erste senden ohne Ergebnis ... verstehts jemand?

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich würde in der ISR erstmal das RXFlag prüfen!
Sonst haut dir die ISR ggf mit neuen Daten dazwischen.
SIGNAL(UART1_RECEIVE_INTERRUPT) {
    if(RX1flag == 0) {
        if (UART1_DATA == 0x02) {
            RX1_index = 0;
        }
        RX1_buf[RX1_index++] = UART1_DATA;
        if (UART1_DATA == 0x03)    {
            RX1flag = 1;
        }
    }
}
Das gleiche habe ich auch gerade gemacht zur auswertung eines GPS 
Empföngers(allerdings in ASM).
Desweiteren solltest du sicherstellen das RX1_index nicht größer als 
dein Array werden kann und korrekt initialisiert ist!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läubi Mail@laeubi.de wrote:
> Also ich würde in der ISR erstmal das RXFlag prüfen!
> Sonst haut dir die ISR ggf mit neuen Daten dazwischen.
>
>
SIGNAL(UART1_RECEIVE_INTERRUPT) {
>     if(RX1flag == 0) {
>         if (UART1_DATA == 0x02) {
>             RX1_index = 0;
>         }
>         RX1_buf[RX1_index++] = UART1_DATA;
>         if (UART1_DATA == 0x03)    {
>             RX1flag = 1;
>         }
>     }
> }

Sorry, aber das ist seeehr "suboptimal". Wenn im Interrupt das 
Datenregister nicht ausgelesen wird, wird der Interrupt nach nur einem 
Asm-Befehl gleich wieder aufgerufen.

@ Jens:

Außerdem würde ich das Datenregister im Interrupt nur einmal auslesen, 
und nicht gleich dreimal.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also sowohl in meinem Code als auch in den Änderungen oben versteh ich 
eins mal gar ned, ich sende mit dem Computer STX 0 1 2 ... ETX und 
direkt nach dem Senden müßte das Echo ja auf dem Computer empfangen 
werden, durch das RX1flag. Macht es aber nicht erst wenn ich wieder STX 
blabla ETX sende, dann erscheint auf meinem Notebook das vorhergehende 
Telegram, das kann doch gar ned sein, aber ist reproduzierbar, wieso?

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay:
data = UART1_DATA;   // Zeichen kopieren
und mit data weiterarbeiten - schon funktionierts wie erwartet ... im HP 
wird ein Echo der Eingabe sofort nach ETX zurückgeschickt. Allerdings 
würd ich gern verstehen wieso??? Wenn mich jemand nach einer Erklärung 
fragt würde ich sagen, dadurch, daß ich mehrmal das UDR1 abfrage wird 
immer wieder ein Interrupt ausgelöst und das ganze kommt durcheinander?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
siehe Interrupt

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:
> siehe Interrupt

OT:
Wieso gibt es in der Artikelsammlung eigentlich zwei Artikel über 
Interrupts wobei der von Dir genannte Interrupt in dem 
Inhaltsverzeichnis der Artikel scheinbar nicht verlinkt ist. Der Artikel 
AVR-Tutorial: Interrupts dagegen schon. Hmmm..... hier geht soviel 
Wissen unter, weil es einfach noch viel zu unübersichtlich organisiert 
ist. :-(

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Sorry, aber das ist seeehr "suboptimal". Wenn im Interrupt das
> Datenregister nicht ausgelesen wird, wird der Interrupt nach nur einem
> Asm-Befehl gleich wieder aufgerufen.
>
> @ Jens:
>
> Außerdem würde ich das Datenregister im Interrupt nur einmal auslesen,
> und nicht gleich dreimal.

Du hast recht was du über das Datenregister sagst ;)
SIGNAL(UART1_RECEIVE_INTERRUPT) {
    char data = UART1_DATA;
    if(RX1flag == 0) {
        if (data == 0x02) {
            RX1_index = 0;
        }
        RX1_buf[RX1_index++] = data;
        if (data == 0x03)    {
            RX1flag = 1;
        }
    }
}

So besser? :)

Autor: Michael H* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
900ss D. wrote:
> Falk Brunner wrote:
>> siehe Interrupt
>
> OT:
> Wieso gibt es in der Artikelsammlung eigentlich zwei Artikel über
> Interrupts wobei der von Dir genannte Interrupt in dem
> Inhaltsverzeichnis der Artikel scheinbar nicht verlinkt ist. Der Artikel
> AVR-Tutorial: Interrupts dagegen schon. Hmmm..... hier geht soviel
> Wissen unter, weil es einfach noch viel zu unübersichtlich organisiert
> ist. :-(

siehe http://www.mikrocontroller.net/articles/Spezial:Allpages
da die hauptseite der artikelsammlung auch bestandteil des wiki ist, 
kannst du ja deiner meinung nach fehldende artikel in einer diskussion 
beanstanden, oder einfach mit dazusetzen.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H* wrote:
> da die hauptseite der artikelsammlung auch bestandteil des wiki ist,
> kannst du ja deiner meinung nach fehldende artikel in einer diskussion
> beanstanden, oder einfach mit dazusetzen.

Ja stimmt, allerdings ist es schon ungünstig, dass es zwei Artikel über 
Interrupts gibt. Ja ja gut, könnte ich auch ändern :-)
Wenn ich mal Zeit habe (tm)....

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.