Problem Codevision BCD -> Dez -> Display

Gast #73725
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
Gast #73726
> 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.]
Gast #73727
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
Gast #73728
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.
Gast #73729
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?
Gast #73730
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
Gast #73731
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.
Gast #73732
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
Gast #73733
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
Gast #73734
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
Gast #73735
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.
Gast #73736
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.