Zeichen über USART empfangen

Gast #2215589
Lesenswert?

Hallo!

Ich habe ein programmiertechnisches Problem in C:

Ich möchte Befehle, welche über USB an einen mC kommen, auslesen und 
auswerten, da sie dann über RS 485 an weitere Geräte geschickt werden. 
Hierzu habe ich folgende Abfrage-Routine:
1
        i = 0;
2
      while (i < NUM_BYTES) 
3
      {
4
          if (USART_RXBufferData_Available(&USART_data)) 
5
          {
6
        receiveArray[i] = USART_RXBuffer_GetByte(&USART_data);
7
        if (receiveArray[i] == 'Q')
8
        {
9
          break;
10
        }
11
        else
12
          i++;
13
      }
14
    }

NUM_BYTES bezeichnet die Anzahl der einzulesenden Bytes (Also die Länge 
des Befehls). Nun möchte ich unterschiedlich lange Befehle einlesen, 
welche jeweils mit einem Zeichen (z.B Q) terminiert werden. Wird dieses 
Zeichen als i-tes Element eingelesen, soll der Einlesevorgang beendet 
werden.
Das Einlesenen habe ich mit obiger if-Abfrage realisiert.

Der Befehl soll dann weitergesendet werden:
1
      i=0;
2
      while (i<NUM_BYTES)
3
      {
4
        bool byteToBuffer;
5
        byteToBuffer = USART_TXBuffer_PutByte(&USART_485_data, receiveArray[i]);
6
        
7
        if(byteToBuffer)
8
            {
9
          i++;
10
        }
11
      }

Dss Problem ist nun, wenn ich z.B. einen Befehl mit 4 Bytes ('ABQS') 
sende, dann wird zwar beim ersten Mal nur 'ABQ' weitergesendet, beim 
nächsten Befehl allerdings wird das 'S' aus dem Puffer dem Befehl 
vorangestellt (also z.B. 'SABQ').
Hat hier jemand einen Tipp wie ich das lösen kann?
#2215935
Lesenswert?

Das widerspricht sich:

> Nun möchte ich unterschiedlich lange Befehle einlesen,
> welche jeweils mit einem Zeichen (z.B Q) terminiert werden.

und

> wenn ich z.B. einen Befehl mit 4 Bytes ('ABQS') sende

Der Befehl ABQS kann laut deiner vorhergehenden Definition keine 4 Bytes 
haben.



Wenn deine Befehle keine einheitliche LÄnge mehr haben, dann wird wohl 
das hier
1
      while (i<NUM_BYTES)

nicht mehr sinnvoll sein. Denn ein einzelner Befehl ist nun mal jetzt 
keine NUM_BYTES Zeichen mehr lang.

Dein Befehl hört mit einem 'Q' auf. Also wird wohl dieses 'Q' irgendwo 
in der Abbruchbedingung der Schleife vorkommen müssen. (Die Schleife ist 
an dieser Stelle sowieso meistens eine ganz schlechte Idee)
Gast #2215952
Lesenswert?

>ss Problem ist nun, wenn ich z.B. einen Befehl mit 4 Bytes ('ABQS')
>sende, dann wird zwar beim ersten Mal nur 'ABQ' weitergesendet, beim
>nächsten Befehl allerdings wird das 'S' aus dem Puffer dem Befehl
>vorangestellt (also z.B. 'SABQ').
>Hat hier jemand einen Tipp wie ich das lösen kann?


Ich würde zuerst zum Übertragungsprotokoll ein Timeout definifieren.
zB: die Zeitdauer, die die Übertragung von fünf Bytes dauert.

Wenn jetzt zB folgendes empfangen wird:
ABCQE (hier eine Pause größer oben beschrieben) SDFQ ...

so wird empfangen:
ABCQ => Auswerten,
E dann Timeout => ignorieren, da gegen PRotokoll (Q) verstößt,
SDFQ => Auswerten,

..
Gast #2216596
Lesenswert?

Doch!
1
uint8_t *p=Puffer;
2
uint8_t i=lenPuffer;
3
while(i--)
4
 *p++=0;
oder:
1
for (uint8_t i=0; i < lenPuffer; i++)
2
 Puffer[i]=0;
manchmal reicht es auch (bei dir sollte es gehen), den Schreib-/ 
Lesezeiger nur wieder auf den Anfang zu setzen.
Gast #2216659
Lesenswert?

Das Thema Pointer solltest du dir bei einer schönen Tasse Kaffee und 
Kuchen bei einem Sauwetter wie heute zu Gemüte führen und dann nochmal 
und nochmal und...

Mit einfachen Beispielen anfangen. Pointer auf Anfang vom Array? Das ist 
doch schon fast der Fall schlecht hin :)
Also:

uint8_t EinByte; // Ich bin ein Byte
uint8_t EinArrayOfBytes[]; // Ich hab mehrere Bytes

uint8_t *EinByte_P; // Ich bin ein Zeiger auf ein Byte, zeige aber noch
// auf nichts


EinByte = EinArrayOfBytes; // Nun zeige ich auf das erste Element im 
Array
// So kann ich zum Beispiel einer Funktion übergeben werden, ohne dass 
das
// komplette Array kopiert werden muss.

Wenn noch Fragen?

gruß Jonas
Gast #2216675
Lesenswert?

Danke, war jetzt komplett daneben, funktioniert nun. ;-)

Eine Frage hätt ich aber noch: Wenn in nun die Zeichen eingelesen habe, 
habe ich ja ein Array mit i Elementen. Wenn ich nun die Zeichen durch 
logische Operatoren vergleichen möchte, muss ich ja immer a la
1
if (receiveArray[0] == 'A' && receiveArray[1] == 'B') usw.
vorgehen.
Kann ich dieses Array in z.B. einen String umwandeln, sodass ich einfach 
z.B.
1
if (receive == 'AB') usw.
verwenden kann?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren