Forum: Mikrocontroller und Digitale Elektronik Newbie: Probleme mit Konvertierung Binär --> BCD


von Uwe Naumann (Gast)


Lesenswert?

Hallo,

nachdem ich mit so ziemlich allen Assembler-Lösungen, die ich dazu
gefunden habe, nicht so recht klar gekommen bin (teilweise erschließt
sich mir einfach die Funktion des Codes nicht) hab ich mich hingesetzt
und selber eine Routine gestrickt:

; Konvertierung Binaer-->BCD
; Binaerwert wird in temp uebergeben

BIN_to_BCD:
           clr    pulses5                  ; Zehntausender
           clr    pulses4                  ; Tausender
           clr    pulses3                  ; Hunderter
           clr    pulses2                  ; Zehner
           clr    pulses1                  ; Einer

BIN_to_BCD5:
           cpi    temp, 0x2710             ; mit 10000 vergleichen
           brlo   BIN_to_BCD4              ; <10000 --> BIN_to_BCD4
           subi   temp, 0x2710             ; 10000 abziehen
           inc    pulses5                  ; Huderterstelle erhoehen
           rjmp   BIN_to_BCD5              ; nochmal

BIN_to_BCD4:
           cpi    temp, 0x03E8             ; mit 1000 vergleichen
           brlo   BIN_to_BCD3              ; <1000 --> BIN_to_BCD3
           subi   temp, 0x03E8             ; 1000 abziehen
           inc    pulses4                  ; Huderterstelle erhoehen
           rjmp   BIN_to_BCD4              ; nochmal

BIN_to_BCD3:
           cpi    temp, 0x0064             ; mit 100 vergleichen
           brlo   BIN_to_BCD2              ; <100 --> BIN_to_BCD2
           subi   temp, 0x0064             ; 100 abziehen
           inc    pulses3                  ; Huderterstelle erhoehen
           rjmp   BIN_to_BCD3              ; nochmal

BIN_to_BCD2:
           cpi    temp, 0x000A             ; mit 10 vergleichen
           brlo   BIN_to_BCD1              ; <10 --> BIN_to_BCD1
           subi   temp, 0x000A             ; 10 abziehen
           inc    pulses2                  ; Zehnerstelle erhoehen
           rjmp   BIN_to_BCD2              ; nochmal

BIN_to_BCD1:
           mov    pulses1, temp            ; den Rest noch in
Einerstelle schieben

           ret                             ; wieder zurueck

Im Ergebnis soll also in jedem pulses1-5-Register eine Stelle der Zahl
stehen. Solange der Eingabewert maximal 0xF ist klappt das auch
wunderbar. Sobald größere Werte konvertiert werden sollen kommt
teilweise nur noch Mist raus. Bei 0x15 wird z. Bsp. 10005 ausgegeben.

Wo liegt mein Denkfehler? Hat jemand einen Tipp?

von Achim Walther (Gast)


Lesenswert?

Moin Uwe,

habe zwar noch keine praktische Erfahrung mit der AVR-Programmierung,
aber ich denke, es liegt am CPI. Die Anweisung lässt nur 8-Bit
Konstanten zu:

CPI – Compare with Immediate
Description:
This instruction performs a compare between register Rd and a constant.
The register is not changed. All conditional
branches can be used after this instruction.
Operation:
(i) Rd - K
Syntax: Operands: Program Counter:
(i) CPI Rd,K 16 = d = 31, 0= K = 255 PC &#8592; PC + 1

Mich wundert dann allerdings, dass es überhaupt läuft bzw. sich
kompilieren lässt (grübel). Klär mich mal auf.

Achim.

von Frank Linde (Gast)


Lesenswert?

Hallo Uwe,

ich bin geneigt, Dein Posting als Aprilscherz aufzufassen. Du schreibst
überall von Binär, arbeitest im Programm aber mit Dezimalwert. Falls
das kein Scherz ist, erkläre doch bitte noch einmal, was Du überhaupt
machen möchtest. Meinst Du nun eine Umwandlung von Binär (nur Nullen
und Einsen) nach BCD oder von Dezimal (unser "normales" Zahlensystem)
nach BCD? Und wieviele Stellen soll der Eingangswert maximal haben?

Davon abgesehen, hat Achim natürlich recht. So geht es auf keinen
Fall.

Gruß, Frank

von Uwe Naumann (Gast)


Lesenswert?

Also ich will folgendes machen:

Ich habe einen Zählerwert in einem Register (temp), z. Bsp. 34567. Den
möchte ich gern in seine einzelnen Zahlen zerlegen, so das jede Stelle
in einem Register steht.

Und nein, es ist kein Aprilscherz. Mir schwirrt nur langsam der Kopf
vor lauter Zahlen und Konvertierungen.

Das cpi und subi nur 8 Bit können hab ich mittlerweile in der
Befehlsreferenz auch rausgefunden und und ebtsprechend auf cp und sub
mit zusätzlicher Variablen geändert.

Aber so langsam dämmerts mir. Irgendwie hab ich wohl den Denkfehler
gehabt, das die Register r16-r31 16-bittig sind, aber es sind ja nur 8
:-( Hab ich wohl mit den Timer-Registern verwürfelt.

Ich werde mich wohl mal ausgiebig mit 16-Bit-Subtraktion befassen
müssen...

von Chris (Gast)


Lesenswert?

Hallo,

"Ich habe einen Zählerwert in einem Register (temp), z. Bsp. 34567."

Ein Register wie temp ist ein Arbeitsregister und hat als maximalen
Wert 255, also 8 bit.

r16 bis r31 sind genauso wie r0 bis r15 alle 8-Bit-Register, denn der
AVR ist ein 8-Bit MC.

R24,25
r26,27
r28,29
R30,31

sind Doppelregiser und eigen sich auch für 16-Bit Operationen. Dies am
besten in der Befehlslisten nochmal genau nachlesen.
Die obersten drei Registerpaare heißen auch X, Y, Z.

GRuß

von Uwe Naumann (Gast)


Angehängte Dateien:

Lesenswert?

@Chris: Das sind zwar Doppelregister, aber da bekomme ich Vergleiche mit
cp und Subtraktionen mit sub nicht hin. Wenn ich die Doku richtig
verstanden habe geht das wohl auch nicht mit Doppelregistern.

@Alle: Ich habe es nun anders gelöst (siehe Anhang).

Das Lowbyte wird wie gehabt in Digit 1/2/3 umgesetzt.

Das Highbyte wird bitweise nach rechts geschoben und danach Carry
ausgewertet, wenn Carry gesetzt ist wird per Subroutinen die jeweilige
Wertigkeit des Bits (256, 512, ...) zu den vorhandenen BCD-Werten
byteweise dazuaddiert (also z.Bsp. bei 256: erst 6 zu BCD1, dann 5 zu
BCD2, dann 2 zu BCD3) incl. Beachtung der jeweiligen Overflows >=10.

Ist zwar alles ziemlich aufwendig, code- und rechenintensiv, aber a) es
funktioniert und b) ich begreife es. Wenn ich in ein paar Jahren dann
richtig fit in Assembler bin kann ich es ja nochmal überarbeiten ;-)

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.