Forum: Compiler & IDEs UART uart_getc(); in for(;;) Schleife


von chris (Gast)


Lesenswert?

Hallo Leute,
ich brauche mal kurz eure Hilfe. Ich denke das es für ein ein leichtes
sein wird, aber ich habe momentan eine kleine Denkblockade :-)
nun gut, ich verwende die uart.c von Peter Fleury.
Ic möchte über Rs232 ein befehl empfangen, welches in einer for(;;)
loop rennt. sieht ca. so aus....

for(;;)
{
        c = uart_getc();

  if ( c & UART_NO_DATA )
        {
          //no data available from UART
        }
        else
        {
            if ( c & UART_FRAME_ERROR )
            {

                //uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {

                //uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
    //uart_puts_P("Buffer overflow error: ");
            }

  uart_putc( (unsigned char)c );

  command[k]=c;
  k++;

  if(k==4)
  {
  command[k++]='\0';
  k=0;
  uart_puts_P(">");

  if (strcmp(command, "reset") == 0)  //stricmp
         {
  uart_puts_P("reset!");
   }

      }

}

jetzt ist ja das Dilemma, das "k" bei jedem Durchlauf erhöht wird,
was ich ja nicht will, sondern nur wenn ein "neues" Zeichen empfangen
wird um es ins array zu schieben. Kenn mir da  jemand einen guten Tip
geben,wie man das schlau macht.
vielen Dank schon mal

von Volkmar e. P. (keepitsimple)


Lesenswert?

Hi Chris,

ich kenne die Lib zwar nicht, habe mir gerade aber mal das
online-manual angesehen. laut definition wird ein unsigned int
zurückgegeben, bei dem im msb der status festgehalten wird (s.u.). ist
das msb ungleich 0 liegt ein fehler vor, also nur prüfen ob msb == 0

mal ein bisschen schnellhack-code:

if( (c & 0xFF00) == 0 )
  {
uart_putc( (unsigned char)c );

  command[k]=c;
  k++;

  if(k==4)
  {
  command[k++]='\0';
  k=0;
  uart_puts_P(">");

  if (strcmp(command, "reset") == 0)  //stricmp
         {
  uart_puts_P("reset!");
   }
  }

so müsste es gehen.

gruß
volkmar


________________________________________________
#define  UART_FRAME_ERROR   0x0800
#define  UART_OVERRUN_ERROR   0x0400
#define  UART_BUFFER_OVERFLOW   0x0200
#define  UART_NO_DATA   0x0100

von chris (Gast)


Lesenswert?

Hallo Volkmar,

vielen Dank für deine Hilfe. Funzt jetzt super und habe wieder was dazu
gelernt :-)


if( (c & 0xFF00) == 0 )
  {
uart_putc( (unsigned char)c );

  command[k]=c;
  k++;

  if(k==4)
  {
  command[k++]='\0';
  k=0;
  uart_puts_P(">");

  if (strcmp(command, "reset") == 0)  //stricmp
         {
  uart_puts_P("reset!");
   }
  }

cu
chris

von Karl H. (kbuchegg)


Lesenswert?

das hier:
> uart_puts_P(">");
funktioniert sicher nicht. uart_puts_p will einen Pointer
der ins Flash zeigt. ">" wird aber im SRAM angelegt.

Und wie du bei 4 empfangenen Zeichen diese erfolgreich
mit "reset" vergleichen willst ist mir auch nicht ganz klar :-)

von chris (Gast)


Lesenswert?

Hallo :)

<das hier:
<uart_puts_P(">");

doch, das funktioniert. der compiler meldet mir auch keine
Fehlermeldung.

<Und wie du bei 4 empfangenen Zeichen diese erfolgreich
<mit "reset" vergleichen willst ist mir auch nicht ganz klar :-)

warum? ich schiebe jedes empfangene Zeichen in den Array buffer, hänge
ein Nullzeichen dran und vergleiche es mit strcmp. Wenn die Antwort der
function == 0 ist, das ist es gleich.
OK, du hast recht, der compiler meldet mir eine Fehlermeldung zurück,
die ich noch nicht wegbekommen habe, aber es funktioniert definitiv.

cu
chris

von Karl heinz B. (kbucheg)


Lesenswert?

> warum?

Weil "reset" aus 5 Buchstaben besteht!
Das wird bei einem strcmp niemals mit etwas gleich sein,
dass nur aus 4 Buchstaben besteht.

> ich schiebe jedes empfangene Zeichen in den Array buffer
Das tust du nicht. Du schiebst nicht jedes empfangene Zeichen.
Nach dem 4. Zeichen hörst du auf und vergleichst auf "reset".
Wie schon gesagt. "reset" hat 5 Buchstaben. Bei einem Vergleich
mit einem String der aus genau 4 Buchstaben besteht, können
die niemals gleich sein.

  command[k]=c;
  k++;

  if(k==4)     <-  hier
  {

> aber es funktioniert definitiv
Das kann höchstens zufällig sein.

von Karl heinz B. (kbucheg)


Lesenswert?

> <das hier:
> <uart_puts_P(">");
>
> doch, das funktioniert. der compiler meldet mir auch keine
> Fehlermeldung.

Was nur heist, dass sich der Compiler nicht wehren kann :-)

Die korrekte Syntax für den gcc lautet:

  uart_puts_P( PSTR( ">" ) );

Siehe auch das gcc-Tutorial, den Abschnitt 17.2
und dann schau dir mal im Fleury Source-Code an, was uart_puts_P
mit dem übergebenen Wert macht.

von chris (Gast)


Lesenswert?

Hallo K-H.,

ich habe mich bezüglich des uart_puts_P an das Beispiel von Peter
gehalten (test_uart.c).
Da steht unter anderem drin...

uart_puts("String stored in SRAM\n\r");
/*
* Transmit string from program memory to UART
*/
uart_puts_P("String stored in FLASH\n\r");

Bin davon ausgegangen, das das so richtig sei.

cu

chris

von chris (Gast)


Lesenswert?

hi,

ok.... hast ja recht... if(k==5)... dann geht es... :-)

von Karl H. (kbuchegg)


Lesenswert?

> *
> * Transmit string from program memory to UART
> */
> uart_puts_P("String stored in FLASH\n\r");
>
> Bin davon ausgegangen, das das so richtig sei.

Diesmal hab ich was übersehen.
P.Fleury hat sich ein Makro gebaut, dass den PSTR
einsetzt:

#define uart_puts_P(__s)       uart_puts_p(PSTR(__s))

deshalb funktioniert das korrekt.
Mea culpa.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Mea culpa.

Ich wäre auch drauf reingefallen.  Widerspricht ein wenig dem
"principle of least astonishment" (POLA), was sich der Peter
da ausgedacht hat.  Alle anderen auf _P endenden Funktionen
übernehmen einen String, der bereits im ROM liegen muss, er
dagegen übernimmt einen, den er erst in den ROM legt.

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.