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
Die drei Bytes passend schieben und zusammenverodern und anschließend nach itoa() googlen...
ich habe vergessen zu erwähnen, der Pic16f88 wird mit Assembler programmiert. VG
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
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.
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?
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.
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.
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?
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.
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.
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
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.
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.
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)
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...
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 | /**********************************************************/
|
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.