Forum: Mikrocontroller und Digitale Elektronik Problem Codevision BCD -> Dez -> Display


von Tobias A. (Gast)


Lesenswert?

Hi

ich habe ein Problem

mir liegt ein Byte Informationen vor.
Davon sind je 4 Bit eine BCD Zahl.
Die eine durch die oberen und die andere
durch die unteren 4 Bits dargestellt.

Jetzt muss ich die beiden trennen und
danach aufs LCD schreiben.
So weit so schön.
Habe mir da einen code ausgedacht, aber
irgendwie macht das Ding Sondermüll.
Erstmal nur für das untere Byte
Wo ist da der Denkfehler?

daten=PINA;   // einlesen der 8 Bitzahl über PORT A bei DDRA=0x00;

daten=daten*16;    // *16 bedeutet das man die unteren 4 Bit nach oben
                   // schiebt
daten=daten/16;    // das ganze retour, obere 4Bit sind platt gemacht.
daten=daten+0x30;  //von BCD nach ASCII
lcd_gotoxy(0,0);
lcd_putchar(daten);



Ich hatte mir auch schon mal überlegt das irgendwie mit einem
Logischen UND zu lösen aber irgendwie fehlt mir da die Idee wie
ich das am schlausten codiere.

in umgangssparche:

0xAA UND 0x0F = 0x0A

irgendwie bin ich hier mit Blindheit (oder Blötheit) geschlagen.

Kann mir da wer helfen?

Gruß
  Tobi

von Jörg Wunsch (Gast)


Lesenswert?

> daten=daten*16;
> daten=daten/16;

Ziemlich aufwendig. ;-) Falls `daten' ein vorzeichenbehafteter Typ
ist
(also `int' oder `char', nicht `unsigned int' oder `unsigned
char'),
handelst Du Dir außerdem Probleme mit Werten ein, bei denen das Bit 3
gesetzt ist: nach der Schieberei würde es zum Bit 7 und damit eine
negative Zahl darstellen.  Beim Zurückschieben nach rechts würden alle
oberen Bits mit 1 gefüllt (negatives Vorzeichen bleibt erhalten).

Schönheitsfehler: das obere Nibble (also die oberen 4 Bits) machst Du
sinnloserweise tot, statt sie gleich noch mit aufzuheben.

> in umgangssparche:

> 0xAA UND 0x0F = 0x0A

Genau das solltest Du tun.  Das deutsche `UND' heißt auf C `&'. ;-)

Also:

daten = PINA;
lcd_gotoxy(0,0);
lcd_putchar((daten & 0x0f) + '0');
lcd_putchar(((daten & 0xf0) >> 4) + '0');

[a >> 4 ist dasselbe wie a / 16; jeder ordentliche Compiler sollte die
Division hier ohnehin in eine Verschiebung überführen können.]

von Tobias A. (Gast)


Lesenswert?

Hi

das ging schnell.
Wer ich gleich mal probieren.
Das die Variante die ich da hatte umständlich
war, war mir klar aber irgendwie wollte sonst nix
klappen und so hab ich es so probiert.


Ich test mal...

Tobi

von Tobias A. (Gast)


Lesenswert?

Hi

klappt nicht!

es macht was er will. Mal zeigt er die Zahl an
dann wieder nicht.
Einige scheinen zu funktionieren, andere nicht.
Aber es kommen definitiv nicht die Zahlen raus,
die sollen.

von Tobias A. (Gast)


Lesenswert?

also wenn ich 85 reinstecke kommen
:1 raus
irgendwie scheint das verdreht....
wie tausch ich denn die reihenfolge der daten?
das müsste doch mit
daten=255-daten ;
gehen oder?

von Tobias A. (Gast)


Lesenswert?

Hi

also nochmal hier der ganze Kram im Zusammenhand

daten ist ein Feld von unsigned char.


    PORTD.5=0;     //
    PORTD.6=0;     //  Wählt via Adressdecoder ein Latch aus
    PORTD.7=0;     //  an dem die Inforamtionen anliegen
    DDRA=0x00;     //  macht dem Port A klar das Daten reinsollen
    PORTD.4=0;     //
    PORTD.4=1;     //   PORTD.4 Toggeln um daten ins Latch zu
    PORTD.4=0;    //    clocken
    daten[1]=PINA;   // daten reinziehen

    DDRA=0xFF;      // PORTA wieder auf Ausgang schalten
    lcd();         //  wählt via Adressdecoder das LCD aus
                   //  Enable Signal sind mit UND realisiert
    lcd_gotoxy(0,0);  // geht zu LCD Position 0,0
    lcd_putchar((daten[1] & 0x0f) + '0');  // siehe obiges Postin
    lcd_putchar(((daten[1] & 0xf0) >> 4) + '0');  // dito

jetzt sind noch die daten verdreht
also mein 8 Bit ist eigentlich das erste bit.
Korrekturversuche mit konstruten wie
daten[1]=255-daten[1];
schlugen leider fehl

un nu?

Danke Euch
  Tobi

von Jörg Wunsch (Gast)


Lesenswert?

Gab's auch schon längliche Threads darüber.  Das einfachste ist es
wirklich, die Bits zu schieben:

unsigned char a, b, mask;

a = input value;
...
for (b = 0, mask = 0x80; mask != 0; mask >>= 1) {
 b <<= 1;
 if (a & mask) b |= 1;
}

b ist der Ausgabewert.

Die Schleife kann man auch ,,entrollen'', wenn's auf
Geschwindigkeit
ankommt.

Für Werte mit mehr als 8 Bit gibt's trickreiche C-Varianten davon,
aber für 8 Bit lohnt das nicht.

von Tobias A. (Gast)


Lesenswert?

Hi

danke für die Hilfe.
Aber bist Du sicher das der Code stimmt?
ich hab das hier grad mal probiert und
wenn ich nacheinander a und b mal auf LEDs ausgebe
sehen die beiden völlig identisch aus.

Gruß
 Tobi

von Khani (Gast)


Lesenswert?

Suggestions :

- Was macht den eigentlich lcd_putchar ? Das gibt doch einfach einen
Character aus oder ? Wenn das so ist, dann wird zunächst der Character
im Argument (beispielsweise ein 'A') in einen Hex-Code umgewandelt
(hier dann 0x3A o.Ä.). Dann wird dieser HexCode an das Display
geschickt. Und da liegt das PROBLEM : Auf dem Rechner (PC) kann man
wunderbar Hex-Zahlen erzeugen, in dem man ein Nibble (Halbbyte)
nacheinander zu 0x30 addiert und das Ergebnis ausgibt (maybe via
putchar()). Das geht auf vielen Displays nicht !
Warum ? Ganz einfach - hier liegt keine ASCII-Tabelle sondern
irgendeine Zeichentabelle vor. Das ist schade, aber nicht zu ändern.
Also ins Datenblatt des Displays schauen und herausfinden, ob nach der
9 das A oder sont was kommt (meistens kommt da : ; oder so)

- Willst Du eigentlich Deine Zahl in Hex oder Dez ausgeben ? Wenn Du
einen Wert als Dezimalzahl ausgeben willst, dann muss man sich schon
ein bißchen anstrengen, es sei denn Sie ist vorher schon BCD codiert
(ist doch so bei Dir oder ?)

MfG, Khani

von Tobias A. (Gast)


Lesenswert?

Hi

also jetzt gehts.
Ich hab das mal so ähnlich wie oben in der beschriebenen
Schleife gelöst (wobei ich mir wirklich fast sicher bin das
die ihren Dienst nicht tut).
Die Umformatierung klappt pima so wie beschrieben.
Erst die 4 Bits nach unten schieben und dann 0x30 Addieren
das Display hat einen HD44780 Controller und bei dem
liegen die Zahlen ab 30 aufwärts.

Danke an alle die mir geholfen haben.
Ich glaube wenn das net geklappt hätte, hätte ich
noch bis heute nacht hier gesessen.

Gruß
  Tobi

von Jörg Wunsch (Gast)


Lesenswert?

Sorry, ich hatte natürlich einen Disclaimer vergessen: nein, ich kann
es mir nicht leisten, irgendwelchen example source code auch noch
vorher zu testen.  Sowas ist als Gedankenanregung gedacht und einfach
aus dem Effeff aufgeschrieben, in der Hoffnung natürlich immer, daß
der geneigte Leser sich die Mühe macht, die Anregung zu verstehen und
für sich die Funktionalität zu verifizieren. ;-)

Ja, Du hast natürlich Recht, daß das nicht funktioniert.  (Wenn ich
jetzt nochmal draufgucke, sehe ich meinen Denkfehler auch.)  Sollte
aber nicht allzu schwer zum Funktionieren zu bringen sein.

von Tobias A. (Gast)


Lesenswert?

Hi Jörg

kein Problem. War nurso runter mit den Nerven, das
ich das einfach mal probiert habe ohne vorher groß
darüber nachzudenken.
Trotzdem danke, die Zeilen haben als Anregung einiges
gebracht. Bin mittlerweile schon ein ganzes Stück weiter.
Leider muss ich bald die Prozessorebene verlassen und dann
ein Windwos Programm incl. RS232 schreiben (MFC würG)
um mit dem ganzen Spaß zu kommunizieren.
Na ja, wie dem auch sei. Danke Dir nochmal.

Gruß
  Tobi

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.