UART Zeichenkette empfangen aber ohne pollen

Gast #992570
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
Gast #992573
>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.
Gast #992588
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?
Persönliche Seite #992611
Also ich würde in der ISR erstmal das RXFlag prüfen!
Sonst haut dir die ISR ggf mit neuen Daten dazwischen.
1
SIGNAL(UART1_RECEIVE_INTERRUPT) {
2
    if(RX1flag == 0) {
3
        if (UART1_DATA == 0x02) {
4
            RX1_index = 0;
5
        }
6
        RX1_buf[RX1_index++] = UART1_DATA;
7
        if (UART1_DATA == 0x03)    {
8
            RX1flag = 1;
9
        }
10
    }
11
}
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!
#992621
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.
>
>
1
SIGNAL(UART1_RECEIVE_INTERRUPT) {
2
>     if(RX1flag == 0) {
3
>         if (UART1_DATA == 0x02) {
4
>             RX1_index = 0;
5
>         }
6
>         RX1_buf[RX1_index++] = UART1_DATA;
7
>         if (UART1_DATA == 0x03)    {
8
>             RX1flag = 1;
9
>         }
10
>     }
11
> }

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.
Gast #992622
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?
Gast #992628
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?
Persönliche Seite #992675
> 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 ;)
1
SIGNAL(UART1_RECEIVE_INTERRUPT) {
2
    char data = UART1_DATA;
3
    if(RX1flag == 0) {
4
        if (data == 0x02) {
5
            RX1_index = 0;
6
        }
7
        RX1_buf[RX1_index++] = data;
8
        if (data == 0x03)    {
9
            RX1flag = 1;
10
        }
11
    }
12
}

So besser? :)
Gast #992744
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.
#992842
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

Eine eigene Frage? Dieser Thread ist über 18 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.