Forum: Mikrocontroller und Digitale Elektronik RESHI und RESLO dividieren


von wuddy (Gast)


Lesenswert?

Habe diesmal ausmahmsweise ein Problem das nur indirekt mit dem MSP zu 
tun hat. Und zwar geht es darum, das ich mir mit dem Hardware Multiplier 
einen Wert errechnen lasse. Dies geschieht allerdings in Assembler, 
folglich hab ich das Ergebniss in RESHI und RESLO. Anschließend soll 
noch eine Division stattfinden. Wie verknüpfe ich jetzt die beiden 
Register damit ich einen eizigen Wert erhalte den ich dann dividieren 
kann?


1
 erg= RESHI;
2
  erg= erg<<16;
3
  erg= erg| RESLO;

erg ist als long definiert.

von Christian R. (supachris)


Lesenswert?

Die MSP430-Entwickler haben sich schon was dabei gedacht, die 
Ergebnisregister direkt hintereinander im Speicher anzuordnen:
1
UINT32 Result = *(UINT32*)&RESLO;

von wuddy (Gast)


Lesenswert?

Sorry aber daraus werd ich nicht ganz schlau. UINT32, damit spielst du 
bestimmt auf einen 32 bit integer an. Aber weiter kann ich mit dem 
Ausdruck nix anfangen. Wo ist das Problem bei meiner Vorgehensweise?
Auf einem PIC konnt ich genauso realisieren.

von Christian R. (supachris)


Lesenswert?

Dann lerne C. Problem an deiner Vorgehenseweise ist kein prinzipielles. 
Nur je nach Optimierungsfähigkeiten des Kompilers dauert das mehrere 
Takte. Dadurch, dass die beiden Register direkt hintereinander im 
Speicher liegen kann man die auch gleich direkt als 32 Bit Wert 
betrachten. Ob das nun INT32 oder UINT32 ist, hängt ja von den 
Ausgangsdaten und dem verwendeten Modus ab (signed/unsigned).

Der Befehl erstellt einen Pointer auf eine 32-Bit Variable und 
dereferenziert diesen im gleichen Schritt wieder. Also steht in Result 
gleich der 32-Bit Wert. Übrig bleiben 3 Assembler-Befehle:
1
    6d76:  1f 42 3c 01   mov  &0x013c,r15  ;0x013c
2
    6d7a:  b2 4f 8e 12   mov  @r15+,  &0x128e  ;
3
    6d7e:  b2 4f 90 12   mov  @r15+,  &0x1290  ;

Im Gegensatz zu deinem Rotieren:
1
    6d76:  1f 42 3c 01   mov  &0x013c,r15  ;0x013c
2
    6d7a:  0e 4f         mov  r15,  r14  ;
3
    6d7c:  0f 43         clr  r15    ;
4
    6d7e:  82 4e 8e 12   mov  r14,  &0x128e  ;
5
    6d82:  82 4f 90 12   mov  r15,  &0x1290  ;
6
    6d86:  1e 42 8e 12   mov  &0x128e,r14  ;0x128e
7
    6d8a:  1f 42 90 12   mov  &0x1290,r15  ;0x1290
8
    6d8e:  0d 4e         mov  r14,  r13  ;
9
    6d90:  0c 43         clr  r12    ;
10
    6d92:  82 4c 8e 12   mov  r12,  &0x128e  ;
11
    6d96:  82 4d 90 12   mov  r13,  &0x1290  ;
12
    6d9a:  1c 42 3a 01   mov  &0x013a,r12  ;0x013a
13
    6d9e:  0d 43         clr  r13    ;
14
    6da0:  1e 42 8e 12   mov  &0x128e,r14  ;0x128e
15
    6da4:  1f 42 90 12   mov  &0x1290,r15  ;0x1290
16
    6da8:  0e dc         bis  r12,  r14  ;
17
    6daa:  0f dd         bis  r13,  r15  ;
18
    6dac:  82 4e 8e 12   mov  r14,  &0x128e  ;
19
    6db0:  82 4f 90 12   mov  r15,  &0x1290  ;

Optimierung jeweils -O2 beim MSPGCC.

von wuddy (Gast)


Lesenswert?

mag sein das meine Variante "aufwendiger" ist aber das Problem ist sie 
tut nicht und das wundert mich. Nach ausführen des letzten Befehls ist 
erg "unavailable"

von Christian R. (supachris)


Lesenswert?

Lerne C. Kann man nur nochmals sagen. Wenn die Variable nicht gebraucht 
wird, wirft die der Kompiler weg. Musst du halt als volatile 
deklarieren, dann kommt sie in den RAM und wird nicht wegoptimiert. 
Außerdem sollte der Kompiler dann eine Warnung bringen, dass du die 
Variable nicht benutzt.

von wuddy (Gast)


Lesenswert?

OK sehe ja ein das die Pointerlösung geschickter ist, hab das jetzt auch 
mal versucht anzuwenden aber das Problem ist das mein Compiler mit 
UINT32 / IN32 nix anfangen kann. Der Punkt ist doch das mit
1
UINT32 Result = *(UINT32*)&RESLO;
 ein zeiger angelegt wird der auf eine 32bit Variable verweist, die 
wiederum einre 32bit Variablen zugewiesen wird. Also müsste es doch auch 
mit einem anderen 32bit Datentyp gehen?

von Christian R. (supachris)


Lesenswert?

Na jetzt stell dich doch nicht so an. Hast du noch nie C programmiert? 
Dann nimm halt einen beliebigen 32-Bit breiten Datentyp.
meinetwegen

long Result = *(long*)&RESLO;

Wenn long bei deinem Kompiler 32 Bit sind....welchen Kompiler benutzt du 
eigentlich?

von wuddy (Gast)


Lesenswert?

Sorry aber ich versteh die welt nicht mehr. Hab die Geschicht von oben 
jetzt mal in ein anderes, kleies Testprogramm eigebunden und es tut 
einwandfrei; beider Varianten. In meinem Ursprungsprogramm will es 
allerdings nicht.
Entschuldige mich aber erstmal dafür einen so begriffsstutzigen Eindruck 
gemacht zu haben. Aber es hat einfach keinen Sinn ergeben. Wenn mal den 
halben Tag damit zubringt sowas simples zum laufen zu bringen sieht man 
irgendwann den Wald vor lauter Bäumen nicht mehr :D

Ach ja... ich programmiere mit IAR Embedded Workbench. Nähere Compiler 
Infos hab ich auf die schnelle jetzt nicht gefunden.

von wuddy (Gast)


Lesenswert?

Ok, hab jetzt den fehler beseitigt und jetzt tut es auch im 
Hauptprogramm! Danke für die Hilfe

von Christian R. (supachris)


Lesenswert?

Woran lag´s denn?

von wuddy (Gast)


Lesenswert?

Das willst du jetzt nicht wirklich wissen :D
Alt bekanntes Problem ( Variablengültigkeit). Hab jetzt die variablen 
die ich brauch global definiert und siehe da es geht. Also das ist ein 
Fehler der mir nicht mehr so häufig unterlaufen wird.

von Christian R. (supachris)


Lesenswert?

Wenigstens bist du lernfähig....wir haben hier auch viele 
lernresistente...

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.