MPLAB, Assembler, PIC16F1512: Warum funktioniert der folgende Ausdruck nicht? [movlw 0x90+kanal-0x1] Inhalt von "kanal" = 0x1 Adresse von "kanal" = 0x30 w soll geladen werden mit 0x90 + 0x1 - 0x1 = 0x90 Tatsächlich berechnet der Assembler diesen Wert aber mit 0xC0. Statt den Inhalt der Zelle "kanal" zu nehmen, rechnet der Assembler wohl mit der Adresse der Zelle "kanal". Wie erreiche ich das richtige Ergebnis?
Da wird wohl ein intermediate '#' fehlen.
Ich empfehle da dringend das Studium der Adressierungsarten im Manual.
Ein movlw kann auch nicht auf:
> Inhalt von "kanal" = 0x1
zugreifen.
:
Bearbeitet durch User
Wie hast Du denn kanal definiert? Warum immer der Geiz mit dem Zeigen von den exakten Codezeilen (C&P).
Vielen Dank für die schnelle Information! An welcher Stelle fehlt das #-Zeichen? Wenn ich die Antwort richtig verstehe, dann kann ich mit oder ohne #-Zeichen keinesfalls auf den Inhalt von "kanal" zugreifen. Der Assembler rechnet immer nur mit der Adresse. Zum Studium der Adressierungsarten: Ja, das ist notwendig, denn ich bin Anfänger...
Hallo peda, "kanal" ist wie folgt am Anfang des Programmes dem Speicherort 0x30 zugeordnet worden: kanal equ 0x30
Ein Assemler kennt nicht das Konzept von Variablen, das kann nur ein Compiler. Für den Assembler sind alle Symbole nur Symbole. Du kannst sie als Adreßlabel verwenden oder als Wert.
Michael B. schrieb: > kanal equ 0x30 Auch wenn meine PIC-Zeiten schon wieder ewig zurückliegen, aber das ist doch nur eine Konstante, und keine Adresse. > Adresse von "kanal" = 0x30
Michael B. schrieb: > kanal equ 0x30 Damit sagst Du dem Assembler nur, ersetze fürderhin alle Vorkommen von "kanal" durch "0x30". Daß Du irgendwann mal an Adresse 0x30 den Wert 0x1 abspeichern willst, das kann er nicht erahnen. Er weiß schlichtweg nichts von Variablen oder Typen.
Vielen Dank für den Hinweis. Dann muss ich das wohl auflösen in folgende Programmzeilen: movlw h'90' addwf kanal,0 ;w = w + kanal (Inhalt von kanal) movwf ON ;ON = w decf ON,1 ;ON = ON - 1 Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen könnte: movlw 0x90+kanal-0x1 Jetzt sind es immerhin 4!
:
Bearbeitet durch User
addwf kanal,0 ;w = w + kanal (Inhalt von kanal) Das ist zwar nicht falsch, besser waere: addwf kanal,w ;w = w + kanal (Inhalt von kanal) Dann ist der Kommentar unnoetig. Genau so: decf ON,1 ;ON = ON - 1 decf ON,f ;ON = ON - 1 oder gleich decf ON ;ON = ON - 1 Das ein PIC kein ARM ist, hast du ja schon festgestellt. Und sparen kann man beim PIC am besten, wenn man sich klar macht, dass das w-Register eben kein Akku ist, sondern nur ein Hilfsregister um literale Werte laden zu koennen. Man rechnet eben direkt mit den Registern. Das Ergebnis einer Operation steht danach im Register. Weiteres Speichern: ueberfluessig.
Vielen Dank für die wertvollen Tipps. Dennoch habe ich noch folgende Fragen: In der PIC-Befehlsbeschreibung steht aber, dass man "0" oder "1" hinter dem Komma schreiben soll, nicht aber "f", "w" oder gar "nichts"! Das verwirrt natürlich den Laien und wirft die Frage auf, wo man nachlesen kann, welche Bezeichnungen hinter dem Komma zulässig sind. In der Befehlsbeschreibung PIC kennt man nur "0" oder "1". Ersetzt "f" die "1"? Ersetzt "w" oder " " die "0"? Jedenfalls ist "f" oder "w" viel anschaulicher, als "0" oder "1"!
:
Bearbeitet durch User
> Jedenfalls ist "f" oder "w" viel anschaulicher, als "0" oder "1"! Ja eben :). Der Fall > "nichts" ist der Default. Und der steht sehr wohl in der Beschreibung. Ob das f und w in den Assembler "eingebaut" ist, oder einfach als EQU in einem Headerfile steht? Das kannst du ja selbst rauskriegen. Zum Lesen: https://www.sprut.de/electronic/pic/grund/grund.htm https://www.sprut.de/electronic/pic/assemble/befehle.html
:
Bearbeitet durch User
Michael B. schrieb: > Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen > könnte: > movlw 0x90+kanal-0x1 Man muß sich schon mit dem Befehlssatz beschäftigen, wenn man Assembler programmieren will. MOVLW erwartet eine Konstante als Argument. Es kann also keine Variable aus dem RAM lesen. Der Assembler berechnet daher 0x90+0x30-0x1 und übergibt es dem MOVLW.
Vielen Dank für diese Informationen und die Zusammenhänge sind jetzt völlig klar. Meine Bemerkung zum Befehlssatz und der "0" bzw. "1" bezog sich mehr auf den Befehl ADDWF, dessen Beschreibung wie folgt lautet: ADDWF Add W and f Syntax: [ label ] ADDWF f,d Operands: 0 f 127 d 0,1 Operation: (W) + (f) (destination) Status Affected: C, DC, Z Description: Add the contents of the W register with register ‘f’. If ‘d’ is ‘0’, the result is stored in the W register. If ‘d’ is ‘1’, the result is stored back in register ‘f’. Hier kann man für "d" gemäß Beschreibung nur "1" oder "0" einsetzen. Von "w" oder "f" ist hier keine Rede. Nach Deinen Erklärungen verstehe ich das wie folgt: "0" würde dann "ADDWF xxx,w" entsprechen und "1" "ADDWF xxx,f". "w" ist somit Platzhalter für "0" und "f" ist somit Platzhalter für "1". Das dürfte im Assembler eingebaut sein, denn ansonsten bekäme ich eine Fehlermeldung bei Anwendung von "w" oder "f".
> Das dürfte im Assembler eingebaut sein, denn ansonsten bekäme ich eine > Fehlermeldung bei Anwendung von "w" oder "f". Vermutlich ja. Weil der Assembler ja auch ohne weitere Hilfe den Default kennt. Trotzdem koennte "irgendwo" in einem Includefile ja auch ein: f EQU 1 w EQU 0 stehen. Das koenntest du zur Vervollstaendigung deines Wissens ja mal ausprobieren. So ein EQU wuerde ja dann ueberall in einem Assemblerfile seine Wirkung tun. Nicht nur in der Zielangabe von Befehlen. Also z.B. movlw #f :)
Michael B. schrieb: > Vielen Dank für den Hinweis. > Dann muss ich das wohl auflösen in folgende Programmzeilen: > > movlw h'90' > addwf kanal,0 ;w = w + kanal (Inhalt von kanal) > movwf ON ;ON = w > decf ON,1 ;ON = ON - 1 > > Schade, ich hatte geglaubt, dass man dies mit nur einer Zeile machen > könnte: > movlw 0x90+kanal-0x1 > > Jetzt sind es immerhin 4! Dass es 4 Zeilen sind, liegt daran, dass du das Ergebnis noch nach ON transportierst, sonst wären es 3 Zeilen. Man kann aber noch eine Zeile einsparen, wenn man nicht extra dekrementiert sondern: movlw 0x90 - 0x01 addwf kanal,w
Hallo motopick, vermutlich findet man das im File "p16F1512" (include <p16F1512.inc>). Leider kann ich diese Datei im MPLAB nicht öffnen. Unter "Projects" ist dieses File nicht zu finden... Noch einmal herzlichen Dank für Deine Zeit, die Du mit der Beantwortung meiner Fragen geopfert hast. Das hat mir deutlich weitergeholfen!
Michael B. schrieb: > vermutlich findet man das im File "p16F1512" (include <p16F1512.inc>). So ist es: ;===================================================================== ; ; Register Definitions ; ;===================================================================== W EQU H'0000' F EQU H'0001'
Hallo berndmm, vielen Dank für Deinen heißen Tipp! Dann geht es ja doch erheblich kürzer (kanal=0x1): movlw 0x90-0x01 ;w = 0x8F addwf kanal,w ;w = 0x8F + kanal = 0x90 Das sind sogar 2 Zeilen weniger, wenn ich ON nicht brauche! Wie konnte ich das übersehen? Jetzt werde ich das gesamte Programm danach untersuchen, ob ich diesen Fehler auch noch woanders gemacht habe... Herzlichen Dank!
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.