Forum: Mikrocontroller und Digitale Elektronik USART: Merkwürdiges Sendeverhalten


von Dennis S. (dennnis)


Lesenswert?

Hallo Zusammen,

ich habe folgendes Problem und weiß nicht weiter:
Ich sende über den PC einen Befehl an meinen MC, der sieht z.B. so aus: 
LED001;
Über den USART-Interrupt lasse ich den String zerlegen und will ihn im 
Grunde zum Test direkt wieder zurück schicken.
Hier der entsprechende Codeabschnitt:
1
volatile char uart_string[11] = "";
2
volatile uint8_t uart_str_count = 0;
3
4
ISR(USART_RXC_vect)
5
{
6
  unsigned char nextChar;
7
  nextChar = UDR;
8
  //SendChar(nextChar);
9
  if( nextChar != ';')
10
  {  //String ist noch im Aufbau
11
    uart_string[uart_str_count] = nextChar;
12
    uart_str_count++;
13
  }
14
  else 
15
  {   //String ist Komplett!
16
    uart_string[uart_str_count] = '\0';
17
    uart_str_count = 0;
18
    unsigned char Empfaenger[3];
19
    unsigned char Wert[3];
20
    
21
      Empfaenger[0] = uart_string[0];
22
      Empfaenger[1] = uart_string[1];
23
      Empfaenger[2] = uart_string[2];
24
      Empfaenger[3] = '\0';
25
        
26
      Wert[0] = uart_string[3];
27
      Wert[1] = uart_string[4];
28
      Wert[2] = uart_string[5];
29
      Wert[3] = '\0';
30
      
31
      sendstring(Empfaenger);
32
      sendstring(Wert);
33
  }
34
}
35
36
37
void sendstring(char *s)
38
  {
39
     while (*s)
40
     {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
41
       SendChar(*s);
42
       s++;
43
     }
44
  }
45
  
46
void SendChar(unsigned char c)
47
{
48
  while ( !( UCSRA & (1<<UDRE)) );
49
  UDR = c;
50
  return 0;
51
}
Das Problem ist nun das ich am PC nur den "Wert" empfange, ohne das 
vorherige "Empfaenger". Wenn ich es aber z.B. so schreibe:

sendstring(Empfaenger);
sendstring(Empfaenger);

oder so:

sendstring(Wert);
sendstring(Wert);

kommt alles passend (doppelt) an.
Drehe ich es um:

sendstring(Wert);
sendstring(Empfaenger);

kommt nur der "Wert" an, "Empfaenger" wird wieder verschluckt.

Hat Jemand eine Idee?

von Reinhard R. (reinhardr)


Lesenswert?

Vermutlich keine Erklärung für deinen Fehler, aber du mischt "char" und 
"unsigned char" wenn es um die Stringverarbeitung geht.

Etwas Offensichtliches fällt mir jetzt nicht auf. In so einer Situation 
bereinige ich gerne das Projekt (z.B. make clean) und erstelle es neu. 
Das hilft meistens zwar nicht (weil der Fehler im Code liegt), aber wenn 
es hilft hat man meistens schon lange an anderen Stellen gesucht. ;-)

Gruß
Reinhard

von Karl H. (kbuchegg)


Lesenswert?

1
    unsigned char Empfaenger[3];
2
    unsigned char Wert[3];
3
    
4
      Empfaenger[0] = uart_string[0];
5
      Empfaenger[1] = uart_string[1];
6
      Empfaenger[2] = uart_string[2];
7
      Empfaenger[3] = '\0';

zähl nach.
Du hast 4 Zuweisungen an Empfänger, hast aber Empfänger nur mit einer 
Größe von 3 Elementen definiert.

Du überlaufst dein Array, dasselbe mit 'Wert'.

Je nachdem, wie der Compiler die Arrays im Speicher angeordnet hat, 
beschriebst du mit Wert[3] eigentlich Empfänger[0]. Und damit hast du 
dir den String dort gleich an der ersten Stelle gekappt.

von Reinhard R. (reinhardr)


Lesenswert?

Karl Heinz Buchegger schrieb:
> zähl nach.

Autsch! So viel zu meiner Aussage mit "nichts Offensichtliches".

Duck und weg,
Reinhard

von Dennis S. (dennnis)


Lesenswert?

Tatsache:

unsigned char Empfaenger[4];
    unsigned char Wert[4];

      Empfaenger[0] = uart_string[0];
      Empfaenger[1] = uart_string[1];
      Empfaenger[2] = uart_string[2];
      Empfaenger[3] = '\0';

      Wert[0] = uart_string[3];
      Wert[1] = uart_string[4];
      Wert[2] = uart_string[5];
      Wert[3] = '\0';

      sendstring(Empfaenger);
      sendstring(Wert);

funktioniert. Besten Dank.
Ich war der Auffassung das die Größe [3] insgesamt 4 Zeichen zulässt, 
also 0..3.

Naja, so kann man sich täuschen.

Vielen Dank

von Karl H. (kbuchegg)


Lesenswert?

Dennis Scholz schrieb:

> Ich war der Auffassung das die Größe [3] insgesamt 4 Zeichen zulässt,
> also 0..3.
>
> Naja, so kann man sich täuschen.

Soll ich's sagen?

Du brauchst ein C-Buch

von Purzel (Gast)


Lesenswert?

> interrupt :
>     sendstring(Empfaenger);
>     sendstring(Wert);

Was soll das ? Im Rx-Interrupt sendet man sicher nicht. Noch duemmer 
waer's wenn die Senderoutinen blockierend waeren.

von Karl H. (kbuchegg)


Lesenswert?

Purzel schrieb:
>> interrupt :
>>     sendstring(Empfaenger);
>>     sendstring(Wert);
>
> Was soll das ? Im Rx-Interrupt sendet man sicher nicht. Noch duemmer
> waer's wenn die Senderoutinen blockierend waeren.

Ich bin mir sicher, dass das nur ein erster Test war und nicht der reale 
Code.

von Purzel (Gast)


Lesenswert?

Auch wenn's nur ein Test war ... er soll den Kuchen bringen und dann 
tschuess. Gilt eigentlich fuer alle dazwischen auch. Keiner hat's 
gemerkt.

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.