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?
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 ← PC + 1 Mich wundert dann allerdings, dass es überhaupt läuft bzw. sich kompilieren lässt (grübel). Klär mich mal auf. Achim.
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
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...
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ß
@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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.