www.mikrocontroller.net

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


Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
char data;

if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
  data = USART_ReceiveData(USART1);
  xputc(data);
}

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

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


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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  Hc Zimmerer,

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

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

Viele Grüße
Klaus

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hc Zimmer,

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

Viele Grüße
Klaus

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus (Gast)
Datum:

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

Danke!

Autor: tsag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (data == '$') {

Autor: Markus Müller (mmvisual)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
  Result = 0;
  Result = 10 * Result + Buffer[0] = 10 * 0 + 5 = 5
  Result = 10 * Result + Buffer[1] = 10 * 5 + 1 = 51
  Result = 10 * Result + Buffer[2] = 10 * 51 + 0 = 510
  //....

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

Autor: DerTom (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.