Forum: Mikrocontroller und Digitale Elektronik 3 x 8 Bit addieren


von Martin (Gast)


Lesenswert?

Hallo

nach langem Kopfzerbrechen und keiner vernünftigen Lösung versuche ich 
hier mein glück.
Ich denke die Frage ist kein Problem.

Ich habe 3 8Bit Register, in einem steht die 1er Zahl im nächsten die 
10er Zahl und im 3. die 100er Zahl
Maximal kann aber nur 999 erreicht werden(anzeigebedingt)

Nun möchte ich diese 3 Registerwerte in einem 16Bit Register 
abspeichern.

Wie kann ich das lösen?
Mein erster Gedanke waren die Pointer, aber ich weiß nicht wie!

Wer kann helfen.

Martin

von Sebastian Wille (Gast)


Lesenswert?

Hi Martin,

hier ein Vorschlag (vielleicht nicht der eleganteste, könnte aber 
funmtionieren):

1. Die Einer und die Zehner addieren (add).
2. Schauen, ob die Hunderter größer als 2 sind
   --> nein --> Hunderter dazuaddieren (add) --> fertig!!!
   --> ja --> siehe 3.!
3. 200 zum 1. Ziel-Register addieren (adiw)
4. 200 von den Hundertern abziehen (subi)
5. Die "übrigen" Hunderter ins 2. Ziel-Register. --> fertig!!!

Versuch's mal so und berichte, ob's geklappt hat!

Grüße,

Sebastian

von edi (Gast)


Lesenswert?

hi,

hund*64h
zehn*0ah
eins
___
summe(16bit)

ed

von Martin (Gast)


Lesenswert?

Danke Sebi,

Aber kannst du mir sagen was du mit den 200 immer erreichen willst und 
welches Register ist nachher da low und welches das high Byte?

Also Edi leider läßt mein 8515 keine multiplikation zu.
hast du einen Andere möglichkeit?

Martin

von Jangomat (Gast)


Lesenswert?

Jedes Byte kann max. 9 sein.
Du benötigst demnach 4 Bit pro "Byte".
Dann machs doch einfach so:

xxxxhhhh zzzzeeee

x = frei
h = hunderter
z = zehner
e = einer

das kannst Du einfach mit Schiebeoperationen und Maskierung 
bewerkstelligen.

von Sebastian Wille (Gast)


Lesenswert?

Hi Martin,

bevor ich's erklär, hier ein paar Definitonen:

.def Einer     = r16
.def Zehner    = r17
.def Hunderter = r18

.def Ziel_low = r28
.def Ziel_high = r29

.def temp1 = r21
.def save1 = r22
.def save2 = r30
.def save3 = r31

Nun addiertst Du zuerst Einer und Zehner (Ergebnis minimal 0 und maximal 
99).

Was mir hier gerade auffällt: Vergiß das mit den 200. Denkfehler von 
meiner Seite. Auch der Rest hatte Denkfehler.

Hier ein neuer Vorschlag:

; Zehner-Zahl erzeugen (Zehner*10)
mov  temp1,Zehner

add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1
add  Zehner,temp1

mov  save3,temp1 ; hier stehen die Zehner (z.B. 6*10 = 60)
addi  save3,Einer ; nun sind die Einer und Zehner addiert

; Hunderter in save1 und save2 ablegen
; zuerst x10
mov  temp1,Hunderter

add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1

;nochmal x10
mov  save1,Hunderter
mov  temp1,Hunderter

add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1
add  Hunderter,temp1

; die Hunderter stehe nun in save1 (low)/save2 (high)
; der Rest immer noch in save3, also:
add  save1,save3

mov  Ziel_low,save1
mov  Ziel_high,save2

Ich hab's nicht getestet, probier's mal!

Sebastian

von Bernhard T (Gast)


Lesenswert?

Ja wie Jangomat würd ichs auch machen (heist glaub ich packed BCD). Die 
AVR's kennen den Swap Befehl (vertauscht die oberen 4 bit(= 1 Nibble) 
mit den unteren 4 bit eine 8 bit Registers (etwas schneller als 
schieben) und dan maskieren.
Gruß Bernhard

von Martin (Gast)


Lesenswert?

Nun das ist nicht in meinem sinne da anschließend ein Pointer mit dem 
16bit wert geladen werden soll und da ist deine Möglichkeit Jangomat 
nicht ideal.

wenn beispielsweise

  1er = 00000000 = 0
 10er = 00000101 = 5
100er = 00000010 = 2

dann sollte mein 16 bit wert so aussehen:

00000000 11111010
HighByte LowByte

und das ist mein Problem


Martin

von Martin (Gast)


Lesenswert?

Also

zu Sebi ist zu sagen, dass bei dir nirgends erwähnt wird wie du 
Hunderter und save1 und save 2 verarbeitest und des weiteren versuch mal 
wenn Hundert = 9
dann 9x10 und anschließend nochmal die 90x10 in einem 8Bit Register zu 
realisieren.

Zu den Bernhard und Jangomat ist zu sagen, vielleicht funktioniert es 
wie ihr es vorhabt, nur leider kann ich mit maskieren noch nicht viel 
anfangen.

Könntet Ihr eure Methode vielleicht etwas genauer beschreiben und 
erklären?

Martin

von Jangomat (Gast)


Lesenswert?

Hallo,

dann mußt Du wohl wirklich von Hand multiplizieren:

Ergebnis=Einer + Zehner*0Ah + Hunderter*64h

die Multiplikation mit Additionen und Schleifenzähler nachbilden. 
Braucht wenig Platz!

von Sebastian Wille (Gast)


Lesenswert?

Hi Martin,

schon klar, ich habe gehofft, es gibt einen automatischen Überlauf ins 
nächste Register, dann würd's schon klappen! Kann sein, daß es auch nur 
mit den 4 obersten Registern geht, müsst ich mich auch nochmal einlesen.

Sebastian

von Martin (Gast)


Lesenswert?

Noch eine Frage dazu.

Würde es funktioniern wenn ich sage

X-Pointer(16bit) + Einer + Zehner + Hunderter

??

Das wäre dann nämlich die einfachste Methode.

Martin

von Jangomat (Gast)


Lesenswert?

auf keinen Fall,

stell Dir vor:

1. Fall:
Einer=0
Zehner=0
Hunderter=4

2. Fall:
Einer=2
Zehner=2
Hunderter=0

von Peter D. (peda)


Lesenswert?

Man kann es auch mit der Zählmethode machen, d.h die einzelnen Digits 
runterzählen und dementsprechen oft 10 bzw. 100 zum Ergebnis addieren:


.def hund = r16
.def zehn = r17
.def ein = r18

.def lowbyte = r19
.def highbyte = r20

mov lowbyte, ein
ldi highbyte, 0
m1:
dec zehn
brmi m2
subi lowbyte, -10 ;+10
rjmp m1
m2:
dec hund
brmi m3
subi lowbyte, low(-100) ;+100
sbci highbyte, high(-100) ;Übertrag beachten !
rjmp m2
m3:
ret


Peter

von Bernhard T (Gast)


Lesenswert?

Ich hatte dich falsch verstanden. Du willst also doch multiplizieren. 
Was du machen willst ist bei deinem Beispiel  X = 2 * 100 + 5 * 10 + 0. 
Ich selber verwende kein asm für Mathe. Befrag mal die Suche nach 
Multiplikation da gibt es reichlich Beispiele.
Gruß Bernhard

von Martin (Gast)


Lesenswert?

Nun gut das leuchtet mir ein.

Leider kann ich beim 8515 nicht den Befehl MUL (multiplizieren) 
anwenden.

Erlich gesagt bin ich gerade genau so weit wie am Anfang.
Aber es muß doch eine Methode geben. Wenn ich beispielsweise Einer und 
Zehner addiere, dann hab ich nur noch 2 x 8Bit

und jetzt müßte ich diese beiden Register (Hunderter und (Einer+Zehner) 
irgendwie miteinander verknüpfen um einen 16Bit wert zu erhalten.

Das kann doch eigentlich gar nicht so schwer sein!!!!

Grübel.....

Bitte alle mithelfen

Gruß Martin

von edi (Gast)


Lesenswert?

hi,

sorry fuer meine ignoranz...(es gibt keine multiplikation)

ich spiele mit dem 8051er.....aber einem ''ding'',das pro sekunde 
millionen zyklen macht, dem kann man doch ein 16bit register bis zu 999 
mal hochzaehlen lassen.
...oder gibt es beim AVR kein 'INC' ?

ed

long live '51

von Jangomat (Gast)


Lesenswert?

schau Dir doch mal den Beitrag von Peter Dannegger kann.
So fein vorgekaut brauchst Du nicht mehr viel tun!
Geht alles ohne den heiligen "mul" Befehl!

von Bernhard T (Gast)


Lesenswert?

Man kann auch multiplizieren ohne MUL Befehl. da gibt es auch ein Atmel 
pdf zu. Ansonsten versuch es doch mal mit der suchfunktion.
z.B. : 
http://www.mikrocontroller.net/forum/forum.php?query=Multiplikation+asmembler&forums%5B%5D=1&forums%5B%5D=2&forums%5B%5D=3&forums%5B%5D=4&action=sendsearch

Gruß

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.