Forum: Mikrocontroller und Digitale Elektronik STM32 - UART - Zeichen für Zeichen auswerten - Unmöglich? (Zeichenlängen pro char von 1-34.)


von Klaus (Gast)


Lesenswert?

STM32 - UART - Zeichen für Zeichen auswerten - Unmöglich? (Zeichenlängen 
pro char von 1-34...)

Hallo,

arbeite gerade mit einem GPS, dieser Code
1
char data;
2
3
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
4
  data = USART_ReceiveData(USART1);
5
  xputc(data);
6
}

hat diesen Output (GPS hat grad keinen Empfang, aber gut)
1
.....
2
$GPRMC,192655.000,V,,,,,0.00,204.48,040910,,,N*47
3
$GPVTG,204.48,T,,M,0.00,N,0.00,K,N*38
4
$GPGGA,192656.000,,,,,0,0,,,M,,M,,*47
5
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
6
$GPGSV,3,1,11,24,82,054,,19,80,258,15,03,56,160,24,22,50,067,*78
7
$GPGSV,3,2,11,06,44,146,,11,23,274,,14,20,120,,18,19,049,27*70
8
$GPGSV,3,3,11,28,15,325,,32,14,206,,08,03,297,*44
9
$GPRMC,192656.000,V,,,,,0.00,204.48,040910,,,N*44
10
$GPVTG,204.48,T,,M,0.00,N,0.00,K,N*38
11
......

Zeige ich mir dazu noch pro empfangen data char, die char länge an,
1
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
2
  data = USART_ReceiveData(USART1);
3
  xputc(data);
4
  printf("%d\r", strlen(&data));
5
}

ist demnach das ganze völlig unbrauchbar. Zeichen fehlen,
Zeichenlänge von 1-34 usw.

.....
, 2
, 2
4 3
3 2
 2
$ 2
P 2
G 2
A 2
, 7
, 2
1 2
, 2
, 2
, 1
, 2
, 2
, 2
, 1
, 1
, 2
, 2
* 2
1 2

 2
 2
G 2
P 2
S 1
V 34
3 2
, 2
, 2
1 2
1 2
2 2
4 2
8 1
.....


Ist das allgemein bei einem UART Empfang so?
Zeichenfolgen finden usw. on the fly geht nicht?

(STM32, GPS = Mediatek 3329, Compiler = gcc).

Über Hilfe würde ich mich sehr freuen.

Vielen Dank & Mfg
Klaus

von Hc Z. (mizch)


Lesenswert?

1 char ist immer genau ein Zeichen lang.  Da es ein char und kein String 
(char[]) ist, ist es auch sinnlos, die Adresse davon zu nehmen und 
strlen() darauf loszulassen.

von Klaus (Gast)


Lesenswert?

Ein Nachtrag, da fällt mir ein das prinf() ggf. zu lange dauert,
um das in den Uart zu schreiben. Würde die fehlenden Zeichen erklären.

Aber was könnte noch alles in einem UART Byte stecken?
Kann man vielleicht alle möglichen \n und \r filtern?

von Klaus (Gast)


Lesenswert?

Hallo  Hc Zimmerer,

Vielen Dank, nur warum kommt da nicht 1 raus.
Ich hatte versucht zuvor mit:
1
 if (strcmp(&data, "$") == 0) {
2
     xputc(data);
3
 }

aber das nicht möglich. (Ganz selten hat er
was gefunden, würde zu strlen 1 passen)...
Hmmm

Viele Grüße
Klaus

von Hc Z. (mizch)


Lesenswert?

Weil data ein char ist und kein String.  Du lässt aber Funktionen, die 
für Strings gedacht sind, auf dieses char los.  Da kann nur Mist 
rauskommen, aus dem sich keine Schlüsse ziehen lassen.

Strings sind nullterminierte char-Arrays, also Folgen von 0 oder 
mehreren chars, abgeschlossen durch ein char, das den Wert 0 (\0) hat.

Auf der anderen Seite ist außer in einem Einzelfall ein einzelnes char 
nie ein String.  Der Einzallfall ist dann gegeben, wenn das char den 
Wert 0 (\0) hat. Dann ist es auch ein gültiger String der Länge 0.

Ein (fast beliebiges) C-Buch oder ein grundlegender Text dazu sollten 
weiterhelfen.

von Klaus (Gast)


Lesenswert?

Hallo Hc Zimmer,

vielen Dank, das wußte ich nicht.
Ich mache mich mal mit chars schlau.

Viele Grüße
Klaus

von spess53 (Gast)


Lesenswert?

Hi

>Strings sind nullterminierte char-Arrays, also Folgen von 0 oder
>mehreren chars, abgeschlossen durch ein char, das den Wert 0 (\0) hat.

Und ein NMAE-String wird mit CR/LF abgeschlossen.

MfG Spess

von Hc Z. (mizch)


Lesenswert?

Klaus schrieb:
> Ich mache mich mal mit chars schlau.

Viel Erfolg.  Grundlagen sind manchmal trocken, aber man macht sich nur 
unnötige Arbeit, wenn man sie nicht hat.

von Klaus (Gast)


Lesenswert?

super jetzt läufts :)
1
if (data == 0x24) { // entsprich $
2
    xputc(data);
3
}
http://de.wikipedia.org/wiki/ASCII

Danke!

von tsag (Gast)


Lesenswert?

1
if (data == '$') {

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

@Klaus
Baue Dir ein Buffer-System auf.

Rx von GPS löst interrupt aus und schreibt die Zeichen in ein RX-Buffer

Dein Main-Task holt diese Zeichen vom Buffer wieder ab und wertet irgend 
was aus.

Dadurch kann die Software nichts verlieren, auch wenn der Main-Task mal 
länger in einer Schleife warten sollt. Garantiert wird der RX-Interrupt 
mit GPS aufgerufen und zwischengespeichert.
Noch besser ist es, wenn man die Routinen so programmiert, dass es 
niemals ein Warten im Code gibt. (xputc wartet solange bis der TX-Buffer 
der Debug-Ausgabe frei ist!)

Also: wirf den xputc weg und mache ein Buffer-System, das die Zeichen 
des Debug-Buffers auch Asynchron, per Interrupt aus gibt.

Ich habe in meinen Programmen locker 5000-15000 Main-Loop durchläufe je 
Sekunde (bei 8MHz Clock!). Diese Zahl beobachte ich immer. Wenn sie bei 
einer Programmänderung drastisch runter geht, dann hab ich irgendwo ein 
"Klemmer", "Wait" oder einfach eine komplexe Bearbeitung rein gemacht 
und ich weiß ich muß den Code optimieren.

von spess53 (Gast)


Lesenswert?

Hi

>Rx von GPS löst interrupt aus und schreibt die Zeichen in ein RX-Buffer
>Dein Main-Task holt diese Zeichen vom Buffer wieder ab und wertet irgend
>was aus.

Wozu? Ein NMEA-String beginnt immer mit '$'. Diese Erkennung kann man 
locker im Interrupt machen. Danach wird alles bis CR/LF in einen Puffer 
geschrieben. Fertig.

MfG Spess

von Klaus (Gast)


Lesenswert?

Hallo,

zu peinlich "$" und '$' macht ja wirklich einen Unterschied :)
Hatte eigentlich vor alles on-the-fly zu machen.
Breitengrad, Längengrad, Höhe, usw. alles interessante hochrechnen,
nach dem Muster:
1
  Result = 0;
2
  Result = 10 * Result + Buffer[0] = 10 * 0 + 5 = 5
3
  Result = 10 * Result + Buffer[1] = 10 * 5 + 1 = 51
4
  Result = 10 * Result + Buffer[2] = 10 * 51 + 0 = 510
5
  //....

da mein ggc compiler atoi() nicht akzeptiert.

Ich werds einfach mal versuchen. STM32 ist flott und das Wichtige
unterbricht den Interrupt auch (in der NVIC weit hinten). xputc(data)
ist nur zum Debuggen.

Vielen Dank & Viele Grüße
Klaus

von DerTom (Gast)


Lesenswert?

Wieso akzeptiert dein gcc atoi() nicht?
Bei mir funktioniert das schon. Hast du -lc und -lgcc in der makefile?

von Karl H. (kbuchegg)


Lesenswert?

DerTom schrieb:
> Wieso akzeptiert dein gcc atoi() nicht?


WEil er den Unterschied zwischen einem einzelnen Zeichen und einem 
String immer noch nicht kapiert hat. Von einem layered Softwareaufbau, 
bei dem sich höhere Funktionen auf den Service von tiefer liegenden 
Softwareschichten stützen reden wir erst mal gar nicht.

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.