Probleme beim parsen von UART string

OP #4617351
Lesenswert?
• ▲
▼
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:
(Firma: Schweigstill IT) Persönliche Seite #4617421
Lesenswert?
• ▲
▼
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren