Forum: Compiler & IDEs lcd_putint falsche Ausgabe


von Wolfgang H. (hastekene)


Lesenswert?

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

von ich (Gast)


Lesenswert?

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]);

von Wolfgang H. (hastekene)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?


von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

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?

von Wolfgang H. (hastekene)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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
}

von P. S. (Gast)


Lesenswert?

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.

von Wolfgang H. (hastekene)


Lesenswert?

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

von Wolfgang H. (hastekene)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Wolfgang H. (hastekene)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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(...).

von Wolfgang H. (hastekene)


Lesenswert?

ok,
hab die Routine in meine LCD include übertragen
mit der externen tmp Deklaration  volatile

Funktion ist OK

Warnung = 0;

Danke Wolfgang

von Wolfgang H. (hastekene)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Wolfgang H. (hastekene)


Lesenswert?

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

von Joachim (Gast)


Lesenswert?

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

von Joachim (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.