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
> hat jemand eine Idee
ja, aber zeig mal lieber den Quellcode man sehen kann wo der Fehler ist.
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
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); }
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.
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);
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?
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.
"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); }
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.
1 | while( Buffer[i] != '\0' ) |
2 | {
|
3 | if(Buffer[i] == ';' || i == MaxLen -1) |
4 | {
|
5 | ...
|
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
1 | void split(char* Buffer, int MaxLen ) |
2 | {
|
3 | long a = 0; |
4 | long b = 0; |
5 | char* end; |
6 | |
7 | Puts1( "\nParsing String: &"); |
8 | Puts1( Buffer ); |
9 | Puts1( '&'); |
10 | |
11 | a = strtol( buffer, &end, 10 ); |
12 | if( *end == ';' ) { |
13 | buffer = end + 1; |
14 | b = strtol( buffer, &end, 10 ); |
15 | }
|
16 | |
17 | Puts1( "\nYour Frequency is: "); |
18 | Putl( a ); |
19 | |
20 | Puts1( "\nYour baudrate is: " ); |
21 | Putl( b ); |
22 | |
23 | Putch1( '\n' ); |
24 | }
|
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.
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
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.