Forum: Mikrocontroller und Digitale Elektronik falsches Ergebnis auf Lcd-Display nach Division mit einer Variable.


von microkad (Gast)


Lesenswert?

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.

von Tom (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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.

von Tom (Gast)


Lesenswert?

Hallo!

Peter II schrieb:

 '0' + 3 = '3'

Warum setzt ihr das unter diese ' wenns auch ohne geht?

fG Tom

von troll (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

Tom schrieb:
> Warum setzt ihr das unter diese ' wenns auch ohne geht?

was es ohne ' kein zeichen sonder eine zahl ist.

von Tom (Gast)


Lesenswert?

und er will doch mit zahlen rechnen oder hab ich seine frage falsch 
verstanden???

von Peter II (Gast)


Lesenswert?

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* )

von Stefan Hennig (Gast)


Lesenswert?

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.

von Chris (Gast)


Lesenswert?

Erst mit Zahlen rechnen und mit itoa() ausgeben? :-)

von qinyan723 (Gast)


Lesenswert?

Ü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

von Tom (Gast)


Lesenswert?

Also laut Variablendef sind a und b char Datentypen. meiner meinung nach 
der falsche datentyp um damit direkt zu rechnen.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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?

von bazzzel (Gast)


Lesenswert?

vielleicht nimmt er (der Compiler) 4 als Integer an und casted dann
auf Integer.

   a = (char) 4/b + '0';

von Peter II (Gast)


Lesenswert?

bazzzel schrieb:
> vielleicht nimmt er (der Compiler) 4 als Integer an und casted dann
> auf Integer.

aber auch dann sollte da 0 rauskommen.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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'.

von Werner A. (homebrew)


Lesenswert?

Wenn es normalerweise ein mehrstelliges Ergebnis gibt ist auch klar, 
warum das nicht geht

von Cyblord -. (cyblord)


Lesenswert?

Also mal zusammenfassend:
1
b = 2;
2
a = 4/b + '0';

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

von Klaus (Gast)


Lesenswert?

Ob die Verwendung des MPLAB Debuggers etwas Licht in die Dunkelheit 
bringen Könnte?

MfG Klaus

von Cyblord -. (cyblord)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von microkad (Gast)


Lesenswert?

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!!

von Werner A. (homebrew)


Lesenswert?

Es gibt auch die div function in C ...

von Cyblord -. (cyblord)


Lesenswert?

Und mal anders klammern?
>
1
 b = 2;
2
> a = (4/b) + '0';
3
>

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?

von Klaus (Gast)


Lesenswert?

microkad schrieb:
> a = 4/2 + '0';

Daraus wird der Compiler

a = 0x32

machen, da alles zur Compilezeit bekannt ist.

MfG Klaus

von J.-u. G. (juwe)


Lesenswert?

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.

von Holger W. (holgerw)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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

von microkad (Gast)


Lesenswert?

Hallo Cyblorg und H.-u. G.,

nach
1
 b = 2; 
2
a = 4/b + '0';
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]".

von Max D. (max_d)


Lesenswert?

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

von microkad (Gast)


Angehängte Dateien:

Lesenswert?

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

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.