Forum: Mikrocontroller und Digitale Elektronik PIC Anfängerfrage Variablen


von Philipp L. (khz-tone)


Lesenswert?

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

von Krapao (Gast)


Lesenswert?

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

von Krapao (Gast)


Lesenswert?

w soll wohl "wahr" bedeuten und f "falsch". Naja.

von Krapao (Gast)


Lesenswert?

w := 0 und f := 1 sind dann aber komisch. Jedenfalls hat es IMHO nix mit 
den Registern W und F zu tun. Genaueres müsste man im Quellcode kucken.

von Meister E. (edson)


Lesenswert?

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

von Michael S. (rbs_phoenix)


Lesenswert?

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.

von Krapao (Gast)


Lesenswert?

Wieder was gelernt. Thanks.

von Philipp L. (khz-tone)


Lesenswert?

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

von Krapao (Gast)


Lesenswert?

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.

von Meister E. (edson)


Lesenswert?

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.

von Philipp L. (khz-tone)


Lesenswert?

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

von Sebastian H. (sebihepp)


Lesenswert?

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

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Krapao (Gast)


Lesenswert?

> 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.

von Krapao (Gast)


Lesenswert?

> 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!

von Krapao (Gast)


Lesenswert?

> 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

von Philipp L. (khz-tone)


Lesenswert?

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

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.