Forum: Mikrocontroller und Digitale Elektronik 24 Bit Umwandeln


von Sabine M. (zizo)


Lesenswert?

Hallo zusammen,
durch Serial-Kommunikation bekommt mein Pic16F88 ein Wert in Form von 3 
Byte, die drei Byte soll ich auf dem Display anzeigen lassen.

Wie kann ich die 3 Byte in decimal umwandeln?

vielen Dank

Sabine

von troll (Gast)


Lesenswert?

Die drei Bytes passend schieben und zusammenverodern und anschließend 
nach itoa() googlen...

von Sabine M. (zizo)


Lesenswert?

ich habe vergessen zu erwähnen, der Pic16f88 wird mit Assembler 
programmiert.

VG

von alfons (Gast)


Lesenswert?

integervariable = byte

von Kein Name (Gast)


Lesenswert?

Die FXD2424U Division findest du in der Application Note 617.
Und hier ein Beispiel, das 24 Bit in Ziffern wandelt.

;Display aufbereiten
    movfw   numA2
    movwf   AARGB2
    movfw   numA1
    movwf   AARGB1
    movfw   numA0
    movwf   AARGB0
    movlw   digitBuf + 5
    movwf   FSR
    call    u24ascii


; 24Bit Zahl in Ascii String
u24ascii
    movlw   6
    movwf   digitCount

ascii24Loop
    movlw   D'10'
    movwf   BARGB2
    clrf    BARGB1
    clrf    BARGB0

    movlw   HIGH FXD2424U
    movwf   PCLATH
    call    FXD2424U
    clrf    PCLATH

    movfw   REMB2
    movwf   INDF
    movlw   '0'
    addwf   INDF,f

    decf    FSR,f
    decfsz  digitCount,f
    goto    ascii24Loop
    return

von Michael A. (Gast)


Lesenswert?

Sabine Mühller schrieb:
> Wie kann ich die 3 Byte in decimal umwandeln?

So einfach ist das nicht. Erstmal muss der Empfänger erkennen können, 
welches das erste der 3 Bytes ist.

von Wilhelm F. (Gast)


Lesenswert?

Sabine Mühller schrieb:

> Wie kann ich die 3 Byte in decimal umwandeln?

In welcher Form liegen die 3 Bytes denn vor? Hexadezimal gepackt oder 
ungepackt, oder ASCII?

von Eumel (Gast)


Lesenswert?

Michael A. schrieb:
> So einfach ist das nicht. Erstmal muss der Empfänger erkennen können,
> welches das erste der 3 Bytes ist.


Aber wenn du das schon hast, dann mit einer wiederholten Subtraktion.

von Michael A. (Gast)


Lesenswert?

Wilhelm Ferkes schrieb:
> In welcher Form liegen die 3 Bytes denn vor?

Drei Byte sind drei Byte. Die Frage ist eher, wie sie interpretiert 
werden müssen.

von Wilhelm F. (Gast)


Lesenswert?

Michael A. schrieb:

> Drei Byte sind drei Byte. Die Frage ist eher, wie sie interpretiert
> werden müssen.

Das ist wohl wahr. Deswegen fragte ich ja noch mal nach. Vielleicht 
liegen sie ja schon dezimal als ASCII vor, wer weiß das schon?

von Sabine M. (zizo)


Lesenswert?

Hallo,
die Byte sind in Binär Form z.b.
wird wie folgend die drei Byte zu Pic geschickt:

1er Byte  00001011
2er Byte  01010101
3er Byte  01010111

das entspricht 000010110101010101010111
am Display soll 742743 gezeigt werden

VG
s.

von Wilhelm F. (Gast)


Lesenswert?

Sabine Mühller schrieb:

> das entspricht 000010110101010101010111
> am Display soll 742743 gezeigt werden

Also mit entsprechender Routine umwandeln. Ich habe hier auf dem 8051 
skalierbare BIN-BCD-Routinen, für beliebig erweiterbare Zahlengrößen, 
das fluppt gut. printf brauche ich so gut wie gar nicht.

Oben nannte schon einer was Routinen von der Microchip-Homepage.

von Peter D. (peda)


Lesenswert?

Auf MCs ohne Division ist die Subtraktionsmethode am günstigsten.
Hier ein Beispiel in AVR Assembler für 32 Bit:

http://www.mikrocontroller.net/attachment/highlight/292

Sollte sich leicht auf den PIC anpassen lassen.


Peter

von Wilhelm F. (Gast)


Lesenswert?

Peter Dannegger schrieb:

> Sollte sich leicht auf den PIC anpassen lassen.

Selbst in C läßt sich eine Hexadezimalzahl besonders leicht in Dezimal 
umwandeln, wenn es nicht besonders zeitkritisch ist. Man teilt die Zahl 
in einer Funktion fortlaufend durch 10, bis nur noch der Rest übrig 
bleibt.

von Dussel (Gast)


Lesenswert?

Wilhelm Ferkes schrieb:
> Man teilt die Zahl in einer Funktion fortlaufend durch 10, bis nur noch der Rest
> übrig bleibt.
Durch 10? Eher doch durch die höchste vorkommende Zehnerpotenz. Sonst 
sitzt man lange an 24Bit.

von stepp64 (Gast)


Lesenswert?

Sabine Mühller schrieb:
> das entspricht 000010110101010101010111
> am Display soll 742743 gezeigt werden

Da ist dann aber auch die Umrechnung nicht bekannt. Weil da steht eher
0B5557 (in Hex)

von Wilhelm F. (Gast)


Lesenswert?

Dussel schrieb:

> Durch 10? Eher doch durch die höchste vorkommende Zehnerpotenz. Sonst
> sitzt man lange an 24Bit.

Ich suche mal. Irgendwo machte ich es mal so in einer C-Funktion...

von Wilhelm F. (Gast)


Lesenswert?

Hier:
1
/***********************************************************
2
DOES:    Print Dezimal (aus Kernighan/Ritchie: Programmieren in C)
3
         Rekursives Beispiel
4
         Könnte zur dezimalen Wandlung von Binärzahlen verwendet werden.
5
GLOBALS: none
6
RETURNS: none
7
***********************************************************/
8
void printd (unsigned long n)
9
{
10
/*
11
  if (n < 0)
12
  {
13
    putchar ('-');
14
    n = -n;
15
  }
16
*/
17
  if (n / 10)
18
  {
19
    printd (n / 10);
20
  }
21
  putchar (n % 10 + '0');
22
}
23
/**********************************************************/

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Naja, ein K&R Beispiel eben. Nicht nur ne Division, sondern dazu auch 
ein mod, was auf ne zweite Division hinausläuft. Wenn schon C, dann kann 
man das auch so:

  if (!L)  Buffer[i--] = '0';
  while (i)
  { if (!L) goto _lready;
    T = ldiv(L,10);
    L = T.quot;
    Buffer[i--] = '0'+T.rem;
  }

Die ldiv() sollte es eigentlich fast überall geben.
Aber hier geht's ja um Assembler auf PIC. Ich hänge mal ne komplette 
GK-Arithmetik hier an, die ich mal Mitte der 90er Jahre geschrieben hab, 
damals noch für die PIC's mit EPROM und Quarzfenster zum Löschen. Sollte 
aber für nen 16F88 auch noch gehen.

W.S.

von Dussel (Gast)


Lesenswert?

Wilhelm Ferkes schrieb:
> Hier:
Stimmt, ist auch logisch. Ich habe an das Dividieren durch Subtrahieren 
gedacht und dann bei deiner Aussage auch ans Subtrahieren gedacht. Das 
Problem bleibt aber, dass die Division lange dauert.

von Wilhelm F. (Gast)


Lesenswert?

Dussel schrieb:

> Das
> Problem bleibt aber, dass die Division lange dauert.

Bei 65 Bit, ein Bit mehr als long long, gibt es auch wieder Probleme. 
Deshalb erfreue ich mich an meinen eigenen skalierbaren Assemblerfiles 
beliebiger Skalierungsgrößen. Sie sind schnellstens, und getestet. Nix 
mit den Compilerlibraries vom Hersteller.

von Anja (Gast)


Lesenswert?

Kein Name schrieb:
> Die FXD2424U Division findest du in der Application Note 617.

In Assembler mache ich das fast immer mit einer Normierung der Zahl und 
anschließend fortlaufender Multiplikation mit 10.

also mal am Beispiel eines 16-Bit-Wertes. 0..65535

Wert = 0xFFFF

16*24 Bit Multiplikation mit Normierungsfaktor 6.5536 -> 6.5536 * 
0x100000 = 0x68DB8C (mindestens 1 Byte höhere Auflösung für den 
Normierungsfaktor)

0xFFFF * 0x68DB8C = 0x68DB232474
Wer möchte kann jetzt noch runden und die "Nachkommastellen" nach den 24 
Bit wegschneiden (das Ergebnis ist sowieso nur 16 Bit genau):
0x68DB23.2474 + 0x000000.8000 = 0x68DB23.A474
-> 0x68DB23
0x6 ist direkt die erste auszugebende Ziffer (0x30 addieren für ASCII)
-> Rest = 0x08DB23 * 0x0A = 0x588F5E -> 2. Ziffer 0x5
-> Rest = 0x088F5E * 0x0A = 0x5599AC -> 3. Ziffer 0x5
-> Rest = 0x0599AC * 0x0A = 0x3800B8 -> 4. Ziffer 0x3
-> Rest = 0x0800B8 * 0x0A = 0x500730 -> 5. Ziffer 0x5

Die Multiplikation mit 0x0A geht als
(Zahl 2 * links-Shift + ursprüngliche Zahl) (also * 5)
und das ganze noch mal links geshiftet.

Gruß Anja

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.