Forum: Mikrocontroller und Digitale Elektronik PIC Assembler "MOVF" Befehl


von Stefan (Gast)


Lesenswert?

Hallo!

Habe ein fremdes fehlerhaftes Programm das ich korrigieren muß.
Der Schreiber des Programmes benutzt scheinbar den "movf" Befehl immer 
in
folgender Form:

movf INDF0,w

Wahrscheinlich dachte er das heitß: Kopere INDF0 nach w -
nach Sprut und anderen Anleitungen sehe ich nun aber dass,
falls w=0: Speicherzelle INDF0 wird in das Arbeitsregister w kopiert.
falls w=1: Speicherzelle INDF0 wird auf sich selbst kopiert.

Gilt das nun auch wenn man wie hier blöderweise das Arbeitsregister 
selbst angibt?

Was passiert wenn w weder 0 noch 1 ist?

Hier Zeig ich euch mal den Assembler Ausschnitt in dem ich den Fehler 
Vermute:

######################################################
Remote
  movf  INDF0,w
  xorlw  'R'; check for remote operation
  btfss  STATUS, Z
  goto  nextcom
  decf  counter, f
  incf  FSR0L, f
  movf  INDF0, w ; load remote setting
  xorlw  '1'
  btfss  STATUS, Z ; check if remote operation was set
  goto  FrontPanel
  movlw  '1'; !!!!!!!!!! Hier wird W zu 1 !!!!!
  movwf  devicestatus+0x19
  bcf  INTCON3, INT1IE; disable external keypad interrupt
  bcf  INTCON3, INT3IE; disable external rotary encoder interrupt
  bsf    remote_led
  goto  EndRemote
FrontPanel
  movf  INDF0, w; !!!!!!! Hier ist W=1, kopie schlägt fehl!!!!
  xorlw  '0'
  btfss  STATUS, Z
  goto  EndRemote
  movlw  '0'
  movwf  devicestatus+0x19
  bsf  INTCON3, INT1IE; enable external keypad interrupt
  bsf  INTCON3, INT3IE; enable external rotary encoder interrupt
  bcf  remote_led
EndRemote
  dcfsnz  counter, f
  goto  endspeccom
#####################################################

Ich denke in den beiden Zeilen mit den Ausrufezeichen steckt der Fehler, 
was meint ihr?

Zudem habe ich noch eine weitere Frage, die Interrupts werden hier für 
eine Tastatur verwendet, wäre es nicht besser die Int-Flags zu löschen 
bevor ich die Interrupts der Tastatur reaktiviere? Sonst könnten doch
alte Interrupts die noch im Register sind, sofort einen Interrupt 
auslösen obwohl keine Taste gedrückt wird. Oder kommen die Flags nur 
wenn die Interrupts auch angeschalten sind?

Vielen dank schonmal im vorraus!

Gruß Stefan

von Gast (Gast)


Lesenswert?

Nein, der Befehl funktioniert genauso wie du es zuerst schreibst.
In der Include_datei ist "w" als "1" definiert.
Es ist egal was im WREG drinsteht. Du kannst auch "movf INDF0,1" 
schreiben.
Das ist nur eine andere Schreibweise.

von TK (Gast)


Lesenswert?

Hallo Stefan,

normalerweise ist 'w' und 'f' in der Include-Datei definiert und dabei 
ist 'w' immer 0 und 'f' immer 1!

Demnach ist das Programm mit den Bezeichnungen auch richtig.
Schau Dir mal an, was der Befehl 'movlw' überhaupt macht!!
Das hat nichts mit 'w' oder 'f' zu tun!!

Gruß
TK

von Stefan (Gast)


Lesenswert?

Hi!

für MOVLW steht: Move Literal to W

gibts jetzt 2 W´s? Ich dachte w wäre mein Arbeitsregister?
Und ins Arbeitsregister kann ich doch was reinladen.

Ich bin froh wenn das nicht der Fehler ist, denn die 4000 Zeilen 
Assembler haben 200 mal diesen MOVF X,W Befehl.

Aber mit euere Beschreibung steh ich jetzt aufm Schlauch, ist W nicht 
das Arbeitsregister?

Gruß Stefan
(Ps. Soll ich nun wie erfragt besser die Interrupt-Flags löschen?)

von Torsten S. (torstensc)


Lesenswert?

Es gibt nur ein W.

movlw '1' kopiert den Wert '1' in das Arbeitsregister.

movf  INDF0,w kopiert den Wert aus INDF0 in das Arbeitsregister.

dafür kannst du auch den "Pseudeo"-Befehl

movfw INDF0  nehmen.

Und ja, du solltest die Flags löschen, sonst erhältst du gleich wieder 
einen INT.

INDF ist aber nur ein Register für die indirekte Adressierung. Bist du 
auch sicher, dass beim Sprung nach Label remote dort auch das richtige 
Source-Register mit FSR ausgewählt ist?

Torsten

von Stefan (Gast)


Lesenswert?

Vielen Dank für Die Antworten, dann im Assembler-Guide stehts auch so - 
dann hab ich mich von der SPRUT Erklärung irgendwie durcheinanderbringen 
lassen.

Die I-Flags lösch ich jetzt mal und das mit den FSR schau ich auch nach, 
danke!.

Gruß Stefan

von Wanja N. (dasalphatier)


Lesenswert?

hallo Leute
ich habe das selbe Problem mit diesem Befehl movf.
Habe mir die Beiträge hier durchgelesen und mir ist immer noch nicht 
klar was da passiert. Dieser Befehl wird so benutzt:

movf BAUD_RATE, W

in dem Standart Header File steht:

W                            EQU     H'0000'
F                            EQU     H'0001'

ist nun mit diesem W in der Befehlszeile(movf BAUD_RATE, W) der Inhalt 
des Arbeitsregisters gemeint oder nicht. Laut sprut passiert hier 
folgendes: der Inhalt der Speicherzelle BAUD_RATE wird nach 
Arbeitsregister kopiert wenn W=0. Das würde bedeuten, so wie ich es 
verstehe, dass nach dem Befehl vorraussgesetzt das Arbeitsregister war 0 
wird das Arbeitsregister mit dem Inhalt der Speicherzelle BAUD_RATE 
gefüllt.

Würde mich freuen wenn einer mich aufklärt.

MfG Iwan

von Dieter W. (dds5)


Lesenswert?

Hallo Iwan,

das mit der unterschiedlichen Bedeutung der beiden "w" ist wirklich 
schwer verständlich.

Einmal gibt es das "w" als Bezeichnung für das Working- oder 
Arbeitsregister, bei vielen MCUs auch Akku(mulator) genannt.
Das tritt aber nicht als einzelner Buchstabe, sondern nur in Befehlen
wie z.B. movlw oder movwf auf.

Zum Anderen gibt es w als Argument, unter anderem beim Befehl
movf Variable,w. Hier ist w eine Konstante mit dem Wert 0.

Am Besten wird das meiner Meinung nach von
Autor: TK (Gast)
Datum: 26.01.2009 13:58
beschrieben.

von Wanja N. (dasalphatier)


Lesenswert?

vielen dank für die Antwort

ist die Definition der Variablen wie ich oben beschrieben habe in dem 
Standart Header File ?

W                            EQU     H'0000'
F                            EQU     H'0001'

MfG Iwan

von Dieter W. (dds5)


Lesenswert?

Die genannte Definition ist in der zur jeweiligen MCU passenden include 
Datei, z.B. P16F84A.INC zu finden.

Diese Dateien liegen im Verzeichnis   mplab/MPASM Suite

Nachtrag:
Es handelt sich nicht um Variablen sondern um numerische Konstanten.

von Wanja N. (dasalphatier)


Lesenswert?

Dankeschön nochmal Dieter,
hast mir echt gut weitergeholfen. Mein Kampf kann weitergehen :-)

von TK (Gast)


Lesenswert?

Um die Verwirrung jetzt zu komplettieren benutze ich beim Programmieren
anstatt des Befehls "movf" das Macro "movfw". Das ist ebenso in der 
Include-Datei definiert und macht nichts anderes, als den Registerinhalt 
in den Akku (W-Register) zu kopieren. Mit dieser Schreibweise ist ein 
Code VIEEEEL verständlicher zu interpretieren.
Meistens wird der Befehl "movf REG,w" genutzt, da "movf REG,f" nur dann 
Sinn macht, wenn damit das STATUS-Register abgefragt werden soll. Und 
genau hierfür gibt es auch das Macro "TSTF REG".

Gruß
TK

von (prx) A. K. (prx)


Lesenswert?

Man sieht hieran, wozu Werbeslogans wie "leicht erlernbar, weil nur 
<soundsoviel> Befehle" führen können. Wenn man die ,1 und ,0 Varianten 
der MOVF und <op>F Befehle als separate Befehle oder Makros ausdrückt, 
dann ist zwar das Werbeargument beim Teufel, der Code aber lesbarer und 
die Programmierung trotz mehr Befehle einfacher.

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.