Hallo zusammen,
ich hab da was nicht ganz verstanden beim setzen der Variablen in einem
Programm.
hab folgendes Beispiel aus einem Buch:
1
2
ZAEHL1 equ 0C ; 0C = erste freie RAM-Adresse
3
ZAEHL2 equ 0D
4
5
; Zeile
6
7
w equ 0
8
f equ 1
ZAEHL1 und ZAEHL2 sind mir soweit klar, hierbei handelt es sich um
Adressen im Register.
Wie sind "w" und "f" hier zu verstehen, sind die "0" und die "1" nicht
auch Adressen im Register?
Vielen Dank schon mal!
Gruß
Philipp
Hier werden nur neue "EQUivalente" Namen für die Konstanten 0C, 0D, 0
und 1 definiert. Damit kann man den dann nachfolgenden Quelltext
lesbarer gestalten.
Der Programmierer hat sich moch eine Anmerkung geschrieben, 0C die
"erste freie RAM-Adresse" ist. Er hätte sich auch einen besseren Namen
ausdenken können und dann den Kommentar weglassen können z.B.
RAMSTART equ 0C
http://www.sprut.de/electronic/pic/assemble/pseudo.html#equ
Krapao schrieb:> w soll wohl "wahr" bedeuten und f "falsch". Naja.
Falsch, es handelt sich um einen Bit-Operanden, der zu den Befehlen
gehört die ihr Ergebnis entweder ins Arbeitsregister "wreg" (w) oder in
ein "file register" (f) im RAM zurückschreiben.
Grüße,
Edson
W steht für Work-Register und F für File-Register. Wenn du einen Befehl
hast, der als 2. Parameter die "Zieladresse" haben will, dann kannst du
ihm sagen, dass er das Ergebnis in das Workregister (0) oder in das
Fileregister (1) zurückschreiben soll. Doch weil man da evtl
durcheinander kommt mit den Zahlen, kann man dann gleich hinschreiben w
oder eben f.
Z.b.:
ADDWF zahlregister, 1
Hier addiert er die Zahl, die im Register "zahlregister" steht zu der
Zahl im Workregister und schreibt das Ergebnis wieder ins fileregister,
sprich in "zahlregister".
Doch wenn man am Anfang mit dem "f" die Zahl 1 verknüpft, dann kann man
auch "ADDWF zahlregister,f" schreiben. Oder eben w, wenn das Ergebnis
ins Workregister geschrieben werden soll.
ok, das mit dem File- und dem Arbeitsregister leuchtet mir ein.
Vereinfacht die Sache ein wenig. Danke!
was mir noch nicht beantwortet wurde: Sind "0" u. "1" jetzt Dezimal-,
HEX- oder Binärzahlen? wie unterscheiden sich die beiden Werte von den
Adressen 00...0C, 0D...?
LG
Wenn w oder f an der Stelle des Operanden d bei einem Befehl wie ADDWF
benutzt werden, sind sie als Binärzahlen zu interpretieren. Nur zwei
Werte sind zulässig entweder 0 oder 1.
http://www.sprut.de/electronic/pic/assemble/befehle.html#addwf
Allgemein gesehen sind 0 und 1 sowohl Binärzahlen, als auch
Dezimalzahlen als auch Hexadezimalzahlen. Bei einem Befehl, der bei dem
Operand k eine Konstante erlaubt, wie z.B. ADDLW, können alle oben
definierten Konstanten benutzt werden...
http://www.sprut.de/electronic/pic/assemble/befehle.html#addlw
ADDLW ZAEHL1 ; Erhöht W um 0C(hex) oder 12(dez)
ADDLW ZAEHL2 ; Erhöht W um 0D(hex) oder 13(dez)
ADDLW w ; Erhöht W um 0(bin) oder 0(hex) oder 0(dez)
ADDLW f ; Erhöht W um 1(bin) oder 1(hex) oder 1(dez)
Es gibt unterschiedliche Schreibweise für Hexzahlen und in der
jeweiligen Assembler-Doku steht, welche für diesen Assembler zulässig
ist. Eine gängige Schreibweise z.B. auch bei C ist, dass man ein
Hexzahlen ein 0x voranstellt. Im obigen Fall also 0x0C bzw. 0x0D. Diese
Schreibweise man auch beim PIC Assembler benutzen.
Beim PIC Assembler werden wohl alle Zahlen ohne vorangestelltes Zeichen
und '' Klammerung als Hexadezimalzahlen interpretiert:
http://www.sprut.de/electronic/pic/assemble/assembler.html#Regeln
Das ist für nicht PIC-User gewöhnungsgedürftig. IMHO sollte man sich die
0x Schreibweise angewöhnen.
Krapao schrieb:> Beim PIC Assembler werden wohl alle Zahlen ohne vorangestelltes Zeichen> und '' Klammerung als Hexadezimalzahlen interpretiert:> http://www.sprut.de/electronic/pic/assemble/assemb...
Kann per "radix" Direktive eingestellt werden. Zitat aus der verlinkten
Seite: "kann aber mit der list r= -Direktive umgestellt werden"
> Das ist für nicht PIC-User gewöhnungsgedürftig. IMHO sollte man sich die> 0x Schreibweise angewöhnen.
In allen Code-Beispielen von Microchip wird diese Schreibweise
verwendet, der vom TE gepostete Code stammt ja aus unbekannter Feder.
Vielen Dank für die raschen Antworten. Soweit versteh ich das nun.
... bleibt noch eine Frage offen: "Kann ich einer Variablen auch eine
x-belibige zahl zuweisen, oder muss es ein Register sein in welches ich
eine Zahlenwert speichere?"
Gruß
Philipp
Das sind keine Variablen, sondern Equivalente. Das bedeutet, dass vor
dem assemblieren jedes Equivalent durch den Wert ersetzt wird. Also aus
jedem ZAHL1 wird 0C, usw.
Und selbst wenn es Variablen wären, kannst du keine Register zuweisen.
Das ist also möchtest du dem Ergebniss einen Schmierzettel zuweisen. :-D
Hallo Philip,
deine Probleme kann ich verstehen. Das meiste davon geht auf das Konto
des nicht wirklich gut gemachten Assemblers von MicroChip. Das war vor
vielen Jahren der Grund, weswegen ich mir für die PICs meinen eigenen
Assembler geschrieben habe. Ich hänge den mal hier dran, einschließlich
eines kleinen Beispiels, damit man mal sehen kann, daß es auch anders
geht.
Was mich beim originalen PIC-Assembler gestört hat, ist hauptsächlich:
1. er kennt keine Adresßräume, obwohl ein PIC ja getrennte Adreßräume
für Daten und Code hat. Bei mir: 'SEG RAM' und 'SEG CODE' um klar
zwischen Daten und Code zu trennen.
2. er kennt keine Speicher-Reservierung, was eine Folge aus 1. ist. Bei
mir: 'DS anzahl' im RAM und 'DATA blabla' im Code (EPROM), z.B. 'DATA
'Hello World'
3. er ist bei Bitmanipulationen zu primitiv:
Ottokar equ 1
BSF PortA,Ottokar
und wenn man aus Versehen mal die Zuordnung zwischen Adresse und
Bitnummer verwechselt, dann sucht man sich halbtot.
Bei mir wird zuerst das Bit eindeutig spezifiziert und dann solo
verwendet:
Ottokar: BIT PortA,1
BSF Ottokar
Da kann nie wieder ne Verwechselung stattfinden (von den Bänken mal
abgesehen)
4. Die Bit-Tests hatten mir auch nicht gefallen:
BTFSS PortA,Ottokar
BTFSC PortA,Ottokar
bei mir:
SKIP Ottokar
SKIP NOT Ottokar
oder was Vordefiniertes:
SKIP Z
SKIP NC
und so weiter
Kurzum, es geht auch besser, dann aber ohne Mplab, es sei denn, jemand
bindet meinen Assembler dort ein.
Das Beispielprogramm funktioniert zwar, aber ich poste es hier nur zu
dem Zweck, daß man mal anhand der Übersetzungsliste sieht, wie man bei
diesem Assembler die Quelle schreiben kann.
W.S.
> Kann ich einer Variablen auch eine> x-belibige zahl zuweisen, oder muss es ein Register sein in welches ich> eine Zahlenwert speichere?
Dazu muss man sich klar werden, wie eine Variable im PIC abgelegt werden
kann.
Eine Variable in einem Register liegen. Dann besteht die Zuweisung eines
Wertes in dem entsprechenden Ladebefehl für eine Konstante in dieses
Register.
MOVLW ZAEHL1 ; Zahl 0C in Register laden
Eine Variable kann aber auch in einer Speicherzelle liegen. Dann besteht
die Zuweisung darin, mit einem entsprechenden Ladebefehl eine Konstante
in die Speicherzelle zu schaffen. Für die Speicherzelle kann man wie
oben mit EQU einen griffigen Namen benutzen. Soweit ich sehe, geht das
Datenbewegen aber i.d.R. über den Umweg eines Registers.
MOVLW ZAEHL1 ; Zahl 0C in Register laden
MOVWF ZAEHL1 ; Inhalt von Register W in Speicherstelle 0C laden
Ausnahme ist, wenn die Zahl eine 0 ist. Dann kann man die Speicherstelle
in einem Rutsch löschen
CLRF ZAEHL1
"x-beliebige Zahlen" nö. Bei den Registern und Speicherstellen bist du
bei einem Maschinenbefehl bei 8-Bit PICS auf 8-Bit Werte (vorzeichenlos
0..255) festgelegt. Wenn du größere oder kleinere Zahlen hast, kannst du
die aus mehreren 8-Bit Werten zusammenbauen und in mehreren
Speicherstellen ablegen. Du musst dich dann aber darum kümmern, wie du
mit mehreren Befehlen für 8-Bit Portionen damit umgehst. Dafür gibt es
z.B. Bibliotheken von Softwareroutinen z.B. für 16/32-Bit Multiplikation
usw.
> MOVLW ZAEHL1 ; Zahl 0C in Register laden> MOVWF ZAEHL1 ; Inhalt von Register W in Speicherstelle 0C laden
Es ist wichtig, dass du die unterschiedliche Bedeutung von ZAEHL1 in den
beiden Zeilen erkennst. Einmal wird ZAEHL1 für eine Konstante verwendet
und einmal für eine Speicherstelle. Geschicktes Programmieren wird das
nach Möglichkeit vermeiden. Die EQUs kosten keine Ausführungszeit und
keinen Speicherplatz. Man kann sie also großzügig verwenden:
ZAEHLER1 EQU 0C
SCHWELLWERT1 EQU 0C
MOVLW SCHWELLWERT1 ; Zahl 0C in Register laden
MOVWF ZAEHL1 ; Inhalt von Register W in Speicherstelle 0C laden
Ist IMHO weniger zweideutig und besser lesbar als die erste Fassung -
bei gleicher Funktion bzw. gleichem Maschinencode!
> ZAEHLER1 EQU 0C
^^
ZAEHL1 EQU 0C
natürlich. Wenn man Konstanten mit ...WERT EQUt und RAM Variablen
(Speicherzellen) mit ...VAR ist es auch lesbarer.
SCHWELLWERT1 EQU 0C
ZAEHLERVAR1 EQU 0C
MOVLW SCHWELLWERT1
MOVWF ZAEHLERVAR1
W.S. schrieb:> deine Probleme kann ich verstehen. Das meiste davon geht auf das Konto> des nicht wirklich gut gemachten Assemblers von MicroChip. Das war vor> vielen Jahren der Grund, weswegen ich mir für die PICs meinen eigenen> Assembler geschrieben habe. Ich hänge den mal hier dran, einschließlich> eines kleinen Beispiels, damit man mal sehen kann, daß es auch anders> geht.
Danke für deine Hilfe, ich werde mir dein Assambler noch näher ansehen.
Ich hab grade erst begonnen mir das Programmieren im Selbststudium bei
zu bringen und werde mich daher noch auf die in meinen Büchern
beschriebennen Assembler konzentrieren.
Krapao schrieb:>> MOVLW ZAEHL1 ; Zahl 0C in Register laden>> MOVWF ZAEHL1 ; Inhalt von Register W in Speicherstelle 0C laden>> Es ist wichtig, dass du die unterschiedliche Bedeutung von ZAEHL1 in den> beiden Zeilen erkennst. Einmal wird ZAEHL1 für eine Konstante verwendet> und einmal für eine Speicherstelle.
Danke, jetzt hab ich es glaub ich verstanden... ich kann die Äquivalente
sowohl als Zahl als auch als Speicherzelle verwenden... je nach Einsatz
xD
omg...schwere Geburt... :)
Danke allen die mich hier unterstützt haben!
Schönen Gruß
Philipp