Forum: Compiler & IDEs Problem mit strcmp???


von Björn Hayer (Gast)


Lesenswert?

Hallo,
ich möchte Kommandos über den UART von einem Terminal-Programm
einlesen, die (mit Enter bestätigt eine entsprechende Funktion
aufrufen, aber irgendwie funzt das bei mir nicht, kann mir jemand
weiterhelfen?
        .
        .
        .
  empfangsdaten[i++]=data;

  if (data==('\r'))
    {
      if (strcmp_P(empfangsdaten,"OK")==0){
      uart_puts("OK akzeptiert");
      uart_putc('\r');
      i=0;
      empfangsdaten[0]=0x00;
      }
      else
      {
        uart_puts("UNKNOWN COMMAND ");
        uart_puts(empfangsdaten);
        uart_putc('\r');
        i=0;
        empfangsdaten[0]=0x00;
      }
    }
}
Er gibt immer nur "UNKNOWN COMMAND" aus, mit
uart_puts(empfangsdaten);
zeigt er mir aber genau das Kommando an das er eigentlich bräuchte für
"OK akzeptiert" zu zeigen...
Was mach ich falsch?

von Reiner (Gast)


Lesenswert?

strcmp_P vergleicht einen string mit einem PROGMEM string.
...if (strcmp_P(empfangsdaten,"OK")==0)...
hier ist aber kein string, der im Flash liegt!
-> ...if (strcmp(empfangsdaten,"OK")==0)...

von Björn Hayer (Gast)


Lesenswert?

...if (strcmp(empfangsdaten,"OK")==0)...

hatte ich auch schon versucht, geht leider auch nicht.
Liegt es vielleicht an meiner Definition von

unsigned char empfangsdaten[190]; ???

empfangsdaten wird byteweise über den seriellen Port eingelesen,
190 deshalb weil das längste Kommando 190 Zeichen lang ist.

von Reiner (Gast)


Lesenswert?

190 bytes ist natürlich viel.  Kommt auf den Prozessor an der verwendet
wird.
Aber mir fällt etwas anderes auf:
1. empfangsdaten wird nie "OK" enthalten sondern "OK\r", da ja
data kurz vor dem Vergleich \r ist.
2. strcmp vergleicht bis auf das terminierende \0 das am ende des
Strings stehen muß.  Wo wird der String terminiert ? Steht da wirklich
"OK\r\0" ?

von Björn Hayer (Gast)


Lesenswert?

Ich hatte schon versucht '\0' am ende hinzuzufügen, hat aber auch
nicht funktioniert.

Habe aber jetzt eine Lösung gefunden die funktioniert:

...if (!strncasecmp(empfangsdaten, PSTR("OK"), 2)){...

Vielen Dank für die antworten.
Das mit dem vielen Speicher stimmt natürlich schon, aber ich wüsste
nicht wie ich das anders machen soll?!?
Ist ein ATMega16, der sollte genug Speicher haben, zur Not kriegt er
eben noch einen externen Baustein spendiert.
Gibt es eine Möglichkeit zu erkennen wieviel freien Speicher ich noch
habe?

von Reiner (Gast)


Lesenswert?

Ja, so gehts natürlich, da die NULL oder \r nicht mehr in den Vergleich
einbezogen werden.  "OK" muß aber am Anfang von Empfangsdaten stehen.


Speicher:  avr-size --help
Dies gibt aber keine Antwort bezüglich des Laufzeitsverhalten, da
sich der Stack und Heap annähern.  Kollidieren die beiden gibt es
"lustige" Effekte.

von Florian Pfanner (Gast)


Lesenswert?

Hallo,

dein Code funktioniert zwar, aber wenn du z.b. das Kommando okay auch
verwendest so werden beide befehle ausgeführt. Ändere die Routiene,
welche die Daten in den Puffer schreiben:

  data=UDR;

  if (data==('\r'))
    {
      if (strcmp_P(empfangsdaten,"OK")==0){
      uart_puts("OK akzeptiert");
      uart_putc('\r');
      i=0;
      empfangsdaten[0]=0x00;
      }
      else
      {
        uart_puts("UNKNOWN COMMAND ");
        uart_puts(empfangsdaten);
        uart_putc('\r');
        i=0;
        empfangsdaten[0]=0x00;
      }
    }
   else
   {
      empfangsdaten[i++]=data;
   }

also das empfangene Zeichen wird nur in den Empfangsbuffer geschrieben,
wenn es nicht das Enter-Zeichen ist.

Gruß, Florian

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.