Forum: Mikrocontroller und Digitale Elektronik Parsen klappt nur bis zur ersten Stelle.


von Markus P. (sebastianwurst)


Lesenswert?

Ich will ein String z.B "99|11|01|00" auf jede Stelle zwischen den "|" 
aufbröseln. Dieses versuche ich mit dem Code (s.unten), die Ausgabe auf 
UART ist jedoch nur : Stelle 1:99

PS. Das -----Jippie---- wird auf der UART ausgegeben!

Warum kommt Stelle 2.4 nicht zum Vorschein?
1
if (usart_status.usart_ready) 
2
  {
3
       
4
      if (!strcmp(usart_rx_buffer,"99|11|01|00")) 
5
      {  
6
      usart_write("----Jipppieee----");
7
      }       
8
9
  
10
11
      int o=0;
12
      char* pToken = strtok(usart_rx_buffer,"|");
13
      
14
      if (pToken)
15
      {
16
        usart_write("Stelle 1: %s\n\r",pToken);
17
        o++;
18
      
19
      while ( (pToken = strtok(NULL, "|")) )
20
        {
21
          if(o==1)
22
          printf("Stelle 2: %s\n\r",pToken);
23
          
24
          if(o==2)
25
          printf("Stelle 3: %s\n\r",pToken);
26
        
27
          if(o==3)
28
          {
29
          printf("Stelle 4: %s\n\r",pToken);
30
            usart_status.usart_ready =0;
31
          }
32
          o++;        
33
        
34
        }
35
      }
36
         
37
  }

von Krapao (Gast)


Lesenswert?

Wahrscheinlich weil dein printf() nicht an der erwarteten Stelle 
ausgibt. Das erste Ergebnis gibtst du mit usart_write() aus, die 
Nachfolger mit printf(). An der Benutzung des strtok() sehe ich auf den 
oberflächlichen Blick nix kritisches 
(http://www.elook.org/programming/c/strtok.html)

von Matthias L. (Gast)


Lesenswert?

In was willst du das denn zerlegen? In einzelne Strings, oder in 
einzelne (zB) uint8_t ??

von Matthias L. (Gast)


Lesenswert?

Ich hab sowas ähnliches letztens auf Arbeit programmiert. Auf das 
Problem hier würde ich das etwa so machen:
1
//-----------------------------------------------
2
uint8_t  sString[] = "99|54|34|55";
3
uint8_t  au8Value[4];
4
5
void parse void ( uint8_t* sChar, uint8_t* sValue, uint8_t u8Len )
6
{
7
  uint8_t  u8State     = 0;
8
  uint8_t  u8StateLast = 255;
9
  uint8_t  u8Cnt       = 0;
10
  //-----------------------------------------------------------
11
  while ( *sChar != 0x00 )
12
  {
13
    switch ( u8State )
14
    {
15
    case 0:
16
      if ( u8StateLast != u8State )
17
      {
18
        u8StateLast= u8State;
19
        *sValue = 0;
20
      }
21
      if ( *sChar == '|' )
22
      {
23
        u8State = 1;
24
      }
25
      else if (    ( *sChar >= '0' )
26
                && ( *sChar <= '9' )  )
27
      {
28
        *sValue = (10 * *sValue) + ( *sChar - '0' );
29
      }
30
      break;
31
32
    case 1:
33
      u8StateLast= u8State
34
      sValue++;
35
      if ( ++u8Cnt == u8Len ) return;
36
      break;
37
    }
38
    sChar++;
39
40
  }
41
42
}
43
44
45
//-----------------------------------------------
46
memset ( au8Value, 0, sizeof(au8Value) );
47
parse( sString, au8Value, 4 );
48
49
// in au8Value sollten jetzt die Ziffern stehen.

von STK500-Besitzer (Gast)


Lesenswert?

1
( (pToken = strtok(NULL, "|")) )

Soweit ich die Doku zu strtok verstanden habe, versuchst du in einem 
NULL-String dein Trennzeichen zu finden...

von gaast (Gast)


Lesenswert?


von Yalu X. (yalu) (Moderator)


Lesenswert?

Krapao schrieb:
> Das erste Ergebnis gibtst du mit usart_write() aus, die Nachfolger mit
> printf().

Das wird es wohl gewesen sein. Der Rest ist in Ordnung.

von Markus P. (sebastianwurst)


Lesenswert?

Yalu X. schrieb:
> Krapao schrieb:
>> Das erste Ergebnis gibtst du mit usart_write() aus, die Nachfolger mit
>> printf().
>
> Das wird es wohl gewesen sein. Der Rest ist in Ordnung.

Einfach zu unkonzentriert ... und kopiert ... sorry für die doofe, 
unnützige Frage! Habe es zwar noch nicht ausprobiert, aber das wird's 
sein.

von Markus P. (sebastianwurst)


Lesenswert?

Matthias Lipinsky schrieb:
> Ich hab sowas ähnliches letztens auf Arbeit programmiert. Auf das
> Problem hier würde ich das etwa so machen:
>
> [c]
>
> //-----------------------------------------------
> uint8_t  sString[] = "99|54|34|55";
> uint8_t  au8Value[4];
>
> void parse void ( uint8_t* sChar, uint8_t* sValue, uint8_t u8Len )
> {
>   uint8_t  u8State     = 0;
>   uint8_t  u8StateLast = 255;
>   uint8_t  u8Cnt       = 0;
>   //-----------------------------------------------------------

Danke, das kann ich gut gebrauchen.

von Matthias L. (Gast)


Lesenswert?

>Danke, das kann ich gut gebrauchen.

Und? Geht das?

von Markus P. (sebastianwurst)


Lesenswert?

Ich bin gerade dabei...
Ich versuch gerade mein Code abzuändern damit ich die gesendeten 
Stringstücke in ein Char- oder Int-Array packe.
Aber das klappt noch nicht. Siehst Du da irgend ein Bock drin?
Leider bin ich zu doof um dein Code komplett zu verstehen, da tu ich 
mich dann immer schwer damit den einfach zu verwenden, auch wenn er 
klappen würde...
1
    
2
  if (usart_status.usart_ready) 
3
  {
4
       
5
      if (!strcmp(usart_rx_buffer,"99|11|01|00")) 
6
      {  
7
      usart_write("----Jipppieee----");
8
      }       
9
10
11
  
12
      int o=0;
13
       char* pToken = strtok(usart_rx_buffer,"|");      
14
     
15
       
16
       if (pToken)
17
       {
18
         usart_write("--Stelle 1: %s--\n\r",pToken);
19
        ReceiveSerial[1] = atoi(pToken);
20
        usart_write_char(ReceiveSerial[1]);  
21
         o++;
22
       
23
       while ((pToken = strtok(NULL, "|")) )
24
         {
25
           if(o==1)
26
          {
27
           usart_write("--Stelle 2: %s--\n\r",pToken);
28
           ReceiveSerial[2] = atoi(pToken);  
29
                    usart_write_char(ReceiveSerial[2]);  
30
           }
31
      
32
           if(o==2)
33
          {
34
           usart_write("--Stelle 3: %s--\n\r",pToken);
35
           ReceiveSerial[3] = atoi(pToken);  
36
          usart_write_char(ReceiveSerial[3]);
37
          }
38
          
39
           if(o==3)
40
           {
41
           usart_write("--Stelle 4: %s--\n\r",pToken);
42
          ReceiveSerial[4] = atoi(pToken);  
43
          usart_write_char(ReceiveSerial[4]);
44
           }
45
           o++;          
46
         }
47
         
48
       }
49
     
50
51
    usart_status.usart_ready =0;       
52
  }

von Markus P. (sebastianwurst)


Lesenswert?

Vergessen: So ist das ReceiveSerial deklariert;
1
char ReceiveSerial[5];

von Karl H. (kbuchegg)


Lesenswert?

Markus P. schrieb:

>          usart_write("--Stelle 1: %s--\n\r",pToken);
>         ReceiveSerial[1] = atoi(pToken);
>         usart_write_char(ReceiveSerial[1]);

Ich kenn zwar deine FUnktionen nicht, aber ich denke nicht, dass du hier 
usart_write_char benutzen willst.

Du hast an dieser Stelle keine Character mehr (und auch keine Strings), 
sondern bereits Zahlen!

Ergo wirst du eine Funktion benutzen wollen, die auch eine Zahl ausgeben 
kann. Zb so was:
1
void usart_write_int( int number )
2
{
3
  char buffer[10];
4
  itoa( number, buffer, 10 );
5
  uart_write( buffer );
6
}

PS: du tust dir unter UMständen leichter, wenn du es dir zur Regel 
machst, dass du den Datentyp char ausschliesslich und nur für Character 
benutzt. Also alles was mit Texten (aka. Strings) bzw. Einzelzeichen wie 
sie in Texten vorkommen reservierst.

Wenn du einen kleinen Integer meinst, also eine Variable die Zahlen 
speichert, so wie in 5 Äpfel oder 28 Grad Celsius, dann benutzt du 
ausschliesslich uint8_t, int8_t (oder uint16_t oder int16_t): Dann 
erinnert dich der Datentyp immer daran, womitr du es zu tun hast: Mit 
Zeichen ('a', 'b', c' aber auch '0', '1', ...) oder mit kleinen Zahlen 
(5, 8, 7). Es hilft auch, wenn du Variablen danach benennst, wozu sie 
dienen, welchen Wert sie enthalten. ReceiveSerial ist da nicht sehr 
hilfreich. Der Name erzählt dir nichts.

PS: strtok ist hier ziemlich kompliziert einzusetzen. Matthias hat dir 
schon gezeigt, wie das einfacher geht. Es ist nicht immer die einfachste 
Variante einen String erst in Einzelteile aufzusplitten und dann mit den 
Einzelteilen etwas zu machen. In deinem Fall, wenn es sich nur um Zahlen 
handelt, die aus dem kompletten String extrahierst und in ein Array 
ablegst, ist es einfacher, wenn man den String einfach ein Zeichen nach 
dem nächsten durchgeht und entscheidet was mit diesem Zeichen zu machen 
ist.
Entweder es ist ein digit (also '0' bis '9'), dann gehört es zur gerade 
geparsten Zahl dazu. Das ist aber leicht zu bewerkstelligen. Denn wie 
wird aus der Zahl 64 und einer daran anzuhängenden 3 die Zahl 643? 
Simpel. 64 * 10 macht 640 (damit hast du die ganze Zahl um 1 Stelle nach 
links 'geschoben' und dann kannst du einfach die 3 dazuaddieren. Du 
kriegst dann 643. Und wenn daran dann noch eine 8 drann soll, dann geht 
das wieder nach dem gleichen Muster: 643*10  macht 6430, und da dann 
noch die 8 dazuaddiert macht 6438. Schau dir nochmal Matthias Code an, 
ob du die Operation dort findest.

Und dann kann in deinem Eingabestring noch das Zeichen | vorkommen. Das 
ist aber leicht. Das schaltet einfach nur weiter in welches Arrayelement 
die nächsten digits reinkommen.

von Matthias L. (Gast)


Lesenswert?

>Leider bin ich zu doof um dein Code komplett zu verstehen, da tu ich
>mich dann immer schwer damit den einfach zu verwenden, auch wenn er
>klappen würde...


Versuche doch einfach meinen COde nachzuvollziehen. Du kannst ja hier 
nachfragen.

Karl Heinz hat Dir ja schon paar Tipps gegeben.

von Markus P. (sebastianwurst)


Lesenswert?

Danke das mach ich, morgen geh ich da wieder bei...

von DirkB (Gast)


Lesenswert?

Und wenn man sowas:
1
           if(o==1)
2
          {
3
           usart_write("--Stelle 2: %s--\n\r",pToken);
4
           ReceiveSerial[2] = atoi(pToken);  
5
                    usart_write_char(ReceiveSerial[2]);  
6
           }
 mehrmals hat, kann man es auch zusammenfassen:
1
//           if(o==1) // wird jetzt nicht mehr gebraucht und gilt auch für andere werte
2
          {
3
           usart_write("--Stelle %d: ",o);
4
           usart_write("%s--\n\r",pToken);
5
           ReceiveSerial[o+1] = atoi(pToken);  
6
                    usart_write_int(ReceiveSerial[o+1]);  
7
           }
Beachten musst du dann nur noch, dass du nicht mehr als 4 Werte 
einliest.

von Markus P. (sebastianwurst)


Lesenswert?

Hi,
ich habe mir jetzt noch einmal deinen Code (Lippy) angeguckt und da ist 
mir auch einiges klar geworden. Zumindest verstehe ich den Code wenn man 
folgenden Dreher beseitigt:

Vorher:
1
    case 1:
2
      u8StateLast= u8State; // <----
3
      sValue++;
4
      if ( ++u8Cnt == u8Len ) return;
5
      break;
Nachher:
1
    case 1:
2
      u8State = u8StateLast; // <----
3
      sValue++;
4
      if ( ++u8Cnt == u8Len ) return;
5
      break;
Ist doch Richtig oder? Doch so ganz klappt es dann auch noch nicht. 
Ausgabe von "12|34|56|78" ist:
12
4
6
8

Bei folgendem Code:
1
void usart_write_int(int data)
2
{
3
  char Bufferchar[10];
4
  
5
      itoa(data, Bufferchar, 10);    
6
            usart_write_str( Bufferchar);
7
      usart_write_str("\r\n");
8
      
9
}

Und das in der USART-Abfrage:
1
  
2
  if (usart_status.usart_ready) 
3
  {
4
       
5
      if (!strcmp(usart_rx_buffer,"99|11|01|00")) 
6
      {  
7
      usart_write("----Jipppieee----");
8
      }       
9
10
11
memset ( au8Value, 0, sizeof(au8Value) );
12
parse( usart_rx_buffer, au8Value, 4 );
13
14
15
// in au8Value sollten jetzt die Ziffern stehen.
16
17
  usart_write_int(au8Value[0]);
18
  usart_write_int(au8Value[1]);
19
  usart_write_int(au8Value[2]);
20
  usart_write_int(au8Value[3]);      
21
     
22
     
23
usart_status.usart_ready = 0;
24
           
25
  }
Da mein "usart_rx_buffer" so deklariert ist (kein unsigned):
1
    #define BUFFER_SIZE  50
2
  char usart_rx_buffer[BUFFER_SIZE];

bekomme ich noch die Warnung:

main.c:1428: warning: pointer targets in passing argument 1 of 'parse' 
differ in signedness.

Das kann doch eigentlich damit nichts zu tun haben, oder?
Stehe gerade bissel auffen Schlauch. Irgendwie jetzt einen zu viel in 
der Case1:, finde den Bock nicht...

von MWS (Gast)


Lesenswert?

Markus P. schrieb:
> Ausgabe von "12|34|56|78" ist:
> 12
> 4
> 6
> 8

Verständlich, wenn man sich den Code durchdenkt. Der läuft in case 0: 
auf ein "|", dann wird der State = 1, Zeichenpointer wird erhöht, zeigt 
nun auf die erste Ziffer, läuft im nächsten Durchgang aber erstmal in 
den case 1: Block und erhöht danach wieder den Zeichenpointer, also wird 
erst ab der zweitem Ziffer erfasst.

Würde das sChar++ an's Ende des Case 0: Blocks stellen.

Das find' ich unschön:
> switch ( u8State )
>     {
>     case 0:
>       if ( u8StateLast != u8State )

Unter case 0: muss u8State = 0 sein, sonst wär' man nicht dort, also 
kann man gleich
if ( u8StateLast != 0 )
bzw.
if ( u8StateLast )
schreiben.

von Karl H. (kbuchegg)


Lesenswert?

Wo kommt eigentlich der String her?
Anderes Programm (per UART) oder Mensch?

Grund: Wenn der String von einem anderen Programm kommt, kann man davon 
ausgehen, dass ernicht fehlerhaft ist. Bei einer menschlichen Eingabe 
muss man mehr Aufwand treiben um Fehler abzufangen.

Annahme: anderes Programm
So gesehen sehe ich nämlich den Vorteil der State-Machine da drinnen 
noch nicht.
1
#include <stdio.h>
2
3
uint8_t parse( const char* sChar, uint8_t* sValue, uint8_t u8Len )
4
{
5
  uint8_t nrArg = 0;
6
7
  sValue[nrArg] = 0;
8
9
  while( *sChar ) {
10
    if( *sChar == '|' ) {
11
      nrArg++;
12
      if( nrArg == u8Len - 1 )
13
        return nrArg + 1;
14
      sValue[nrArg] = 0;
15
    }
16
17
    else if( *sChar >= '0' && *sChar <= '9' )
18
      sValue[nrArg] = 10 * sValue[nrArg] + (*sChar - '0');
19
20
    sChar++;
21
  }
22
23
  return nrArg + 1;
24
}
25
26
int main()
27
{
28
  uint8_t Args[10];
29
  uint8_t parsedArgs;
30
  uint8_t i;
31
  
32
  char String[] = "12|56|34|58";
33
34
  parsedArgs = parse( String, Args, sizeof(Args)/sizeof(*Args) );
35
36
  printf( "Anzahl geparster Argumente %d\n", (int)parsedArgs );
37
  for( i = 0; i < parsedArgs; ++i )
38
    printf( "%d ", Args[i] );
39
  printf( "\n" );
40
}

Der String darf dabei nicht leer sein und darf auch nicht mit einem | 
aufhören (sonst ist die als Rückmeldung gelieferte Anzahl geparster 
Argumente um 1 zu hoch). Bei einem Programm-generierten String ist das 
kein Problem, bei einer menschlichen Eingabe ist das nicht akzeptabel.

von Matthias L. (Gast)


Lesenswert?

>Ist doch Richtig oder?

Nein. War schon richtig, aber

>Doch so ganz klappt es dann auch noch nicht. Ausgabe von "12|34|56|78" ist:
>12
>4
>6
>8

Oh. Ja, ich seh es. Karl Heinz hat recht. Die State Maschine bringt hier 
nix. Das ist zu einfach ;-)

Versuch mal das.

1
//-----------------------------------------------
2
uint8_t  sString[] = "99|54|34|55";
3
uint8_t  au8Value[4];
4
5
void parse void ( uint8_t* sChar, uint8_t* sValue, uint8_t u8Len )
6
{
7
  uint8_t  u8Cnt       = 0;
8
  //-----------------------------------------------------------
9
  while ( *sChar != 0x00 )
10
  {
11
    //-- Trennzeichen ? -----------------------
12
    if ( *sChar == '|' )
13
    {
14
      sValue++;
15
      if ( ++u8Cnt == u8Len ) return;
16
    }
17
    //-- Ziffer -------------------------------
18
    else if (    ( *sChar >= '0' )
19
              && ( *sChar <= '9' )  )
20
    {
21
      *sValue = (10 * *sValue) + ( *sChar - '0' );
22
    }
23
    //-- weiter -------------------------------
24
    sChar++;
25
  }
26
27
}


Ein Leerstring, bzw ein Enden mit | sollte kein Thema sein.

EDIT:

>Unter case 0: muss u8State = 0 sein, sonst wär' man nicht dort, also
>kann man gleich
>if ( u8StateLast != 0 )
>bzw.
>if ( u8StateLast )
>schreiben.

Das ist schon richtig. Gilt aber nur für case 0. Die von mir gewählte 
Schreibweise gilt für jeden case. So kann ich einfach CTRL+C/V machen. 
Ohne die Konstante da anpassen zu müssen.

Beitrag "Re: Programm bzw. Ablaeufe steuern"

von MWS (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> Das ist schon richtig. Gilt aber nur für case 0. Die von mir gewählte
> Schreibweise gilt für jeden case. So kann ich einfach CTRL+C/V machen.

Da sparst ja bei 2 States enorm an Zeit :D
Eventuell im Code noch sValue mit 0 initialisieren ?

von Matthias L. (Gast)


Lesenswert?

>Da sparst ja bei 2 States enorm an Zeit :D

Ja ;-) Aber wie gesagt, das Bsp war von ner Programmierung auf Arbeit. 
DOrt war das PRoblem etwas größer, und die Schrittkette macht dort Sinn. 
Deshalb hatte ich die hier einfach gelassen. Aber nicht nötig.


>Eventuell im Code noch sValue mit 0 initialisieren ?

So recht..?
1
//-----------------------------------------------
2
uint8_t  sString[] = "99|54|34|55";
3
uint8_t  au8Value[4];
4
5
void parse void ( uint8_t* sChar, uint8_t* sValue, uint8_t u8Len )
6
{
7
  uint8_t  u8Cnt       = 0;
8
  //-----------------------------------------------------------
9
  *sValue = 0;
10
11
  while ( *sChar != 0x00 )
12
  {
13
    //-- Trennzeichen ? -----------------------
14
    if ( *sChar == '|' )
15
    {
16
      *++sValue = 0;
17
      if ( ++u8Cnt == u8Len ) return;
18
    }
19
    //-- Ziffer -------------------------------
20
    else if (    ( *sChar >= '0' )
21
              && ( *sChar <= '9' )  )
22
    {
23
      *sValue = (10 * *sValue) + ( *sChar - '0' );
24
    }
25
    //-- weiter -------------------------------
26
    sChar++;
27
  }
28
29
}

von MWS (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> So recht..?

Einwandfrei ;-)

von Markus P. (sebastianwurst)


Lesenswert?

Danke euch, jetzt sind mir auch die Zeiger wieder ein bissel näher 
gekommen! Da tue ich mich immer noch schwer mit..
Was ich nur gemerkt habe ist dass void parse void (... Bei mir ein 
Fehker auslöst. Ich habe nirgends was zum Thema gefunden. Void parse(... 
wird richtig compiliert!

Und warum muss man hier denn nicht mit dem Zeiger arbeiten?

    //-- weiter -------------------------------
    sChar++;

von Matthias L. (Gast)


Lesenswert?

>Was ich nur gemerkt habe ist dass void parse void (... Bei mir ein
>Fehker auslöst.

Ja. Das ist mir noch nicht aufgefallen. Was hab ich denn da für einen 
Mist getippt. So muss es heissen:
1
void parse ( ...
2
{
3
  ..


>Und warum muss man hier denn nicht mit dem Zeiger arbeiten?
>    sChar++;

Tut man doch. Man schiebt den Zeiger ein Element weiter. Würde man 
*sChar schreiben, würde man auf den Zeiger (als da wo der hinzeigt) 
zugreifen.

von Markus P. (sebastianwurst)


Lesenswert?

Danke das klappt.
Einzig noch die Fehlermeldung
1
main.c:1417: warning: pointer targets in passing argument 1 of 'parse' differ in signedness

Liegt ja an den:
1
   #define BUFFER_SIZE  50
2
  char usart_rx_buffer[BUFFER_SIZE];
wenn ich das nur Ändere zieht das einen Rattenschwanz hinter sich...


@ Karl-Heinz
>Wo kommt eigentlich der String her?
>Anderes Programm (per UART) oder Mensch?
Das kommt vom anderen Programm (VB-Oberfläche)

von Markus P. (sebastianwurst)


Lesenswert?

Vielleicht könntest Du mir auch noch dieses Erklären:
1
    //-- Trennzeichen ? -----------------------
2
    if ( *sChar == '|' )
3
    {
4
      *++sValue = 0;
5
      if ( ++u8Cnt == u8Len ) return;
6
    }

Was passiert da mit dem:  *++sValue = 0;
Also wenn das Trennzeichen kommt dann wird der Zeiger um Einen erhöht, 
also eine Positon weiter und gleichzeitig auf Null geschriebn ?
Das verstehe ich nicht.
Vielleicht hilft einer...

von Matthias L. (Gast)


Lesenswert?

>Was passiert da mit dem:  *++sValue = 0;
>Also wenn das Trennzeichen kommt dann wird der Zeiger um Einen erhöht,
>also eine Positon weiter und gleichzeitig auf Null geschriebn ?
>Das verstehe ich nicht.
>Vielleicht hilft einer...

Jein. Gleichzeitig findet garnix statt. Zuerst wird das ++sValue 
bearbeitet. Also der Zeiger namens sValue um ein Element 
weitergeschoben. Anschließend folgt die Zuweisung *sValue = 0; Also wird 
der Zeiger dereferenziert (auf den/die Speicher/zellen zugegriffen, wo 
er hinzeigt) und da eine Null reingeschrieben.


>Einzig noch die Fehlermeldung

Das ist keine Fehlermeldung, sondern eine Warnung. Diese besagt, das der 
Zeiger, den die Funktion parse als erstes Element erwartet ( ein: 
uint8_t*, also ein Zeiger auf uint8_t), du aber beim Aufruf einen Zeiger 
auf ein char mit gibst. Ich glaube das ging im Compiler einzustellen, 
aber char ist wohl vorzeichenbehaftet (signedness).

Kleiner Tip. Wenn ich Strings darstellen will, deklariere ich die immer 
so:
1
uint8_t sString[] ...

Selbst für einen Puffer von Daten nehme ich meistens uint8_t, sofern 
diese irgendwie Byteorientiert vorliegen.

von Markus P. (sebastianwurst)


Lesenswert?

Soweit klappt das jetzt.

Doch habe ich einige Probleme wenn ich die au8Value-Variable an eine ISR 
übergebe die größer als [0] ist
1
    memset ( au8Value, 0, sizeof(au8Value) );
2
    parse( usart_rx_buffer, au8Value, 4 );
3
4
5
    // in au8Value sollten jetzt die Ziffern stehen.
6
7
    usart_write_int(au8Value[0]);
8
    usart_write_int(au8Value[1]);
9
    usart_write_int(au8Value[2]);
10
    usart_write_int(au8Value[3]);      
11
       
12
    u8_Uebergabe = au8Value[0];
Bei au8Value[0] funktioniert die Übergabe am die ISR einwandfrei. Wenn 
ich jedoch [1],[2] oder[3] nehme bleibt der yC hängen. Warum auch immer. 
Die Ausgaben auf die USART sind alle Gleich...
1
ISR (TIMER1_COMPA_vect)
2
{
3
TriacZuenden(u8_Uebergabe ,16);

Dekleration im main.c
1
volatile uint8_t u8_Uebergabe =80;

Dekleration im main.h
1
extern volatile uint8_t u8_Uebergabe;

von numurai (Gast)


Lesenswert?

Markus P. schrieb:
> Dekleration
DEKLARATION bitte, wenn überhaupt auf Deutsch.

von Karl H. (kbuchegg)


Lesenswert?

Markus P. schrieb:

> Doch habe ich einige Probleme wenn ich die au8Value-Variable an eine ISR
> übergebe die größer als [0] ist

Mehr Code

von Markus P. (sebastianwurst)


Lesenswert?

Also das ist die void parse:
1
void parse void ( uint8_t* sChar, uint8_t* sValue, uint8_t u8Len )
2
{
3
  uint8_t  u8Cnt       = 0;
4
  //-----------------------------------------------------------
5
  *sValue = 0;
6
7
  while ( *sChar != 0x00 )
8
  {
9
    //-- Trennzeichen ? -----------------------
10
    if ( *sChar == '|' )
11
    {
12
      *++sValue = 0;
13
      if ( ++u8Cnt == u8Len ) return;
14
    }
15
    //-- Ziffer -------------------------------
16
    else if (    ( *sChar >= '0' )
17
              && ( *sChar <= '9' )  )
18
    {
19
      *sValue = (10 * *sValue) + ( *sChar - '0' );
20
    }
21
    //-- weiter -------------------------------
22
    sChar++;
23
  }
24
25
}
Morgen könnt ich noch die einzelnen Dateien posten

von Markus P. (sebastianwurst)


Angehängte Dateien:

Lesenswert?

Hier hab ich die main's.
Stand ist jetzt das der Triac, der in der ISR gezündet wird, einwandfrei 
funktioniert wenn ich die
1
u8_Uebergabe = au8Value[0];
verwende.
Sobald ich aber
u8_Uebergabe = au8Value[1];
oder
u8_Uebergabe = au8Value[2];
oder
u8_Uebergabe = au8Value[3];
nehme funktioniert das Ganze evtl ein mal und dann hängt sich der yC 
auf. Zu mindest geht dann auch nichts mehr über die USART.
Ich weiss nicht wo er da hängen könnte?
Vielleicht sieht es einer???

von Markus P. (sebastianwurst)


Lesenswert?

Vielleicht Einer nen Tipp??? Sitze immer noch davor...

von Matthias L. (Gast)


Lesenswert?

>>u8_Uebergabe = au8Value[2];

Daran ist nichts auszusetzen. Der Fehler muss woanders liegen.

von Markus P. (sebastianwurst)


Lesenswert?

Findest du denn in der Main irgendwas komisches?

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.