Forum: Compiler & IDEs UART Empfangen mit Lib von P. Fleury


von Bart (Gast)


Lesenswert?

Hallo,
ich versuche einen String mit der Lib von P. Fleury zu empfangen und 
habe mir dazu folgende Funktion geschrieben, die jede Sekunde einmal 
aufgerufen wird:
1
void uart_gets()
2
{
3
  char string[20];
4
  int i=0;
5
  if(uart_getc() != UART_NO_DATA)
6
  {
7
  do {
8
    string[i] = uart_getc();
9
    i++;
10
    }while(uart_getc() != '\0');
11
  uart_puts(string);
12
  }
13
}
Es wird leider immer nur das 2 und das 4 Zeichen zurückgeschickt, kann 
mir jemand weiterhelfen?
Grüße
Bart

von Andreas R. (rebirama)


Lesenswert?

schau dir nochmal an, was genau uart_getc macht...
in der 5. zeile wird nämlich das erste zeichen verworfen
und in der 10ten das dritte.

von Bart (Gast)


Lesenswert?

Ja ich habe mir das angeschaut, lower byte enthält den char, higher byte 
zb einen Fehler oder halt 0.
1
void uart_gets()
2
{
3
  char string[20];
4
  int i=0;
5
  if(!(uart_getc() &UART_NO_DATA)) //So besser?
6
  {
7
  do {
8
    string[i] = uart_getc();
9
    i++;
10
    }while(uart_getc() != '\0');
11
  uart_puts(string);
12
  }
13
}
Weiss nciht so genau auf was du anspielt, hab eine Sache verändert aber 
das hilft auch nicht.

von Bart (Gast)


Lesenswert?

Habs ;) Danke für den Tip, mit dem ersten getc hole ich mir ja schon ein 
Byte aus dem ringbuffer.

von Jörg G. (joergderxte)


Lesenswert?

Was rebirama meint:
1
void uart_gets()
2
{
3
  char string[20];
4
  int i=0;
5
  if(!(uart_getc() &UART_NO_DATA)) /* WENN Daten da sind, verlierst du hier 
6
                                      ein Datenbyte */
7
  {
8
  do {
9
    string[i] = uart_getc();
10
    i++;
11
    }while(uart_getc() != '\0');  /* Und hier nochmal */
12
  uart_puts(string);
13
  }
14
}
Du wlst wohl eher sowas:
1
void uart_gets(void) //Leere Klammern bedeuten in C 'int' parameter
2
{
3
  char buffer[20];
4
  uint16_t i=0, data;
5
  while(!( (data = uart_getc()) & UART_NO_DATA)) { // Datenbyte speichern
6
    buffer[i] = data;           // Highbyte geht verloren, ggf. cast'en
7
    ++i;
8
    if( (data & 0xff != '\0') ) // Ganzer string empfangen?
9
      break;
10
  }
11
  uart_puts(buffer);
12
}
hth, Jörg

von Stefan E. (sternst)


Lesenswert?

Jörg G. schrieb:

> Du wlst wohl eher sowas:

Und wenn man dann noch das "!=" durch ein "==" ersetzt, könnte es sogar 
funktionieren. ;-)

Zumindest gelegentlich, denn wenn die Funktion aufgerufen wird, während 
die Übertragung gerade im Gange ist, hat man in buffer die bisher 
empfangenen Daten, aber ohne Null-Terminierung. Und wenn sie aufgerufen 
wird, ohne das irgendwelche Daten empfangen wurden, ist ebenfalls keine 
Null-Terminierung vorhanden. Das ist natürlich jeweils schlecht für das 
"uart_puts(buffer);".

von Jörg G. (joergderxte)


Lesenswert?

> Und wenn man dann noch das "!=" durch ein "==" ersetzt, könnte es sogar
> funktionieren. ;-)
Ups!

OK, Die Funktion funktioniert so, wie ich sie geschrieben habe, nicht: 
Sobald alle Bytes aus dem Puffer gelesen wurden, werden sie unterminiert 
gesendet, d.h. alle Bytes aus dem RAM bis irgendwo eine 0 steht.
Also nochmal
1
char *uart_gets(const char *buffer, size_t buf_len)
2
{
3
  do {
4
    while ((data = uart_getc()) & UART_NO_DATA)
5
    {}  // auf Daten warten
6
    buffer[i] = data;
7
    ++i;
8
    if (i== buf_len) break;
9
  while( (data & 0xff) != 0); // Endlosschleife, falls kein 0-Byte kommt
10
                              // '\n' waere evtl. als Trenner besser
11
  if (i == buf_len) buffer[i-1] = '\0'; //'Notfall'-terminierung
12
  return buffer;
13
}
uups, Jörg

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.