Hallo, ich bin mittlerweile am Verzweifeln mit meinem ATTiny 26 und LCD Ausgabe wenn ich die Funktion: void lcd_putint(int value){ char tmp[10]; itoa(value, tmp, 10); // for (int i= 0;10;i++){buf[i]= tmp[i];} (A) // lcd_putword(buf); lcd_string(tmp); (B) /* lcd_data(buf[4]); (C) lcd_data(buf[3]); lcd_data(buf[2]); lcd_data(buf[1]); lcd_data(buf[0]); */ } benutze erfolg die Ausgabe verkehrt herum also für lcd_putint(12345) erhalte ich auf dem LCD: 54321 Füge ich die Zeile (A) in die Routine ein erfolgt gar keine Ausgabe mehr ersetze ich die Zeile (B) mit Zeilen (C) ohne Zeile (A) ist die Ausgabe auf dem LCD korrekt sende ich jedoch einen String mit lcd_string("Hallo "); erfolgt die Ausgabe auf dem LCD korrekt Hilfe !! By Wolfgang
Gott ist die Fehlerbeschreibung schlecht! "ersetze ich die Zeile (B) mit Zeilen (C) ohne Zeile (A) ist die Ausgabe auf dem LCD korrekt" Und hier kommt Antwort D wobei E vor F gelesen werden muss damit H Sinn macht. (D) (H) da ja temp den Wert beinhaltet. Was weiß der Henker was buf ist ..... (F) und der Variable int value keinerlei Verbindung besteht, (E) Kann gar nicht sein, da ja zwischen der Ausgabe lcd_data(buf[x]);
ok neuer Ansatz: void lcd_putint(int value){ char tmp[10]; itoa(value, tmp, 10); lcd_string(tmp); } lcd_putint(12345) ergibt auf dem LCD 54321 void lcd_putint(int value){ char tmp[10]; itoa(value, tmp, 10); lcd_data(buf[4]); lcd_data(buf[3]); lcd_data(buf[2]); lcd_data(buf[1]); lcd_data(buf[0]); } lcd_putint(12345) ergibt auf dem LCD 12345 void lcd_putint(int value){ char tmp[10]; char buf[10]; itoa(value, tmp, 10); for (int i= 0;10;i++){buf[i]= tmp[i];} lcd_string(tmp); } lcd_putint(12345) ergibt auf dem LCD nothing bevor die Frage gestellt wird wofür ist die Zeile for (int i= 0;10;i++){buf[i]= tmp[i];} sollte eigentlich heisen for (int i= 10;0;i++){buf[i]= tmp[10-i];} um die Ausgabe umzudrehen (später noch mit Abfrage nach null usw) was ich nicht verstehe : warum ist der Wert im TMP weg und warum ist die Ausgabe falsch rum bei der Simmulation ist sie korrekt nochmals ATtiny 26 By Wolfgang
Wolfgang Hopperdietzel wrote: > was ich nicht verstehe : warum ist der Wert im TMP weg tmp ist eine lokale Variable und nicht static definiert. Nach Verlassen der Funktion in der tmp definiert wurde ist die Variable weg. > und warum ist die Ausgabe falsch rum bei der Simmulation ist sie korrekt Das korrekte Arbeiten von itoa() kann ich in der Simulation nachvollziehen (s. Anhang). Was dahinter kommt - Ausgabe auf LCD - nicht. Was passiert, wenn du Texte auf das LCD schickst (lcd_string("abcde")? Vielleicht ein Initialisierungsfehler am LCD?
Stefan B. wrote: > Wolfgang Hopperdietzel wrote: > > > Was passiert, wenn du Texte auf das LCD schickst (lcd_string("abcde")? > Vielleicht ein Initialisierungsfehler am LCD? Kann ich nicht nachvollziehen da ich das Display nur am Anfang initialisiere Textausgabe ist korrekt und wenn ich den umgewandelten int String verkehrt ausgebe passt es ja auch Ich glaube ich stehe auf Krigsfuß mit Atmega und C Aktuell habe ich den Attiny 26 und den Atmega 168 und wenn ich mein aktuelles Versuchsprogramm mit Text und Zahlenausgabe auf den Tiny laufen lasse habe ich eine Ausgabe Text richtig Zahl falsch rum. Selbes Programm mit Atmega 168 in AVR Studio unter Project Option Device eingestellt compiliert mit Richtiger Taktfrequenz LCD Anzeige gleich null
Vielleicht geht dem itoa() beim Erzeugen des Strings der Platz aus. Oder du hast eine uralte Version der avr-libc. Es gab mindestens eine Version mit diesem Fehler. Halte ich aber für unwahrscheinlich, weil es mit dem Atmega 168 funktionierte. Hintergrund: Das itoa() aus der avr-libc wandelt zunächst in einen String mit umgekehrter Zeichenfolge. Erst am Ende von itoa() wird strrev() aufgerufen, um den String umzudrehen. Wieviel Platz du an der Stelle in deinem Programm noch im RAM (Der Attiny26 hat insgesamt nur 128 Bytes SRAM!) hast, sieht man schwer, weil tmp eine lokale Variable ist. Einfacher wäre es, tmp mal global zu machen bzw. einen anderen globalen Puffer mitzubenutzen.
1 | char tmp[10]; |
2 | void lcd_putint(int value) |
3 | {
|
4 | itoa(value, tmp, 10); |
5 | lcd_string(tmp); |
6 | }
|
Wolfgang Hopperdietzel wrote:
> for (int i= 0;10;i++){buf[i]= tmp[i];}
"10" als Schleifenbedingung ist bestimmt nicht, was du machen
wolltest... und ich wette, das ist nicht der Code, den du laufen
gelassen hast.
Hallo bin leider c Newcommer ich dachte > for (int i= 0;10;i++){buf[i]= tmp[i];} steht für: for i= 0 to 10 i+1 do By Wolfgang
Stefan B. wrote: > > char tmp[10]; > void lcd_putint(int value) > { > itoa(value, tmp, 10); > lcd_string(tmp); > } > [/C] hab ich auch schon probiert ergebnis war so wie es sein sollte und wurde dann durch die Warnungen wieder abgeschreckt ../lernenmega8.c:53: warning: passing argument 2 of 'itoa' discards qualifiers from pointer target type ../lernenmega8.c:56: warning: passing argument 1 of 'lcd_string' discards qualifiers from pointer target type By Wolfgang
Zeile 53 und 56 sehe ich im Moment nicht. Mein Beispiel hat ja weniger Zeilen. Wenn die Warnungen die Benutzung von tmp in diesen beiden Zeilen betrifft: > itoa(value, tmp, 10); > lcd_string(tmp); dann kannst du die Warnungen ignorieren.
Stefan B. wrote: > Zeile 53 und 56 sehe ich im Moment nicht. Mein Beispiel hat ja weniger > Zeilen. Wenn die Warnungen die Benutzung von tmp in diesen beiden Zeilen > betrifft: > >> itoa(value, tmp, 10); >> lcd_string(tmp); > > dann kannst du die Warnungen ignorieren. Warnungen, deren Grund man nicht kennt, soll man nie ignorieren !!! Also herausfinden, woher die Warnungen kommen. Die Zeilen werden bei mir ohne Warnungen compiliert (GCC 4.3.0). Es wird also irgendwas in den 50 Zeilen davor oder einem Include oder einem Compilerschalter stehen, was die Warnungen provoziert. Peter
Stefan B. wrote: > Zeile 53 und 56 sehe ich im Moment nicht. Mein Beispiel hat ja weniger > Zeilen. Wenn die Warnungen die Benutzung von tmp in diesen beiden Zeilen > betrifft: > >> itoa(value, tmp, 10); >> lcd_string(tmp); > > dann kannst du die Warnungen ignorieren. Danke das war´s Ausgabe ist ok Kann ich es noch so umstellen dass ich keine Warnungen mehr bekomme ? By Wolfgang
Wahrscheinlich sind in den Zeilen 53 und 56 die Prototypen für die Funktionen itoa() und lcd_string() noch nicht bekannt. Der C Compiler nimmt dann int Argumente an und tmp (char *) passt da nicht. Wahrscheinlich fehlt das #include <stdlib.h> für itoa() am Programmanfang und lcd_string() wird wahrscheinlich nach lcd_putint() definiert oder es fehlt das #include der "lcd.h"-ähnlichen Datei, wenn es eine Fremdlibrary ist. PS: Peter hat natürlich Recht! EDIT: In deinem anderes Thread hast du eine Source für lcd_string() drin: Beitrag "Re:./lernen3.c:87: warning: assignment makes pointer from integer without a cast" Dort arbeitet die Funktion mit Zeichenketten aus dem ROM und nicht mit Zeichenketten aus dem RAM. Wenn du die hier nimmst, ist es klar wieso das unpassende Argument gemeldet wird. Mich wundert in dem Fall, dass es funktioniert hat. Vorschlag für Ersatzfunktion:
1 | void lcd_string_ram(char *s) |
2 | {
|
3 | while(*s) |
4 | {
|
5 | lcd_data(*s); |
6 | s++; |
7 | }
|
8 | }
|
Bzw. die Konvention ist eigentlich, dass man Funktionen, die mit ROM-Daten arbeiten speziell benennt also hier lcd_string_P(...).
ok, hab die Routine in meine LCD include übertragen mit der externen tmp Deklaration volatile Funktion ist OK Warnung = 0; Danke Wolfgang
Stefan B. wrote: > > Dort arbeitet die Funktion mit Zeichenketten aus dem ROM und nicht mit > Zeichenketten aus dem RAM. Wenn du die hier nimmst, ist es klar wieso > das unpassende Argument gemeldet wird. Mich wundert in dem Fall, dass es > funktioniert hat. > > Vorschlag für Ersatzfunktion: >
1 | >
|
2 | > void lcd_string_ram(char *s) |
3 | > { |
4 | > while(*s) |
5 | > { |
6 | > lcd_data(*s); |
7 | > s++; |
8 | > } |
9 | > } |
10 | >
|
> > Bzw. die Konvention ist eigentlich, dass man Funktionen, die mit > ROM-Daten arbeiten speziell benennt also hier lcd_string_P(...). Das ist eigentlich die Art wie ich bisher in 80c51 programmiert habe nur wie schreibe ich hier mit C die Daten in das ROM (bin immer noch am Anfang mit C) By Wolfgang
Wolfgang Hopperdietzel wrote: > Das ist eigentlich die Art wie ich bisher in 80c51 programmiert habe > nur wie schreibe ich hier mit C die Daten in das ROM (bin immer noch am > Anfang mit C) Ein ganz dezenter Hinweis: AVR-GCC-Tutorial ;-) Also normalerweise sind die Daten im RAM, nur wenn man besondere Klimmzüge macht, kann man einen Teil der Daten (unveränderliche halt) auch im ROM halten und nutzen z.B. um wertvollen RAM-Platz zu sparen. Im Tutorial oben kommen diese Klimmzüge, wenn 90% anderes, wichtiges erklärt ist... Jedenfalls, diese Klimmzüge sind in der lcd_string() aus Beitrag "Re:./lernen3.c:87: warning: assignment makes pointer from integer without a cast" gemacht, aber das kollidiert mit der Benutzung in obiger Funktion lcd_putint(). DORT soll aus der Quelle RAM ausgegeben werden und da passt keine Funktion, die aus der Quelle ROM ausgibt.
Stefan B. wrote: > > Ein ganz dezenter Hinweis: AVR-GCC-Tutorial ;-) > > Also normalerweise sind die Daten im RAM, nur wenn man besondere > Klimmzüge macht, kann man einen Teil der Daten (unveränderliche halt) > auch im ROM halten und nutzen z.B. um wertvollen RAM-Platz zu sparen. Im > Tutorial oben kommen diese Klimmzüge, wenn 90% anderes, wichtiges > erklärt ist... > > Jedenfalls, diese Klimmzüge sind in der lcd_string() aus > Beitrag "Re:./lernen3.c:87: warning: assignment makes pointer from integer without a cast" gemacht, aber das > kollidiert mit der Benutzung in obiger Funktion lcd_putint(). DORT soll > aus der Quelle RAM ausgegeben werden und da passt keine Funktion, die > aus der Quelle ROM ausgibt. Bin ich immer wieder am Schauen AVR-GCC-Tutorial ;-) nur manchmal findet man den Wald vor lauter Bäume nicht (Bittte nicht kommentieren) Klar, eingelesene Werte im ROM zu speichern ist Käse mir geht es hier vielmehr um Statische Anzeige Texte. Es ist schön wieder einen neuen Ansatz gefunden zu haben und ich werde umgehend AVR-GCC-Tutorial ;-) zum 20. mal durchstöbern Danke By Wolfgang
Hallo Wolfgang, die Ausgabe ist tatsächlich falsch. Der ATtiny26 erzeugt mit der Bibliotheksfunktion itoa einen falschen Ausgabewert. Siehe hier: Beitrag "Problem mit ltoa" Gruß Joachim
Wolfgang Hopperdietzel schrieb: > itoa(value, tmp, 10); Die auf dem ATtiny26 auftretenden Anweichungen kann man wie folgt umgehen:
1 | itoa(value, (char*) ((int)tmp & 0xff), 10); |
Gruß Joachim
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.