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


von Jens (Gast)


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

von Klugscheisser (Gast)


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.

von Jens (Gast)


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?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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!

von Stefan E. (sternst)


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.
>
>
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.

von Jens (Gast)


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?

von Jens (Gast)


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?

von Falk B. (falk)


Lesenswert?

siehe Interrupt

von 900ss (900ss)


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. :-(

von Läubi .. (laeubi) Benutzerseite


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 ;)
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? :)

von Michael H* (Gast)


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.

von 900ss (900ss)


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)....

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.