Forum: Mikrocontroller und Digitale Elektronik schreiben von neg Zahlen auf LCD


von frewer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hänge bereits seit längerer Zeit mit einem eigenartigen Problem fest. 
Ich schreibe pos und neg Zahlen in das EEPROM (ATMEGA32) und versuche 
mit einem Formatierungsroutine die zahlen auf ein LCD zu bekommen. Das 
klappt auch ganz ordentlich mit einer Ausnahme. Wenn ich für Zahlen, die 
sich im Bereich 0-99 (pos oder neg) bewegen, im EEPROM in jeweils 1Byte 
schreibe, dann wird die pos Zahl korrekt ausgegeben, die neg Zahl wird 
bei der Abfrage nach <100 abgeblockt, obwohl ich die Zahl davor pos 
gemacht habe "wert=-wert".
Ich habe auch schon versucht den Zahlen im EEPROM 2 Bytes zu spendieren. 
Das ändert aber nichts an der Ausgabe.
Ich habe mal die Passagen aus dem Programm und den EEPROM-Anteil (Zahlen 
sind hervorgehoben) angehängt.
Insgesamt funktioniert dieser Programmteil durch Aufruf des Menüs void 
Verbrauch(void). Es benutzt zum Anzeigen die Formatierung und ASCII 
Wandlung in void RAW_int(.....).

Kann mir jemand helfen????
mfG
frewer

von holger (Gast)


Lesenswert?

Du glaubst doch nicht ernsthaft das jemand dein Word Dokument öffnet?
Poste die Datei die den Code enthält.

von Bernhard S. (b_spitzer)


Lesenswert?

Wenn Du in C programmierst, nimm mal sprintf(Buffer[],"Zahl: %d",Wert);
Danach mit Deiner LCD-Funktion den Buffer[] auf das Display schieben.

unn tschuess
B.

von Werner F. (frewer)


Lesenswert?

Danke Holger,

Ich dachte, dass ich nur den wesentlichen Auszug aus dem Gesamtprogramm 
mache, der sich mit dem Thema beschäftigt. Zusätzlich habe ich den 
EEPROM-Inhalt heruntergeladen und leserlich gemacht. Deshalb das 
Word.doc, das nicht so umfangreich ist. Im Dokument konnte ich dann auch 
die wesentlichen Passagen nur FETT herausstellen.

Danke Bernhard,

Mit "sprint" habe ich das Ganze noch nicht probiert. Ist ein guter Tipp. 
Nur muß ich das ganze Programm umschreiben, weil ich die Formatierung ja 
an vielen Stellen im Gesamtprogramm benutze und ich dann überall mit 
spront arbeiten muß. Dann ist mir auch noch unklar, ob ich mit sprint 
über den USART schreiben kann, was ich mit der Routine "Raw_INT()" 
mache.
Ich werde das schon interessehalber versuchen.

mfG frewer

von Peter D. (peda)


Lesenswert?

Werner Freytag schrieb:
> Deshalb das
> Word.doc, das nicht so umfangreich ist.

Lach, Quelltext ist immer wesentlich kleiner.
Für 35kB mußt Du schon ne Menge Programm schreiben.

Jeder Programmierer hat seine Liebling-IDE mit Syntax-Highlighting und 
nur damit guckt er Programme an.

Eine IDE ist aber extrem allergisch gehen DOC, die versteht nur C oder 
ASM.

Also kein C -> kein Angucken.


Peter

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
schau mal hier:
1
static unsigned char tmp_temp[4];
2
....
3
signed int vh= tmp_temp[i];

vh ist +-15Bit breit und tmp_temp ist 8Bit breit, passt also naht los in 
vh rein!

versuch mal folgendes:
1
signed int vh= (signed char)tmp_temp[i];
jetzt ist der Inghalt von tmp_temp nur noch 7Bit breit und kann auch 
negative Werte darstellen.

Mach dir bei sowas DebugMsg rein, dann hättest du gesehen das tmp_temp 
Werte aufweisst die größer 7Bit sind!!!

Stephan

von Werner F. (frewer)


Lesenswert?

Hallo Stephan,

die Erklärung verstehe ich und hab auch gleich mal das Programm 
geändert. Werde sehen, ob das das Problem ist. Komisch war für mich, 
dass an anderer Stelle der Aufruf von LCD_Int(...) mit neg Zahlen 
funktioniert und zwar ohne den "casr" Operator allerdings auch nicht aus 
dem EEPROM.
Melde mich mit dem Ergebnis.

mfG
frewer

von Stephan W. (sir_wedeck)


Lesenswert?

Hi
bei RAW_INT() ist der Temperaturwert ein signed Wert, die Funktion 
sollte richtig sein!

Aber:
Bei VerbrauchsMenu() ließt du den Wert aus dem EEPROM mit einer unsigned 
Var, also wird der Wert als pos. interpretiert!
Bei der Zuweisung zum signed int passt der positive Wert komplett rein, 
also bleibt er positiv!

Schau dir nochmal die Zahlenbereiche an und dieses:
http://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement

Du hast im EEPROM die Werte:

0xFD 0xF9 ....

0xFD -> 253 dez. (unsigned Wert)
0xFD -> -3 dez. (signed Wert)

Stephan

von Werner F. (frewer)


Lesenswert?

Hallo Stephan,

Deine Kommentierung habe ich verstanden, dennoch bringt die Anwendung 
von signed int vh = (signed char)tmp_temp[i] nicht die Lösung.
Was passiert:
Im VerbrauchsMenu läuft jetzt die Erkennung, dass vh<=100 ist, denn in 
der Anzeige wird aus der Routine Raw_Int() das +?? angezeigt. Das wird 
daher rühren, daß ich in die Routine Raw_Int() wieder mit tmp_temp[] 
ohne cast wechsle. Deshalb habe ich nun im VerbrauchsMenu tmp_temp[] mit 
signed char definiert und bin gespannt, ob dann die Fehler behoben sind. 
Wenn nicht, dann muß ich doch dort jeweils einen 'cast' (signed 
char)tmp_temp[] einführen.

Bin langsam selbst gespannt. Vielen Dank für Deine Erklärung, man muss 
da ja teuflisch aufpassen. Interessant ist, dass ich das Programm aus 
Codevision in WinAVR übersetzt habe und in der entsprechenden 
Codevision-Routine werden weder 'cast' verwendet noch das Array als 
signed char definiert. Aber mir ist nicht bekannt, ob im sog Original 
die Darstellung richtig funktioniert.

Gruß
frewer

von Werner F. (frewer)


Lesenswert?

Hallo Stephan,

also noch einmal vielen herzlichen Dank für Deine Hilfe. Es klappt jetzt 
perfekt. Das ganze Problem war also die richtige Definition des Array im 
VerbrauchsMenu() mit signed int tmp_temp[]. Und was habe ich da 
erfolglos rumprobiert. Präzises Nachdenken hilft halt scheinbar!

Gruß
frewer

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.