Forum: Compiler & IDEs Speichern von Strings


von Armin (Gast)


Lesenswert?

Ich habe ein kleines Problem mit dem Auswerten von Strings. ich bekomme 
von einen Dimmermodul die Aktuelle Dimmwerte sowie die Kanalnummer und 
das Endezeichen(13) für jeden Kanal ein anderes Endezeichen,zuerstmal 
nur ein Kanal zum Testen.
Der String der ankommt sieht wie folgt aus: 0124 ;Kanal,Dimmwert.

Auf dem LCD Bekomm ich nur Angezeigt, RX0 BUFFER INHALT und wirre 
Zahlen.
Baudrate stimmt alles.

Wenn ich mir nun Vom Dimmermodul die Werte über Hterm Anzeige passt 
alles.

Worin liegt nun mein Fehler.
Ich nutze die UART-Lib von Peter Fleury.
mfg

1
 char s[7];
2
 char RX0Buffer[10];
3
 unsigned int c;
4
 int BufferLen = 10;
5
6
7
 for (;;)
8
9
{
10
11
  int i = 0;
12
  unsigned char by;
13
 
14
15
    while( ( c = uart_getc() ) != '13' && i < BufferLen  - 1 )
16
    RX0Buffer[ i++ ] = c;
17
18
    RX0Buffer[i] = '\0';
19
20
//RX0Buffer  auslesen und senden
21
     uart_putc( 17 ); //Zeilen Position auf LCD
22
     uart_putc( 0 );   
23
     uart_putc( 0 );
24
     uart_putc( 0 );   
25
     uart_putc( 0 );    
26
     uart_puts( "RX0 BUFFER INHALT" );  
27
28
          i = 0; 
29
            do
30
             {
31
              by=RX0Buffer[i];
32
               uart_putc( 17 ); //Zeilen Position auf LCD
33
               uart_putc( 0 );
34
               uart_putc( 0 );   
35
               uart_putc( 20 );
36
               uart_putc( 0 );              
37
               itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
38
               uart_puts( s );                
39
               
40
             }
41
              while ((RX0Buffer[i] != '\0') );
42
43
44
45
     }
46
  
47
    }

von Rolf M. (rmagnus)


Lesenswert?

Armin schrieb:
>           i = 0;
>             do
>              {
>               by=RX0Buffer[i];
>                uart_putc( 17 ); //Zeilen Position auf LCD
>                uart_putc( 0 );
>                uart_putc( 0 );
>                uart_putc( 20 );
>                uart_putc( 0 );
>                itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
>                uart_puts( s );
>
>              }
>               while ((RX0Buffer[i] != '\0') );

Da du i hier nirgends inkrementierst, gibst du nur in einer 
Endlosschleife immer wieder den ersten Wert aus.

von Armin (Gast)


Lesenswert?

aber durch die do while schleife wird doch solange gelesen bis das ende 
im String erkannt wird oder bin ich da auf dem Holzweg.

von Holzweg (Gast)


Lesenswert?

Ja, du bist auf dem Holzweg. Die do-while-Schleife inkrementiert die 
Variable i nicht.

Schreibe einfach im Schleifenfuß i++ statt i, dann sollte es gehen.

von smoerre (Gast)


Lesenswert?

Armin schrieb:
> '13'

Das ergibt keinen Sinn.
Entweder
13
oder
'x0D'

von Klaus W. (mfgkw)


Lesenswert?

Nicht nur, daß es keinen Sinn macht - es wird vrmtl. nicht mal 
kompiliert werden.

von Rolf M. (rmagnus)


Lesenswert?

smoerre schrieb:
> Armin schrieb:
>> '13'
>
> Das ergibt keinen Sinn.
> Entweder
> 13
> oder
> 'x0D'

Das naheliegendes wäre eigentlich '\r'.

Armin schrieb:
> aber durch die do while schleife wird doch solange gelesen bis das ende
> im String erkannt wird oder bin ich da auf dem Holzweg.

Das stimmt im Prinzip schon. Da aber i 0 ist und das auch für immer und 
ewig bleibt und du in RX0Buffer[i] nach dem Ende schaust, suchst du 
immer nur im ersten Zeichen des Strings nach dem Ende.

von Karl H. (kbuchegg)


Lesenswert?

>    while( ( c = uart_getc() ) != '13' && i < BufferLen  - 1 )
>      RX0Buffer[ i++ ] = c;

> Ich nutze die UART-Lib von Peter Fleury.

Da ist schon mal der erste Fehler.

Das uart_getc() aus der Fleury Lib ist ein nicht wartendes getc(). D.h. 
es kommt auch dann zurück, wenn kein Zeichen vorliegt oder empfangen 
wurde.

Studier doch einfach mal das Beispiel, welches Peter mitliefert um zu 
sehen, wie man den Returncode von uart_getc() richtig auswertet. 
Deswegen hat Peter es nämlich geschrieben.

von Armin (Gast)


Lesenswert?

Ich hab mir das Beispiel von Peter nochmal angesehen,und sogut we ich 
das kann umgesetzt.
Nun habe ich aber Probleme mit der Ausgabe vom RX0Buffer  ich erhalte 
nun immer 2551610,Angezeigt werden sollte 01 24,weil die Werte ja so vom 
Dimmermodul kommen.
wo mache ich nur den Fehler.
viellecht kann mir von eúch einer nochmal kurz helfen
mfg

1
 char s[2];
2
 char RX0Buffer[10];
3
 unsigned int c;
4
 int BufferLen = 10;
5
6
7
 for (;;)
8
9
{
10
11
  int i = 0;
12
  unsigned char by;
13
14
    c = uart_getc();
15
    if ( c & UART_NO_DATA )
16
     {
17
      //Keine Daten 
18
      //Mach was
19
     }
20
    
21
    else
22
     {
23
24
    while( ( c = uart_getc() ) != '0x0D' && i < BufferLen  - 1 )
25
    RX0Buffer[ i++ ] = c;
26
27
    RX0Buffer[i] = '\0';
28
29
//RX0Buffer  auslesen und senden
30
     uart_putc( 17 ); //Zeilen Position auf LCD
31
     uart_putc( 0 );   
32
     uart_putc( 0 );
33
     uart_putc( 0 );   
34
     uart_putc( 0 );    
35
     uart_puts( "RX0 BUFFER INHALT" );  
36
37
38
            do
39
             {
40
             i++; 
41
             by=RX0Buffer[i];
42
             itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
43
             uart_puts( s );                        
44
             }
45
              while ((RX0Buffer[i] != '\0') );
46
              i=0;
47
48
     }
49
 }
50
}

von Rolf M. (rmagnus)


Lesenswert?

Armin schrieb:
> while( ( c = uart_getc() ) != '0x0D' && i < BufferLen  - 1 )

'0x0D' ist immer noch falsch. Schreib doch einfach '\r'.


Armin schrieb:
> do

Wo ist denn das i=0 vor der Schleife geblieben? Ohne das fängst du nicht 
am Anfang zu lesen an, sondern nach dem letzen in den Puffer 
geschriebenen Zeichen. Da kommt natürlich nur Mist an.

>              {
>              i++;

Warum inkrementierst du i am Anfang der Schleife? So überliest du ja das 
erste Zeichen.

>              by=RX0Buffer[i];
>              itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
>              uart_puts( s );
>              }
>               while ((RX0Buffer[i] != '\0') );
>               i=0;
>
>      }

Übrigens: Eine vernünftige Einrückung würde den Code um einiges lesbarer 
machen.

von Armin (Gast)


Lesenswert?

Trotzdem bekomm ich auf dem Display nur 523255 angezeig, und nicht die 
Werte vom Dimmermodul.

Was mach ich denn nur Falsch
1
 char s[2];
2
 char RX0Buffer[10];
3
 unsigned int c;
4
 int BufferLen = 10;
5
6
7
 for (;;)
8
9
{
10
11
  int i = 0;
12
  unsigned char by;
13
14
    c = uart_getc();
15
    if ( c & UART_NO_DATA )
16
     {
17
      //Keine Daten 
18
      //Mach was
19
20
     }
21
    
22
    else
23
     {
24
25
    while( ( c = uart_getc() ) != '\r' && i < BufferLen  - 1 )
26
    RX0Buffer[ i++ ] = c;
27
28
    RX0Buffer[i] = '\0';
29
    
30
    //RX0Buffer  auslesen und senden
31
    uart_putc( 17 ); //Zeilen Position auf LCD
32
    uart_putc( 0 );   
33
    uart_putc( 0 );
34
    uart_putc( 0 );   
35
    uart_putc( 0 );    
36
    uart_puts( "RX0 BUFFER INHALT" );  
37
38
    i=0;
39
    do
40
     {
41
      by=RX0Buffer[i];
42
      itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
43
      uart_puts( s );                        
44
      i++;        
45
   }
46
    while ((RX0Buffer[i] != '\0') );
47
        
48
49
    }
50
 }
51
}

von High Performer (Gast)


Lesenswert?

>      by=RX0Buffer[i];
>      itoa( by, s, 10 ); // 10 fuer radix -> Dezimalsystem
>      uart_puts( s );

Du wandelst den ASCII-Wert eines jeden Zeichens in einen String um. 
Warum?
Willst Du nicht einfach die ASCII-Zeichen direkt senden?

von Armin (Gast)


Lesenswert?

Ja weil ich die Werte Dezimal ausgen muss.
aber ich Bekomm es nicht hin die Werte die ich Empfange auch so 
Auszugeben.
mfg

von Rolf M. (rmagnus)


Lesenswert?

Armin schrieb:
> Ja weil ich die Werte Dezimal ausgen muss.

Was kommt denn da nun wirklich an? Ein String oder Binärwerte, die du 
erst in Strings wandeln mußt? Bei dener Ausgabe 523255 fällt auf, daß 52 
einer '4', 32 einem Leerzeichen und 55 einer '7' entsprechen würde.

von Armin (Gast)


Lesenswert?

die werte die vom Dimmermdul kommen sind ASCII Werte:
;;KANALNUMMER
  ldi   temp5, 0
  ori  temp5,0x30    ;
  sts  rsbuff+0,temp5

  ldi   temp5, 1
  ori  temp5,0x30    ;
  sts  rsbuff+1,temp5

;;DIMMERWERT
ma1300:  clr  r16      ;0-Wert für 16-Bit Subtraktion
  clr  r18      ;ASCII Stelle 2 löschen
  clr  r19      ;ASCII Stelle 1 löschen
ma1310:  mov  r17,xl      ;Binärzahl zwischenspeichern L
  subi  xl,100      ;100 subtrahieren
  sbc  xh,r16      ;Übertrag subtrahieren
  brcs  ma1320      ;war Zahl>99? nein -> weiter
  inc  r18      ;ASCII Stelle 2 erhöhen
  cpi  r18,10      ;Übertrag?
  brcs  ma1310      ;nein -> Schleife
  clr  r18      ;sonst ASCII Stelle 2 löschen
  inc  r19      ;und ASCII Stelle 1 erhöhen
  rjmp  ma1310      ;Schleife
;
ma1320:  mov  xl,r17      ;letzten Binärwert L holen
  clr  r17      ;ASCII Stelle 3 löschen
ma1330:  cpi  xl,10      ;Wert>9?
  brcs  ma1340      ;nein -> Rest auswerten
  inc  r17      ;sonst ASCII Stelle 3 erhöhen
  subi  xl,10      ;Wert um 10 vermindern
  rjmp  ma1330      ;Schleife
ma1340:  mov  r16,xl      ;Rest in ASCII Stelle 4 legen
  ori  r16,0x30             ;Ergebnis in ASCII wandeln
  ori  r17,0x30
  ori  r18,0x30
  ori  r19,0x30
;

  sts  rsbuff+2,r18;
  sts  rsbuff+3,r17
         sts  rsbuff+5,r16

         RCALL SEND
         ldi   dta, 13
         RCALL uart_tx
ret


send:
         ldi  xl,low(rsbuff)
  ldi  xh,high(rsbuff)    ;Zeiger auf RS232-Puffer
  ldi  temp3,6      ;7 Zeichen senden
send1:
         ld  dta,x+      ;Zeichen holen
  rcall  uart_tx      ;Zeichen senden
  dec  temp3      ;alle Zeichen gesendet?
  brne  send1      ;nein -> Schleife
RET

uart_tx:
        sbis  ucsra,udre
        rjmp    uart_tx
        out     UDR,  dta
ret

von Rolf M. (rmagnus)


Lesenswert?

Armin schrieb:
> die werte die vom Dimmermdul kommen sind ASCII Werte

Dann solltest du sie auf der Empfänger nicht als Binärwerte 
interpretieren und nochmal nach ASCII konvertieren. Gib sie einfach so 
aus wie sie sind.

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
   c = uart_getc();
2
    if ( c & UART_NO_DATA )
3
     {
4
      //Keine Daten 
5
      //Mach was
6
7
     }
8
    
9
    else
10
     {
11
12
    while( ( c = uart_getc() ) != '\r' && i < BufferLen  - 1 )
13
    RX0Buffer[ i++ ] = c;

ist doch immer noch Unsinn.
Du musst JEDES uart_getc() darauf abfragen, ob überhaupt ein Zeichen 
angekommen ist, nicht nur das erste.


  Schleife {
    c = uart_getc();
    war es ein gültiges Zeichen?
       Ja: war es kein \r und ist noch Platz im Buffer?
             Ja: Speichere es im Buffer
             Nein: Brich aus der Schleife aus
  }


Da gibt es genau eine Schleife und innerhalb der Schleife wird ein 
Zeichen geholt, sofern eines da ist und abgespeichert. Du musst die 
Dinge schon logisch richtig ineinander schachteln und nicht einfach nur 
ein bischen Code den du schon hast durch die Gegend schieben.

von Klaus W. (mfgkw)


Lesenswert?

c & UART_NO_DATA erscheint mir auch nicht besonders sinnig.

von Karl H. (kbuchegg)


Lesenswert?

Das hat er ausnahmsweise richtig

 unsigned int c;

Scheinbar hat er das Original-Beispiel zumindest angesehen. uart_getc 
returniert einen uint16_t, wobei die oberen 8 Bit kodieren, ob etwas im 
Puffer war, ob es Fehler gab, etc.
Wertet man aber nicht alle Bits aus, dann wäre es eventuell nicht 
verkehrt die oberen 8 Bits wegzucasten, ehe man zb auf \r vergleicht.

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.