mikrocontroller.net

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


Autor: chris (Gast)
Datum:

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

Autor: Volkmar e. P. (keepitsimple)
Datum:

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

Autor: chris (Gast)
Datum:

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

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

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

Autor: chris (Gast)
Datum:

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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

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

Autor: chris (Gast)
Datum:

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

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,

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

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

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

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.