Hallo, ich versuche grad das Ergebnis einer Funktion auf meinem LCD-Display auszugeben. Wie wandle ich den Int-Wert am einfachsten so um ,das z.B int x = 52; sendenLCD(x); dann auch 52 auf dem Display steht und nicht 'r'? Bei Java war das einfach. Einfach die Variable in die Ausgabe einfügen und fertig. z.B. "Ergebnis: "+ x +" lautet." Gibts das auch für C. Ich verwende einen MSP430, IAR und 2x16 Display. Danke für eure Tips. Ich komm grad auf keine Lösung. Gruß Steph
Für den IAR kann ichs leider nicht sagen, aber beim AVR-GCC mach ichs mit dem sprintf() - Befehl. Beispiel: sprintf (text,"+ %d +",x); text muss als char-array definiert sein. Anschließend "text" mit einer entsprechenden Subroutine Zeichen für Zeichen auf dem Display ausgeben.
@thkais wenn ich das richtig versteh schreibt sprintf die Variable x in den char-array text. Was bedeutet %d ?? Die Subroutine wäre dann meine Funktion void sendString(char* Zeichenkette) an die ich nur noch text übergeben muss. Das werd ich gleich mal testen. @ Rahul dein Tip hab ich grad im Kernighan/Ritchie nachgelesen. Ist mir noch etwas unklar werds aber auch aus probieren. Bin halt noch Anfänger. Klappt das dann auch mit Long und Double Werten. Die Int ist nur zum testen. Wenns läuft brauch ich die größeren. Danke Gruß Steph
%d ist eine Zahlendarstellungsvariante. Siehe auch "printf".
>hab ich grad im Kernighan/Ritchie nachgelesen
sehr löblich!
Benutzt habe ich itoa auch noch nie, weil ich die Umwandlung des
Zahlenformats bis jetzt immer händisch/zu Fuß gemacht habe.
@ Rahul Wie geht das zu Fuß bzw wie machst du das? Ich hab ja dann das Problem das ich den Wert '143' in 1, 4 und 3 zerlegen muss. 0b10001111. Hab mir erst gedacht durch Bitmaskierung den Wert quasi in Hunderter, Zehner und Einer zu zerlegen. Hat nicht geklappt, vielleicht hab ich aber nur einen Fehler gemacht.
143 / 10 ist 14 da es sich um integer handelt. 143 % 10 ist 3 (der Rest der Division). 143 / 100 ist also? 143 % 100 ist also? Übrigens findet sich auch im K&R ein Bespiel dazu (zumindest in meiner Ausgabe).
@ Rahul ahh ich verstehe... das gute alte Modulo. Danke. Vermutlich steht es dann auch in meiner Ausgabe. Bestimmt hat es sich nur versteckt, die Sau. ;-). Immer schwierig wenn die Überschriften nicht so grooß sind wie auf dem Wischpapier mit der hohen Auflage und dem großen 'B...' vorne drauf.
klappt nicht, da ist noch der Wurm drin. char* text; void sendInt(int a) { LCDcommand(CMD_CLEAR_DISPLAY); LCDcommand(CMD_CURSOR_HOME); sprintf (text,"+ %d +",a); // hier passiert nichts !! sendString(text); } da wird nichts in Text geschrieben ?? Was ist falsch? Danke
So, kann mir bitte noch mal jemand helfen? Ist jetzt wohl ein reines C-Problem: wenn ich bei der Initialisierung den char-Arry mit 10 festlege schreibt mir itoa(..) korrekte Werte in s[]. Leider funkioniert dann meine Funkion sendeString(char* Zeichenkette); nicht mehr. Initialisiere ich: char s[]; dann schreibt itoa() nichts in s[]. Liegt das daran das mit char s[10] keine richtige Zeichenkette mehr vorliegt. Jedenfalls zeigt der Debuger es als Array an[1][2] und nicht mehr als Zeichenkette {"..."} Danke für Eure Hilfe. C-File angehängt. char s[10]; void itoa(int n, char s[]) // n in Ziffernkette s umwandeln { int i, sign; if((sign = n) < 0) // Vorzeichen notieren n =-n; i =0; do{ s[i] = n % 10; i++; }while ((n /= 10 ) > 0); if(sign < 0) s[i++] = '-'; s[i]= '\0'; reverse(s); } void(main){ itoa(12345,char* s) sendeString(char* zeichenkette) }
Mit char* text wird nur ein Pointer auf einen Speicherbereich gesetzt. Aber wohin? char* text = {" "}; sollte einen Leerstring initialisieren, sprich: Auch den benötigten Speicher reservieren. Evtl. liegts schon daran.
Woher soll dein Programm wissen, dass s und zeichenkette auf den gleichen Speicherbereich zeigen? Die Implementation von s z.B. mit char s[10]; ist OK. Es wird ein Speicherbereich von 10 Zeichen angelegt. Anders geht es auch s. unten
1 | void main() |
2 | {
|
3 | char s[] = "hier soll genug Platz für eine zahl reserviert |
4 | werden"; |
5 | char * zeichenkette; |
6 | |
7 | itoa(12345, s); |
8 | zeichenkette = s; |
9 | sendeString(zeichenkette); |
10 | }
|
11 | [C] |
12 | |
13 | Der Name *itoa* für die eigene Funktion ist unglücklich gewählt. Es |
14 | gibt eine Bibliotheksfunktion, die leicht damit verwechselt werden |
15 | kann, weil sie genauso heisst. |
16 | |
17 | http://www.mkssoftware.com/docs/man3/itoa.3.asp |
18 | |
19 | Der Unterschied ist: Es kann ein beliebiger Radix angegeben werden (bei |
20 | dir ist 10 fest eingestellt) und es wird s zurückgegeben (bei dir keine |
21 | Rückgabe) |
22 | |
23 | Mit der Bibliotheksfunktion könnte man schreiben: |
24 | |
25 | [C] |
26 | void main() |
27 | {
|
28 | char s[] = "hier soll genug Platz für eine zahl reserviert |
29 | werden"; |
30 | sendeString( itoa(12345, s, 10); |
31 | }
|
Woher soll dein Programm wissen, dass s und zeichenkette auf den gleichen Speicherbereich zeigen? Die Implementation von s z.B. mit char s[10]; ist OK. Es wird ein Speicherbereich von 10 Zeichen angelegt. Anders geht es auch s. unten
1 | void main() |
2 | {
|
3 | char s[] = "hier soll genug Platz für eine zahl reserviert werden"; |
4 | |
5 | char * zeichenkette; |
6 | |
7 | itoa(12345, s); |
8 | zeichenkette = s; |
9 | sendeString(zeichenkette); |
10 | }
|
Der Name itoa für die eigene Funktion ist unglücklich gewählt. Es gibt eine Bibliotheksfunktion, die leicht damit verwechselt werden kann, weil sie genauso heisst. http://www.mkssoftware.com/docs/man3/itoa.3.asp Der Unterschied ist: Es kann ein beliebiger Radix angegeben werden (bei dir ist 10 fest eingestellt) und es wird s zurückgegeben (bei dir keine Rückgabe) Mit der Bibliotheksfunktion könnte man schreiben:
1 | void main() |
2 | {
|
3 | char s[] = "hier soll genug Platz für eine zahl reserviert werden"; |
4 | |
5 | sendeString(itoa(12345, s, 10); |
6 | }
|
@thakis Aeh nein. Dein Pointer zeigt zwar auf einen char-String, aber diese character sind const! Das das überhaupt vom Compiler akzeptiert wird, hat historische Gründe, die zähneknirschend akzeptiert werden (mussten). Eigentlich sollte das heissen: const char* test = " "; und alles andere (also: ohne const) einen Fehler ergeben. @Stephan Sag mal: Warum schreibst du eigentlich Funktionen wie strlen() und itoa() selbst? Die hast du bereits in Deiner Libarary drinnen. Alles was du tun musst, ist sie zu verwenden: Fuer alle str... Funktionen (streln, strcat, strcpy) inkludierst du #include <string.h> und itoa() findet sich meist in stdlib.h #include <stdlib.h> (itoa ist keine Standard-C Funktion. d.h. der Compiler muss sie nicht anbieten. Viele tun es aber. Die Funktion heisst dann auch oft _itoa(), mit einem führenden '_' am anzuzeigen, dass es sich hier um eine Nicht-Standardfunktion handelt.
Ich bin davon ausgegangen das iota(int x, s[]){...} das s quasi als Rückgabewert liefert und wenn ich dann meine Funkion sendeString(s); ausführe s als Übergabewert angenommen wird, auch wenn die Funktion eigentlich void sendeString(char* zeichenkette){...} lautet Mein iota(,) ist aus Kernighan/Ritchie abgeschrieben weil ich nichts anderes gefunden hab. Werd mal versuchen zu verstehen was du mir geschrieben hast. Danke Gruß Steph
> char* text; > ... > void sendInt(int a) > { > LCDcommand(CMD_CLEAR_DISPLAY); > LCDcommand(CMD_CURSOR_HOME); > sprintf (text,"+ %d +",a); > sendString(text); > } das kann nichts werden. Wie thakis richtig sagt: Wohin zeigt text? Das Problem ist: 'text' ist ein Pointer. Als solcher ist 'text' daher eine Variable, die eine Speicheradresse aufnehmen kann. In diesem konkreten Fall liegt dort die Adresse im Speicher an der beginnend eine Reihe von Character abgelegt werden kann. Aber: Nur weil du einen Pointer hast, heist das noch lange nicht, dass du auch den entsprechenden Speicher für die Character hast. Den Speicher musst du schon selbst anlegen, der Compiler hat nur den Speicher zur Speicherung der Adresse angelegt. char* text; ist also ein Pointer, der (wie alle globalen Variablen) mit 0 vorinitialisiert wird, d.h. der Pointer zeigt auf die Speicher Adresse 0. Wenn nun sprintf( text, ... ); den String dort ablegt, tja, dann überschreibt er sich damit eine Menge andere Variablen, da ja nirgendwo definiert wurde, dass ab Speicheradresse 0 beginnend ein paar character abgelegt werden. Machst du aber char text[20]; dann könnten theoretisch die 20 character auch bei Adresse 0 abgelegt werden, allerdings: jetzt weiss der Compiler, dass die ersten 20 Speicherzellen zur Speicherung von charactern reserviert sind und legt keine anderen Variablen dorthin. Auch wichtig: Auch wenn sich Pointer und Arrays bei ihrer Verwendung in der Syntax ähneln bzw. über weite Strecken identisch verwendet werden, so sind sie doch verschiedene Dinge. Ein Pointer ist kein Array und ein Array ist kein Pointer. Um einen String zu speichern brauchst du ein charcater-Array, dass gross genug ist um alle Zeichen plus das abschliessende '\0'-Zeichen speichern zu können. Alles andere geht zwar oft syntaktisch durch den Compiler durch, ist aber trotzdem falsch. Letztendlich musst du dich immer fragen: Wo existiert den nun der Speicher, in den ich grade schreibe? Und wenn du nur einen Pointer hast, lautet die nächste logische Frage: WOhin zeigt denn der Pointer?
o.k die Pointer-Problematik, irgendwann holt sie mich ein. Ich habs geahnt. @ Karl-Heinz die obere Methode sendInt() verwende ich nicht mehr, weil mein Compiler sprintf() nicht leiden kann? Daher hab ich's dann mit itoa() versucht. Der IAR hat in der stdlib.h das itoa() nicht stehen nur atoi. Aber vom Prinzip würde meine sendInt() wegen dem Pointer auch nicht laufen. Also mal sehen wie ich das zum laufen bekomm mit itoa() und co. Gruß Steph
Probier mal _itoa() Falls alle Stricke reissen: Probier mal in der Hilfe zum Compiler, ob er so eine Funktion hat. > die obere Methode sendInt() verwende ich nicht mehr, weil mein > Compiler sprintf() nicht leiden kann? Was soll das heissen? Ein Compiler kann nicht irgendetwas leiden oder nicht leiden. Du kannst aber durch Unwissenheit einen oder mehrere schwerwiegende Fehler in ein Program einbauen, sodass das Pgm im schlimmsten Fall die komplette Laufzeitumgebung zerschiesst und nichts mehr funktioniert. Wenn du das als: mein Compiler mag mich nicht ansiehst, .... Wenn du schon einen K&R hast, dann solltest du den auch durcharbeiten. Nach Möglichkeit nicht auf einem AVR, sondern auf einem Desktop-System. Ein µC öffnet dem gegenüber nur einen zusätzlichen Sack an Fehlermöglichkeiten.
int i = 25; int* p = &i; // p zeigt auf i *p = 10; // jetzt ist i = 10 !! wie funktioniert das bei char arrays?? meine Werte stehen jetzt in char s[10]. Wie baue ich einen Zeiger der darauf zeigt und den ich an die Funktion übergeben kann. Oder ist es besser die Funkton umzuschreiben und ihr statt char* ein char s[] zu übergeben? oder geht das auch nicht? Es tut mir leid, aber ich komm nicht drauf. Bin zu doof- sollte wohl besser Metzger werden(die armen Tiere). @stefan : so gehts nicht. char * zeichenkette; itoa(12345, s); zeichenkette = s; sendeString(zeichenkette); @karl heinz: kein itoa beim IAR-Compiler // allso Inhalt von char s[] muss da rein verdammt... void sendString(char* Zeichenkette) { int i; char zeile=0; char spalte=0; LCDcommand(CMD_CLEAR_DISPLAY); LCDcommand(CMD_CURSOR_HOME); for (i=0;Zeichenkette[i]!='\0';i++) { sendChar(Zeichenkette[i]); spalte++; wait(70000); if((Zeichenkette[i]==' ')&&(spalte>12)&&(zeile==0)){ LCDcommand(CMD_2nd_LINE_2x16); zeile++; } }
> Wie baue ich einen Zeiger der darauf zeigt und den ich an die > Funktion übergeben kann. Du brauchst keinen expliziten Zeiger. Benutze einfach das Array: char text[20]; ... sprintf( text, "%d", i ); Arraysa werden in C immer so an Funktionen übergeben, indem ein Zeiger auf das erste Array Element übergeben wird. Das einzige worauf du achten musst ist, dass der String den sprintf erzeugt nicht länger wird als (in diesem Fall) 20 Zeichen. Ist das der Fall, kann gar nichts mehr schief gehen. OK. sprintf ist ein Resourcenfresser. Dafür bietet er aber auch einiges. Mit den FOrmatierungen kann man so manch tolle Dinge ganz einfach machen: zb. %4d der Integer wird in ein Feld der Größe 4 rechtsbündig eingepasst. Gut für Tabellen %04d selbiges wie oben. Nur werden jetzt noch führende Nullen eingebaut. Eine Zahl 25 in i wird als 0025 ausgegeben. ... Noch viel mehr.
Danke für die Hilfe, aber hab ich jetzt nicht mein Ziel verlohren? Du sagst: char text[20]; ... sprintf( text, "%d", i ); Mein anfänglicher Wunsch war es ein Ergebnis einer Berechnung vorliegend als Int,Long oder Double umzuwandeln in eine char* Zeichenkette die ich an mein LCD-Display schicken kann(Funktion vorhanden). printf und sprintf schicken ihre Rückgabewerte an die Standartausgabe. Das ist aber der Bildschirm bzw. die Konsole. Ich müsste also putchar() welches von printf() verwendet wird, umleiten auf mein kleines 2 Zeilen LCD-Modul. Stimmt das? Das klappt bei meinem Kenntnisstand nicht in vertretbarer Zeit. Ich hab dafür auch schon mal ein Beispiel gesehen. Leider hat es nicht funktioniert. Deshalb fand ich itoa eigentlich ganz passend. Gruß Steph
Oh Mann. > als Int,Long oder Double umzuwandeln in eine char* > Zeichenkette Was bitte ist eine char* Zeichenkette :-) Sowas gibt es nicht in C. Du solltest schleunigst im K&R noch mal über Stringbehandlung nachlesen. Und wenn du schon dabei bist, informier dich auch noch über den Array-Pointer Zusammenhang. Es ist genau dieses Nichtwissen, das dich jetzt straucheln laesst. In C werden Zeichenketten immer in einem char-Array gespeichert. Punkt. Wenn du also schreibst: char Test[20] = "Hallo"; dann wird ein Array der Laenge 20 aufgesetzt, dass mit den Buchstaben 'H', 'a', 'l', 'l', 'o', '\0' gefüllt wird. Test +---+---+---+---+---+---+- ...-+---+---+ | H | a | l | l | o | \0| | | | +---+---+---+---+---+---+- ... +---+---+ Soweit so gut. Was passiert bei: char* Test = "Hallo"; Auch hier wird ein Array aufgesetzt. Nur hat dieses Array keinen Namen. Zusätzlich wird noch eine Pointer Variable erzeugt, und das ganze so eingerichtet, dass dieser Pointer auf das Array zeigt. Test +-----+ | o--------------------+ +-----+ | | v +---+---+---+---+---+---+ | H | a | l | l | o | \0| +---+---+---+---+---+---+ Beachte auch: Das Array hat genau die Größe die notwendig ist, um den String "Hallo" aufzunehmen. Weiters darf der Compiler dieses Array im ROM ablegen. D.h. das Array ist für dich als Progammierer unveränderlich. Du kannst dort zwar lesen, kannst aber nicht schreiben. Wenn du einen String beschreiben willst, und sprintf will genau das tun, dann muss das Array zwangsweise irgendwo im RAM-Speicher liegen. d.h. mittels char* Test = "Hallo"; kannst du das nicht erreichen. Also musst du für das Ergebnis selbst ein Array definieren: char Test[20]; Weiters: Wenn ein Array an eine Funktion übergeben wird, so erfolgt dies in C immer in der Form, dass ein Pointer auf das erste Array-Element übergeben wird. Deine Funktion SendString (oder wie die heist) möchte einen Pointer auf den auszugebenden String haben. Dann übergib doch das Array! Arrays werden immer per 'Pointer auf das erste Element' übergeben und genau das will doch deine Funktion: Einen Pointer auf den Beginn des Strings (auf das erste Element). > printf und sprintf schicken ihre Rückgabewerte an die > Standartausgabe. Unsinn Die Rückgabewerte der Funktionen printf und sprintf sind Zahlen. Diese Zahlen geben an, wieviele Konvertierungen durchgeführt werden konnten. printf gibt den durch die Konvertierungen und Ersetzungen entstandenen String nach stdout aus. sprintf schreibt den entstandenen String in den bei sprintf() angegebenen Buffer. Die Verantwortung dafür, dass der Buffer bei sprintf() gross genug ist, trägt der Programmierer. char Text[20]; sprintf( Text, "%d", i ); SendString( Text ); und fertig. Wenn sendString richtig funktioniert, und davon gehe ich mal aus; wenn der Typ im Formatstring (%d) zum Datentyp des Arguments (i) passt; wenn der sprintf()-Buffer (in diesem Fall 'Text') gross genug ist (nun ja: eine einzelne Zahl in einer 16 Bit Variable kann unmöglich 19 dezimale Ziffern haben), dann kann da gar nichts schief gehen. K&R studieren! Das ist alles C-Basiswissen.
oh Mann, danke, vielen Dank. Kannst die Mail gleich ins WIKI setzen. Werde mich gleich heut Abend damit beschäftigen. Falls es nicht klappt werd ich mich jetzt auch nicht mehr melden. Irgendwann ist halt dann genug. Danke, Gruß Steph
Von der Programmiertechnik, die Karl Heinz offensichtlich beherrscht, bin ich natürlich weit entfernt. Falls es aber trotzdem noch interessiert: Im Anhang einige Ausschnitte aus einem bei mir funktionierenden Programm für die Ausgabe eines Zahlenwertes mit einem MSP430 auf einer Flüssigkristallanzeige unter Verwendung des IAR Compilers. (keine neuen Lösungsansätze) Vielleicht hilft es zur Lösung des Problems. MfG Wolfgang
@Wolfgang Danke für die Blumen. Aber das bis jetzt geschilderte ist eigentlich noch sehr einfaches C-Basiswissen. Zu Dienem Code: Ich hoffe du nimmst es mir nicht übel wenn ich da was zu meckern habe. Ein schwerwiegender Punkt ist folgendes: > void Puls1(void) > { > int z,b,c; > char txt[5]; Beachte: txt hat Platz für exakt 5 Zeichen! > WriteData(33); 33 legt fest, wo erstes > Zeichen auf FKL erscheint > WriteData(0); > WriteCtrl(0x24); 0x24 = Kommando > sprintf(txt,"%5d",Puls_A ); Puls_A ist der anzuzeigende Puls-Wert Hier: der sprintf erzeugt aber 6 Zeichen! Wie kommts? %5d ist die Anforderung den int in ein Ausgabefeld bestehend aus 5 Zeichen einzupassen. Der int wird dazu rechtsbündig eingepasst und führende Stellen werden mit einem ' ' gemacht. Die Zahl 123 wird also so " 123" in das Ausgebfeld eingepasst. So weit so gut. Aber: sprintf erzeugt auch einen String! Und so wie jeder andere String in C, ist auch dieser mit einem '\0' Zeichen abgeschlossen. Wird dieser String in txt aufgebaut, so werden tatsächlich 6 Zeichen geschrieben, nicht 5!: txt[0] <- ' ' txt[1] <- ' ' txt[2] <- '1' txt[3] <- '2' txt[4] <- '3' txt[5] <- '\0' Das würde aber ein Array der Größe 6 erfordern, txt ist aber nur ein Array der Größe 5! d.h. das letzte Zeichen überschreibt im Speicher irgendetwas anderes (eine andere Variable oder wenns gar böse kommt, eine Returnadresse, oder ...). Wie die Auswirkungen konkret sind, hängt immer vom Einzelfall (und vom verwendeten Compiler) ab, das kann niemand voerhersagen. Es kann auch sein, dass man den Fehler gar nicht bemerkt, es kann aber auch sein, dass die Maschine abschmiert. Wie auch immer: Fehler ist Fehler. Auch wenn man den Fehler zunächst nicht bemerkt, ist er trotzdem vorhanden. Und Fehler dieser Art sind sehr schwer zu finden. Daher hab ich mir zur Regel gemacht: bei sprintf() und Konsorten nicht kleckern und kleinlich sein. Das Array lieber großzügig dimensionieren als in das Risiko hineinzulaufen, dass ich das Array überlaufe (Im Englischen heist dieser Fehler, ein 'Out of Bounds Access' - 'Ausserhalb der Grenzen Zugriff'). Wenn ich keine Obergrenze habe, dann muss schlimmsten- falls eine andere Technik benutzt werden. Oder eine andere Programmiersprache. In C++ zb. ist es extrem einfach diesen Fehler nicht zu machen :-)
@Wolfgang neben C-Kenntnissen solltest du dir auch noch weitere Kenntnisse anlernen: Ein *.txt Dokument (deines Codes) belegt garde mal 1836 Bytes. Man (du) kannst das auch als Word-Dokument abspeichern und als Anhang einstellen, das belegt dann locker mal 20 Kbytes. Alternativ kannst du das auch noch auf Postscript oder pdf Format aufblasen, da sind locker über 30 Kbytes drin ....
Das stimmt, da habe ich echt gepennt. Zumeist komprimiere ich größere
Dateien mit Winzip. Werde mich in Zukunft bessern.
@ Karl Heinz,
>Ich hoffe du nimmst es mir nicht übel wenn ich da was zu meckern
habe.<
niemals, im Gegenteil. Ich freue mich, wenn ich Tipps erhalte, wie ich
es besser machen könnte.
Aber das ist mal eine Stelle in meinem Programm, die ich bewusst so
gestaltet habe. Da der Puls eines Menschen niemals über 3 Stellen
ansteigen wird, habe ich hier so wenig Zeichen gewählt.
MfG
Wolfgang
> die ich bewusst so gestaltet habe.
Bei allem Respekt. Aber das ist dem sprintg() völlig egal.
Du forderst ihn auf 6 Zeichen in einen 5 character-breiten
Buffer zu schreiben. Und das ist nun mal ein Fehler.
char txt[5];
sprintf(txt,"%5d",Puls_A ); Puls_A ist der anzuzeigende
***
Egal was deine Absichten waren: 6 Zeichen passen nun mal
nicht in ein Array der Länge 5.
Habe ich es jetzt richtig verstanden? char txt[5]; sprintf(txt,"%4d",Puls_A ); Obwohl wir hier nicht in einem C-Programmierkurs sind, aber Karl Heinz aus meiner Sicht immer fundierte und ausführliche Antworten gibt, mal eine Frage zu einer wahrscheinlich einfachen Sache: return soll ja bei einer Funktion den in der Klammer stehenden Wert zurückgeben. aus einem Demoprogramm von TI zur Kopplung einer MMC/SD -Speicherkarte an einen MSP430: unsigned char spiSendByte(const unsigned char data) { while ((IFG1&UTXIFG0) ==0); // wait while not ready / for RX TXBUF0 = data; // write while ((IFG1 & URXIFG0)==0); // wait for RX buffer (full) return (RXBUF0); } meine Fragen: - wie komme ich zu dem im Empfangsregister RXBUF stehenden Wert? - wann wird RXBUF geleert? Vielleicht kann Karl Heinz eine Antwort an meine oben stehende e-mail Adresse senden. MfG Wolfgang
x = spiSendByte(d); und schon steht RXBUF in x. IMHO wird erst RXBUF gelesen (und damit vermutlich auch gelöscht) und dann auf den Stack geschrieben, wo ihn die aufrufende Funktion abholen kann.
> Habe ich es jetzt richtig verstanden? > > char txt[5]; > sprintf(txt,"%4d",Puls_A ); Jetzt hast du's. Der Grund warum ich darauf so rumreite ist der, dass * solche Fehler häufig passieren * solche Fehler gern übersehen werden * die Auswirkungen des Fehlers nicht abschätzbar sind (dein Programm verhält sich dann morgen u.U anders als heute. Stichwort unter Programmierern: 'Das lief aber schon mal.' * solche Fehler immer im ungünstigsten Moment zuschlagen * solche banale Fehler enorme Kosten in der Behebung verursachen, da sie in einem größeren Projekt praktisch nicht zu finden sind. Um sowas zu finden, braucht man normalerweise auch immer etwas Glück. > return soll ja bei einer Funktion den in der Klammer stehenden > Wert zurückgeben. Letzteres ist ein Irrtum: Der zurückzugebende Wert muss keineswegs in Klammern stehen. 'return' ist ja kein Funktionsaufruf sondern ein ganz normales C-Schlüsselwort. > wie komme ich zu dem im Empfangsregister RXBUF > stehenden Wert? Wenn du RXBUF0 lesend benutzt, wird das entsprechende Hardware-Register ausgelesen und der darin enthaltene Wert geliefert. Er ist dann Returnwert der Funktion. Den Wert kriegt dann der Aufrufer der Funktion zur Verfügung gestellt. Zb. so unsigned char Received; ... Received = spiSendByte( 'a' ); 'a' ist das zu sendende Zeichen. spiSendByte sendet dieses, wartet danach auf Antwort (die 2.te while-Schleife), holt die Antwort aus RXBUF0 ab und returniert diese an den Aufrufer. Der Aufrufer seinerseits speichert, das was spiSendByte liefert (nämlich den Inhalt von RXBUF0) in einer Variablen 'Received' ab. > wann wird RXBUF geleert? Ich würde mal sagen, gar nicht. Aber wenn wieder was neues über die Schnittstelle reinkommt, dann wird RXBUF0 überschrieben. > oben stehende e-mail Adresse senden. Normalerweise heist es in Newsgroups immer: You post here, you read here Ausserdem mache ich auch Fehler. Und da ist es schon gut wenn Andere auch noch korrekturlesen.
<warum ich darauf so rumreite> das hast du richtig gemacht, denn aus meinen Argumenten war für dich erkennbar, dass ich noch gar nicht verstanden hatte, worum es wirklich geht. Was du zu return geschrieben hast, werde ich mir nun genauer ansehen. Danke Auf e-mail kam ich, weil mein Frage eigentlich nicht unmittelbar zum Thema gehört. MfG Wolfgang
> Was du zu return geschrieben hast, werde ich mir nun genauer > ansehen. Ist im Grunde ganz simpel. Die C-Syntax verlangt nicht, dass der Ausdruck nach dem return, sofern einer vorhanden ist, in Klammern geschrieben wird. Das ist einfach nur ein Ausdruck, der einen Wert liefern muss. Mehr nicht. Das ist genauso, wie du bei einer Zuweisung auch nicht den rechts vom '=' stehenden Teil in Klammern schreiben musst. Das ist genaus einfach nur ein Ausdruck, der einen Wert liefert. Du schreibst ja auch nicht i = ( 5 ); sondern i = 5; Obwohl: wenn du unbedingt willst, kannst du natuerlich die Klammern schreiben. Genauso hier return 5; Wenn du unbedingt willst, kannst du natuerlich schreiben return ( 5 ); Ist aber genauso nicht notwendig, wie im Beispiel mit der Zuweisung. In beiden Fällen wird nur verlangt, dass da ein Ausdruck steht, der zu einem Wert führt. Syntaktisch gesehen ist es in beiden Fällen sogar das selbe Sprachelement, das hier verlangt wird. D.h. du kannst bei einem return alles machen, was du auch auf der rechten Seite einer Zuweisung machen kannst und natürlich umgekehrt.
Hallo, hab jetzt noch mal ne Frage zur Formatierung der Ausgabe nachdem meine Ausgabe jetzt funktioniert. void sendDouble(double a){ int z,b; char txtDouble[33]; sprintf (txtDouble,"%.02E",a); for (z=0; z<9;z++){ b=txtDouble[z]; sendChar(b); } } sendDouble(0.000044); erzeugt eine Ausgbabe: 4.40E-05[] Das [] ist ein schwarzes Kästchen. O.k. das Kästchen bekomm ich weg mit z<8 oder ich sende eine neg.Zahl. Wie kann ich das dynamisch anpassen? Der Wert kann ja auch mal kleiner oder größer sein, oder muss ich mich auf eine bestimmte Zahl an Nachkommastellen festlegen mit +/- Vorzeichen. Zu dem würde es mir besser gefallen die Ausgabe würde so aus sehen: 440E-03. Das hab ich leider nicht heraus gefunden wie das geht. Gruß Steph
Alle C Funktionen, die mit Strings arbeiten, befolgen eine Konvention: jeder String wird mit einem 0-Byte (in C-speak: ein '\0'-character) abgeschlossen. D.h. anstatt einer fixen Laufweite, gibst du einfach Zeichen aus, bis du auf den abschliessenden '\0' stoest: z = 0; while( txtDouble[z] != '\0' ) sendChar( txtDouble[z++] ); oder etwas kürzer: z = 0; while( txtDouble[z] ) sendChar( txtDouble[z++] ); irgendwann bist du dann die Array-Syntax leid und wandelst das ganze in Pointer-Syntax um: void sendDouble( double a ) { char txtDouble[33]; char* tmp = txtDouble; sprintf( txtDouble, "%.02E", a ); while( *tmp ) sendChar( *tmp++ ); }
> Zu dem würde es mir besser gefallen die Ausgabe würde so aus sehen: > 440E-03. Ich denke nicht, dass das mit printf nur durch die Formatierung möglich ist. Da müsste man selbst Hand anlegen.
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.