Hallo zusammen,
ich habe ein problem und zwar: nach der Division unter Verwendung einer
Variable, wird an meinem LCD-display nur falsches Ergebnis angezeigt!!
so sieht mein C-code aus:
1
#include <p18f25k22.h>
2
char a;
3
char b;
4
5
void main(void) {
6
OSCCON = 0x50; // 4 MHz clock
7
PORTB = 0;
8
LCD_init(); initialize the lcd display
9
10
b = 2;
11
a = 4/b + '0';
12
13
LCD_put_Data_Port_out(a); // display the value of "a" on the lcd !
14
15
while (1);
16
}
den wert von "a" möchte ich auf dem LCD-Display anzeigen lassen. Was ich
aber da erhalte sind nur falsche werte wie "/", "-" oder "^". Wird im
Ausdruck von "a" die variable "b" durch seinen tatsächlichen Wert (2)
ersetzt, also "a = 4/2", erscheint das richtige Ergebnis von "a" auf dem
LCD-Display, nämlich "2".
Außerdem, wenn ich den Ausdruck von "a" im Code ändere, wie z.b. "a =
4+b", "a = 4-b" oder "a = 4*b", so werden richtige Ergebnisse von "a"
angezeigt. Nur mit der Division mit Variablen, werden falsche Ergebnisse
angezeigt.
Was sollte ich machen oder beachten, damit das richtige Ergebnis von "a
= 4/b" angezeigt wird?
Für jede Hilfe bin ich dankbar.
Ich benutze den Mikrocontroller PIC18F25K22 mit MPLAB X version 1.10 und
C18 Compiler.
Viele Grüße.
Hallo!
Soweit ich das sehe wird zum Wert a ein String dazugezählt und keine 0.
Dadurch wird irgendetwas angezeigt da der String ja einen gewissen
Hexadezimalen Zahlenwert darstellt.
Nimm mal die " weg. dann dürfte es funktionieren.
fG Thomas
Tom schrieb:> Soweit ich das sehe wird zum Wert a ein String dazugezählt und keine 0.
er willst ja buchstaben Addieren also '0' + 3 = '3' das sollte gehen.
ich kann auch keinen anderen Fehler finden.
Tom schrieb:> '0' + 3 = '3'>> Warum setzt ihr das unter diese ' wenns auch ohne geht?
Weil es zwei völlig unterschiedliche Sachen sind.
3 --> Zahl 3
'3' --> ASCII-Wert des BUCHSTABEN 3 = 51
Tom schrieb:> und er will doch mit zahlen rechnen oder hab ich seine frage falsch> verstanden???
will er nicht, er will auf dem Display eine ziffer ausgeben und das ist
ein zeichen und keine zahl.
Man müsste ja mal wissen welchen Paramter LCD_put_Data_Port_out braucht.
Zahl (int), zeichen( char) oder eventuell sogar String( char* )
Hmm, Du gibst uns etwas wenig Info zur angeschlossenen HW und zu den
Bibliotheksfunktionen, die Du da nutzt.
Was hat denn LCD_put_Data_Port_out für eine Signatur?
Wird bei jedem Aufruf was anderes (falsches) angezeigt?
Außerdem waren die PIC-Controller sehr schwachbrüstig, als ich mich das
letzte Mal damit befasst habe, vielleicht muß er zur Division eine
Bibliothek verwenden, und Du hast die falsche dazugelinkt?
Ein paar mehr Details wären hier hilfreich.
Ansonsten schließe ich mich meinen Vorrednern an: An Deinem Code ist
erstmal nichts offensichtlich falsch für mich.
Grüße,
Stefan.
Überprüfen Sie zunächst die LCD-Anzeige, um zu versuchen die Ausgabe '0
lenken ', kann das LCD-Display '0' es?
void main(void) {
OSCCON = 0x50; // 4 MHz clock
PORTB = 0;
LCD_init(); initialize the lcd display
//b = 2;
//a = 4/b + '0';
LCD_put_Data_Port_out('0');
while (1);
}
Thanks
qinyan
Tom schrieb:> Also laut Variablendef sind a und b char Datentypen. meiner meinung nach> der falsche datentyp um damit direkt zu rechnen.
Kann zu Sonderfällen führen.
Aber nicht hier bei diesen Zahlenwerten.
Es sei denn natürlich der MPLAB Compiler kocht wieder mal sein eigenes
Süppchen.
Tom schrieb:> Also laut Variablendef sind a und b char Datentypen. meiner meinung nach> der falsche datentyp um damit direkt zu rechnen.
warum denn nicht. Es sind zahlen von 0 bis +127 damit per definition
möglich. (alles andere kann abhäng von Compiler sein (signed oder
unsigned) ) Warum sollte man damit nicht rechnen?
bazzzel schrieb:> vielleicht nimmt er (der Compiler) 4 als Integer an und casted dann> auf Integer.
Das tut er sogar sicher, wenn er sich an die C-Regeln hält. Aber auch
dann muss das richtige rauskommen, denn ein char mit dem Wert 2 ergibt
auch als int den Wert 2.
Um das mal abzukürzen:
Das es nicht klug ist, einen plain vanilla char für Variablen zu nehmen,
mit denen man rechnen will, steht ausser Frage. Da man es dadurch dem
Compiler überlässt, ob da mögliche Vorzeichen im Spiel sind oder nicht,
weiß man bei negativen Zahlen, bzw. Zahlen die über +127 (wegen 2-er
Komplement) hinausgehen, nie mit letzter Sicherheit, welche der
möglichen Operationen zum Zug kommt.
Tatsächlich sollte man sich angewöhnen, 3(!) Character Datentypen zu
unterscheiden:
char für alles was mit Textverarbeitung zu tun hat
signed char für alles, wo man einen kleinen Integer benötigt,
der ein Vorzeichen hat
unsigned char für alles, wo man einen kleinen Integer ohne
Vorzeichen benötigt
Der erste Datentyp( 'char' ) bleibt also für alles was mit Zeichen
und/oder Strings zu tun hat reserviert, die anderen beiden Datentypen (
'signed char', 'unsigned char' ) nimmt man, wenn man rechnen will und
wählt aus, ob man ein Vorzeichen haben möchte oder nicht.
Vor allem der letze Datentyp (unsigned char) wird in der
µC-Programmierung häufig benötigt, weil er das repräsentiert, was man
ein 'Byte' nennt.
Aber: Das alles ist hier nicht das Problem.
Es sind keine negativen Vorzeichen im Spiel und die Zahlenbereiche sind
auch dergestalt (4 und 2) so dass hier nichts passiert, und die
Unterschiede zwischen den 3 Datentypen sich nicht auswirken.
Es sei denn natürlich, der TO hat wieder mal ein Beispiel fürs Forum
speziell hergerichtet und seine Zahlen sind im realen Programm ganz
andere. Wenn dem aber nicht so ist, dann liegt das Problem nicht am
Datentyp 'char'. Solange der Compiler sich an den C-Standard hält, liegt
das Problem NICHT in diesem Bereich. Die Garantien, die man vom
C-Standard bekommt, sind, wenn auch nicht umfangreich, denn doch
ausreichend um diesem Ausdruck ein eindeutiges Ergebnis zuzuordnen. Und
das ist der auf diesem System verwendete Zeichen-Code des Zeichens '2'.
Ergibt für a=50.
Jetzt kommt es auf die Ausgabefunktion an. Wenn die ein Zeichne
erwartet, dann bekommt er ne "2" angezeigt. Wenn die tatsächlich eine
Zahl darstellt (was unwahrscheinlich ist), dann steht da "50". Und wenn
sie einen char* etwartet dann ist sowieso essig.
Aber das will der TE doch alles gar nicht tun. Und diese LCD-Funktion
heißt auch sehr abenteuerlich.
gruß cyblord
Klaus schrieb:> Ob die Verwendung des MPLAB Debuggers etwas Licht in die Dunkelheit> bringen Könnte?>> MfG Klaus
Nein, weil eigentlich ganz klar ist was das Programm tut. Nur der TE
weiß das nicht.
Wenn man nach LCD_put_Data_Port_out()
googelt, findet man folgenden Quellcode für ein DOGM-Display:
http://www.mikrocontroller.net/attachment/146577/eadog-new.c
Demnach erwartet LCD_put_Data_Port_out() tatsächlich einen char, also
ein einzelnes Zeichen.
Erstmals danke für die schnellen Antworten.
Good, die Funktion "LCD_put_Data_Port_out()" erwartet einen char!
wie ich schon oben sagte:
für
1
b = 2;
2
a = 4/b + '0';
werden nur falsche Ergebnisse angezeigt!
aber mit
1
b = 2;
2
a = 4/2 + '0';
wird das richtige Ergebnis, nämlich "2", angezeigt.
Und für alle weitere Operationen wie z.b.
1
b = 2;
2
a = 4-b + '0';
oder
1
b = 2;
2
a = 4+b + '0';
oder
1
b = 2;
2
a = 4*b + '0';
werden die richtigen Ergebnisse auf dem LCD-Display angezeit, nämlich
"2", "6" und "8". Die Variablen "a" und "b" sind weiterhin als "char"
definiert.
Sobald ich eine Variable in meiner Division drin stehen habe, kriege ich
nur mist auf dem Display. ich verstehe das nicht!!
Obwohl die Division hier natürlich eigentlich sowieso als erstes
ausgeführt werden sollte. Trotzdem mal versuchen.
> Sobald ich eine Variable in meiner Division drin stehen habe, kriege ich> nur mist auf dem Display. ich verstehe das nicht!!
Und was genau bekommst du angezeigt?
Klaus schrieb:> Daraus wird der Compiler>> a = 0x32>> machen, da alles zur Compilezeit bekannt ist.
Schon richtig, erklärt aber nicht, warum das Problem nur bei Division
auftritt und nicht bei Addition, Subtraktion und Multiplikation.
cyblord ---- schrieb:> Und was genau bekommst du angezeigt?
Das würde mich auch interessieren. Außerdem, ob jedesmal das gleiche
"falsche" Zeichen angezeigt wird.
Was zeigt denn der Simulator ?
In MPLabX Version 1.30 wird es richtig angezeigt, mit C18 Version 3.43
Vielleicht mal die neueste Version testen ?
Holger
Holger W. schrieb:> In MPLabX Version 1.30 wird es richtig angezeigt, mit C18 Version 3.43
Mit der MPLabX Version wird es nichts zu tun haben, die erzeugt keinen
Code. Und ein C-Compiler, der keine Division kann, wäre bestimmt schon
aufgefallen.
MfG Klaus
wird die Buchstabe "r" angezeigt, am Vormittag und mittag war es noch
das Zeichen "/".
auch mit den klammern:
1
b = 2;
2
a = (4/b) + '0';
hilft nix.
hi Holger, ich habe mir die Werte im Simulator angeschaut, und dort ist
das richtige Wert von "a" angezeigt, nämlich "2". Aber dieser Wert wird
nicht auf dem display angezeigt, sondern ein sinnloses Zeichen wie "/".
ich sollte auch dazu hinfügen, dass das Problem nur mit der Division
auftritt. Auch wenn ich integer Variablen (int c; und int d; ) benutze
wie z.b.
1
2
char out[10];
3
c = 20;
4
d = (2000/c);
5
itoa(d,out);
und dann lasse ich mir out[0], out[1] und out[2] anzeigen, kriege ich
nur falsche Werte ("/", "-" und co.)!! aber für
1
2
char out[10];
3
c = 20;
4
d = (2000/20);
5
itoa(d,out);
habe ich wie vorhin richtige werte auf dem display. ich habe mir sogar
eine selbst ITOA funktion geschrieben, und die C- funnktio "sprintf"
verwendet...nix geholfen. aber im Debugger sehe ich weiterhin richtige
werte von "out[0]..out[2]".
Hast du die Display-Funktionen selber geschrieben?
Hast du in deinem Code noch andere Dinge?
Ich hab mir mal am AVR mit Assembler das Zero-Reg. zerschossen, das gab
dann schöne Fehler irgendwo anders im Programm wo der Compiler mittels
"hinkopieren" des Zero-Regs aufgeräumt hat..... vlt. hast du auch sowas
irgendwo drinne. (Der Simulator nimmt manchmal bestimmte Regs als
"gegeben" an und verdeckt so den Zugriff; Grade bei diesen "rundum
-Paketen " kann sowas vorkommen) .
Hallo Max D.,
Die display Funktionen habe ich selber geschrieben.
es wäre vielleicht besser, wenn ich mein code und die dazugehörige
disassembled-datei der main-funktion einfach hier anhänge!!...das mache
ich auch!
Regards