Probleme beim parsen von UART string

OP #4617351
Hi,

Ich kämpfe jetzt schon seit zwei Tagen damit die empfangene Zeichenkette 
von einem GPRS Modul (SIM900 via uart) zu parsen. Wobei es hier nur mal 
darum geht bis zum CR/LF zu lesen und dann auszugeben. Vielleicht findet 
jemand von euch den Fehler. Im Anhang findet ihr meine uart Routinen, 
die ich hier verwende.

Prinzipiell wird bei jeder Eingabe am Computer via Terminal (via uart0) 
die Zeichenkette "AT+CSQ" an das GPRS Modul geschickt und dann die 
empfangenen Zeichen zurück ans Terminal geschrieben.

Setzt man das WORKING define auf 1, wird zeichenweise mit usart_getc() 
ausgelesen und man sieht am Terminal folgendes:
1
AT+CSQ
2

3
+CSQ: 4,0
4

5
OK

Das ist die korrekte Antwort laut Datenblatt. Jetzt versuche ich via 
usart_read() immer eine komplette Zeile zu lesen (WORKING auf 0 setzten) 
um diese in eckiger Klammer auszugeben. Da kommt dann folgendes daher:
1
[AT+CSQ]
2
[]
3
[Q: 4,0]
4
[]
5
[]

Die erste Zeile passt. Die zweite ist auch OK weil nur CR/LF aber dann 
kommt alles durcheinander. In der dritten Zeile werden Zeichen am Anfang 
abgeschnitten (nicht gelesen?) und das "OK" kommt nie an.

Bitte schaut mal meinen code durch - vielleicht fällt auch was auf. Der 
Fehler muss irgendwo in meinen Leseroutinen vom UART sein.


Hier meine main routine:
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
#include "usart.h"
5

6
#define WORKING 1
7

8
uint8_t tmp;
9
char buff2[64];
10

11
int main(void) {
12
    usart_init(USART0, 9600L);
13
    usart_init(USART1, 9600L);
14

15
    while (1) {
16
        
17
        if( usart_rx_available(USART0) ) {
18
            tmp = usart_getc(USART0);
19
            usart_write(USART1,"AT+CSQ\r\n");
20
        }
21
        
22
#if WORKING
23
        if (usart_rx_available(USART1)) {
24
            tmp = usart_getc(USART1);
25
            usart_putc(USART0, tmp);
26
        }
27
#else
28
        while( usart_rx_available(USART1) ) {
29
            usart_read(USART1, buff2, sizeof(buff2));
30
            
31
            usart_putc(USART0,'[');
32
            usart_write(USART0,buff2);
33
            usart_write(USART0,"]\r\n");
34
        }
35
#endif
36
    }
37
}

Danke,
Max
Angehängte Dateien:
#4617370
Dieses Vorgehen ist Schrott. Mit blockierend Lesen und Schreiben ist 
nichts. Vergiss das schnell mal. Das Standardvorgehen nennt man 
Zustandsmaschine. Eine zum Lesen und eine zum Schreiben. Ob mit oder 
ohne Interrupt kann man immer noch festlegen.
(Firma: Schweigstill IT) Persönliche Seite #4617421
Markus M. schrieb:
> OK. Heisst ich soll zuerst mal alles rausschreiben und dann erst
> einlesen?

Nein, das wäre exakt das Gegenteil von dem angesprochenen 
Zustandsautomaten.

Sinnvollerweise sollte die Kommunikation in beiden Richtungen 
zeichenweise erfolgen, wenn nicht durch die Puffergrößen des USARTs und 
ggf. eines Interrupthandlers sichergestellt wird, dass kein empfangenes 
Zeichen abhandenkommen kann, während der Sendevorgang nicht 
abgeschlossen ist.

Eine mögliche Vorgehensweise besteht darin, einen lokalen 
Nachrichten-FIFO anzulegen, in den Ereignisse wie z.B. ein empfangenes 
Zeichen oder auch andere externe Ereignisse eingetragen werden. 
Anschließend lässt man einen Zustandsautomaten auf diesen FIFO los, der 
die Ereignisse herausholt, abarbeitet und ggf. neue Ereignisse 
hinzufuegt. Sobald der FIFO leer ist, wird die Bearbeitung beendet, und 
das ganze Spiel beginnt von vorne.

Es gibt aber auch noch Unmengen anderer Realisierungsmöglichkeiten für 
Zustandsautomaten.

Antwort schreiben

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