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?
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...
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.
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.
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"!
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.
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.
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:
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!
vielen Dank für Deinen heißen Tipp! Dann geht es ja doch erheblich kürzer (kanal=0x1):
1
movlw 0x90-0x01 ;w = 0x8F
2
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!