PIC Anfängerfrage Variablen

OP #2380095
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
Gast #2380098
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
#2380111
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.
Gast #2380178
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.
#2380254
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.
#2380735
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
Gast #2380755
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.
Angehängte Dateien:
Gast #2380874
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.
Gast #2380878
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!
Gast #2380896
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
OP #2381148
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren