www.mikrocontroller.net

Forum: Compiler & IDEs Variable aus dem PC in uc speichern


Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo zusammen,

ich habe ein kleines Problemchen und zwar, ich moechte zwei Zahlen (z.B. 
200000;300000) zum uC uebertragen und dort berechnen. Mit kleinen Zahlen 
hat es geklappt, aber solbald ich grosse Zahlen uebertrage, dann lassen 
sie sich nicht richtig zum Zahlen konvertieren.
Ich uebertrage die Daten per RS232 als String. Ich kann sie als String 
lesen, aber ich brauche sie als Zahlen.

hat jemand eine Idee

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hat jemand eine Idee
ja, aber zeig mal lieber den Quellcode man sehen kann wo der Fehler ist.

Autor: Joachim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

<Pseudocode an>

Zahl = 0

rotiere bis endezeichen empfangen
   zahl = zahl * 10
   zahl = zahl + empfangenes digit
beginne wieder bei rotiere

<pseudocode aus>

zahl sollte groß genug sein, um deine übertragene Zahl zu speichern.

Gruß
Joachim

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi Peter,

hier mein code:



main()
{
...

  while(1)
  {
       uart_gets(tmp, sizeof(tmp) );
       split(tmp, sizeof(tmp) );
  }
}
unsigned char Getch1(void)    // Waits for and returns incoming char
{
  unsigned char rxchar;

  for(;;)
  {
    while(SSR1_RDRF == 0)     // Wait for data received
    {
      __wait_nop();
    }

    rxchar = RDR1;            // Save receive register

    if ((SSR1 & 0xE0) != 0)   // Check for errors PE, ORE, FRE
    {
      SCR1_CRE = 1;           // Clear error flags
    }
    else
    {
      return (rxchar);        // Return received character
    }
  }
}
void uart_gets( char* Buffer, int MaxLen )
{
  int NextChar;
  int StringLen = 0;

  NextChar = Getch1();         // Warte auf und empfange das nächste 
Zeichen

                                  // Sammle solange Zeichen, bis:
                                  // * entweder das String Ende Zeichen 
kam
                                  // * oder das aufnehmende Array voll 
ist
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
    *Buffer++ = NextChar;
    StringLen++;
    NextChar = Getch1();
  }
                                   // Noch ein '\0' anhängen um einen 
Standard
                                   // C-String daraus zu machen
  *Buffer = '\0';
}
void split(char* Buffer, int MaxLen )
{
    int i = 0;
    int m =0;
    int j =0;
    char Data[2][256];
    int a=0,b=0;
    while( i < MaxLen - 1 )
    {
       if(Buffer[i] == ';' || i == MaxLen -1)
       {
         Data[m][j] = '\0';
         m++;
         j=0;
         i++;

       }
       Data[m][j] = Buffer[i];
       i++;
       j++;
    }
    #define fr atof(Data[0])
    #define bd atof(Data[1])
    sprintf(a,Data[0]);
    sprintf(b,Data[1]);
    Putch1(13);
    Puts1("Your Frequency is: ");
    Puti(a);
    Putch1(13);
    Puts1("Your baudrate is: ");
    Puti(b);
    Putch1(13);
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Split Funktion benötigt MaxLen gar nicht.
Du baust deine String Splitterei momentan auf der Array Größe auf. Aber 
das darfst du nicht. Du hast den String bereits. Das \0 Byte am Ende des 
Strings zeigt dir, wo der String aufhört. Und das muss nicht 
notwendigerweise das Array-Ende sein.


    #define fr atof(Data[0])
    #define bd atof(Data[1])
    sprintf(a,Data[0]);
    sprintf(b,Data[1]);

Du trickst dich wohl gerne selber aus?

Welchen Datentyp hat a? Welchen hat b? Was will sprintf als ersten 
Parameter haben? Hat dein Compiler dazu gar nichts zu sagen?


Die ganze Funktion ist .... nicht gut geschrieben.
Sieh erst mal zu, dass du deinen String sauber in die beiden Teilstrings 
zerlegen kannst. Lass dir die Teilstrings ausgeben und ehe die nicht 
stimmen hat es keinen Sinn, da weiter zu machen.
Wenn die Strings korrekt sind, benutzt du atoi zur Umwandlung der 
Textrepräsentierung in richtige Zahlen (oder atol wenn die Zahlen größer 
sind)

Und räum den Code auf! Es hat keinen Sinn da Variablen und Makros 
rumlungern zu lassen, die nirgends benutzt werden. Du trickst dich damit 
nur selber aus und verlierst die Übersicht.

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,

ich habe schon so probiert, aber sobald ich die Werte 200000;200000 
eingebe,
dann stimmen sie nicht mehr:

    long a,b;
    a = strtol (Data[0], p, 10);
    b = strtol (Data[1], p, 10);
    Putch1(13);
    Puts1("Your Frequency is: ");
    Puti(a);
    Putch1(13);
    Puts1("Your baudrate is: ");
    Puti(b);
    Putch1(13);

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tetef El schrieb:
> hi,
>
> ich habe schon so probiert, aber sobald ich die Werte 200000;200000
> eingebe,
> dann stimmen sie nicht mehr:
>
>     long a,b;
>     a = strtol (Data[0], p, 10);
>     b = strtol (Data[1], p, 10);

Du kannst anstelle von p auch einfach NULL benutzen, wenn dich der 
Endpointer nicht interessiert. Das ist auch sicherer, denn im Moment 
stehen die Chancen nicht schlecht, dass dir strtol irgendwo im Speicher 
etwas niederbügelt, was du gar nicht haben willst.

      a = strtol (Data[0], NULL, 10);
      b = strtol (Data[1], NULL, 10);


>     Putch1(13);
>     Puts1("Your Frequency is: ");
>     Puti(a);

a ist ein long.
Wofür wohl das i in Puti steht?

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puti ueberytraegt Int oder long.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tetef El schrieb:
> Puti ueberytraegt Int oder long.

Zeigen.
Das glaub ich nämlich erst, wenn ich es sehe :-)
Normalerweise hat es einen Grund, warum man die Funktion Puti nennt und 
nicht Putl (l wie long). Ein Putl könnte int und long bearbeiten, weil 
ein int auch in einen long passt. Aber umgekehrt gehts nicht.

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Ein Putl könnte int und long bearbeiten, weil
ein int auch in einen long passt. Aber umgekehrt gehts nicht."

Hier ist die Funktion: ich habe sie umbennant, aber das Problem ist 
immer das gleiche.

void Putl(long val)
{
  long val2;

  val2 = val / 1000000;
  Putch1(val2 + 0x30);

  val = val - (val2 * 1000000);
  val2 = val / 100000;
  Putch1(val2 + 0x30);

  val = val - (val2 * 100000);
  val2 = val / 10000;
  Putch1(val2 + 0x30);

  val = val - (val2 * 10000);
  val2 = val / 1000;
  Putch1(val2 + 0x30);

  val = val - (val2 * 1000);
  val2 = val / 100;
  Putch1(val2 + 0x30);

  val = val - (val2 * 100);
  val2 = val / 10;
  Putch1(val2 + 0x30);

  val = val - (val2 * 10);
  Putch1(val + 0x30);
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow.
Du machst dir viel Arbeit :-)
Aber ok. Die Funktion ist so ok.


Hast du dir schon die Teilstrings angesehen? Und btw. deine Aufteilerei 
ist nicht in Ordnung. Du darfst die while Schleife nicht bis MaxLen - 1 
laufen lassen, sondern nur solange du noch im String bist.

Ausserdem solltest du noch sicher stellen, dass der 2-te Teilstring mit 
einem '\0' abgeschlossen wird. Selbst dann, wenn in der Übertragung kein 
zweiter ; auftaucht.
    while( Buffer[i] != '\0' )
    {
       if(Buffer[i] == ';' || i == MaxLen -1)
       {
...

Schritte:
zuerst den empfangenen String ausgeben lassen um zu sehen, ob da 
überhaupt das drinnen steht, was du denkst das drinnen stehen sollte
dann die Teilstrings nach der Zerlegung.
und erst dann die umgewandelten Ergebnisse.


Ach was solls. Ich würds so machen
void split(char* Buffer, int MaxLen )
{
  long a = 0;
  long b = 0;
  char* end;

  Puts1( "\nParsing String: &");
  Puts1( Buffer );
  Puts1( '&');

  a = strtol( buffer, &end, 10 );
  if( *end == ';' ) {
    buffer = end + 1;
    b = strtol( buffer, &end, 10 );
  }

  Puts1( "\nYour Frequency is: ");
  Putl( a );

  Puts1( "\nYour baudrate is: " );
  Putl( b );

  Putch1( '\n' );
}

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Ergebnis fuer diese Funktion:

Input:
200000;30000
Output
Parsing String: &200000;30000

Your Frequency is: 0003392
Your baudrate is: 0030000,

wie Du siehst, wenn ein Zahl mehr als 5 Stellig dann funktioniert nicht.

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat das nicht mit dem Complir zu tun?
ich gehe davon aus, dass mein Complire ist 16 bit. daher kann er nur:

ul: 0 65535
l: -32768 32767

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry
ich meinte Compiler

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tetef El schrieb:
> Als Ergebnis fuer diese Funktion:
>
> Input:
> 200000;30000
> Output
> Parsing String: &200000;30000
>
> Your Frequency is: 0003392
                        ^^^^ siehe unten
> Your baudrate is: 0030000,

200000 - 3 * 65536 = 3392

Irgendwo gehen Dir die Bits oberhalb von 16 flöten.

Gruß,

Frank

Autor: Leandro Leandro (tetef)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie kann ich es beheben?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tetef El schrieb:
> wie kann ich es beheben?

Nochmal den kompletten Code.
Irgendwo ist höchst wahrscheinlich eine Umrechnung nach int 
(möglicherweise auch implizit) die nicht sein soll.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.