ro.heg

RCLine User

  • »ro.heg« ist der Autor dieses Themas

Wohnort: Quickborn

  • Nachricht senden

1

Freitag, 7. November 2008, 14:09

der Befehl "incf"

Hallo Leute,
es geht mir um den Befehl incf

Ich habe die Datei pic12f-01.asm als Zip-Datei angehangen.
Der Qelltext bezieht sich auf den Ortungspieper, über den schon so viel
diskutiert wurde.
Als Beispiel die Procedure vorber1 ;Zeitablauf = 20 Minuten
Als erstes werden die Konstanten 1300 in die Variablen
SEKUNDEN_HIGH u. SEKUNDEN_LOW transportiert.
Danach call warten
incf SEKUNDEN_LOW,F ;Inhalt + 1 (Inkrement)
incf SEKUNDEN_HIGH,F ;das gleiche
jetzt geht es mit warten1 weiter.
Ich sehe einfach den Sinn von incf nicht!
Im Buch steht, der Befehl erhöht das Register um eins (Frage, was für ein
Register? Etwa F) SEKUNDEN_xxxx ist doch kein Register!
Wo liegt hier der Sinn des Ganzen.
Hoffentlich klappt das jetzt mit der Zip.Datei

Viele Grüße
Rolf
»ro.heg« hat folgende Datei angehängt:
  • PICASM.zip (2,67 kB - 9 mal heruntergeladen - zuletzt: 30. April 2014, 20:29)

2

Freitag, 7. November 2008, 23:13

Hallo Rolf,

doch, SEKUNDEN_xxxx sind Register, und zwar auf den Adressen 0x20 und 0x21, siehe die CBLOCK-Anweisung am Anfang des Programms.

Das "F" nach dem incf bedeutet, dass der Wert nach dem hochzählen wieder in das gleiche Register zurückgeschrieben wird.
Alternative könnte man auch ein "W" verwenden, dies würde bedeuten, dass der Registerinhalt unverändert bleibt, und der um 1 erhöhte Wert im Arbeitsregister W zu liegen kommt.

"F" und "W" sind übrigens im .inc File als Bezeichnungen für die Werte 0 und 1 definiert.

Eine gute Auflistung aller PIC Befehle auf deutsch gibts bei sprut:

http://www.sprut.de/electronic/pic/assemble/befehle.html

Grüße
Claus

3

Samstag, 8. November 2008, 01:49

RE: der Befehl "incf"

Hallo Rolf,

erstmal zum Formalen, was den Begriff "Register" betrifft:
die klassische Einteilung in "Register" und "Speicher", wie man es evtl. von anderen Prozessor-Architekturen gewohnt ist, gibt es bei den PICs nicht.
Es gibt hier nur das "W"-Register und die "File Register". Zu "File Registern" gehört alles, was über die Adresse im Opcode angesprochen werden kann, also die Register mit speziellen Funktionen (IO-Port, Timer, Statusregister usw) und die Register, die einfach nur die in sie hineingeschriebenen Daten speichern. Auch diese "RAM"-Speicherzellen werden hier als Register bezeichnet.
Zur Bezeichung "W" und "F": "W" kommt wohl von "Work"=Arbeit, also "Arbeitsregister", und das "F" steht für "File Register".

Zur logischen Funktion der "incf"-Befehle in Deinem Programm-Kontext:
Wir haben es ja hier mit Zählschleifen zu tun, d.h. es wird eine Zahl (=Anzahl der Schleifendurchläufe) in das Register geladen und dann wird das Register in der Schleife heruntergezählt, bis der Zähler abgelaufen ist.

Hier wird ein 16-bit Zähler realisiert, der über "decfsz"-Befehle die Zählerhälften (Sekunden_low/high) jeweils herunterzählt. Zuerst wird der niederwertige Teil (low) heruntergezählt, und wenn dieser über 0 geht, zählt auch der höherwertige Teil.
Die Bedingung "Zero" wird erreicht, wenn das Register von 1 auf 0 geht, der Übertrag auf das höherwertige Byte müßte aber eigentlich beim Übergang von 0 auf 0xFF passieren! Stell Dir ein mechanisches, 2-stelliges Zählwerk vor: die rechte Ziffer sind die "Einer", d.h. unser niederwertiges (low)Digit, die linke Ziffer sind die Zehner=high. Wenn das Zählwerk korrekt rückwärts laufen soll, muß die Zehnerstelle um 1 decrementiert werden, wenn die Einer-Stelle von 0 nach 9 umspringt, nicht schon, wenn sie von 1 auf 0 springt!
Da der DECFSZ aber nunmal auf 1->0 reagiert und es keinen DECFSxFF-Befehl gibt, wird das einfach dadurch korrigiert, daß die Inhalte der Zählerstellen mit INCF vor dem Start der Schleife um eins erhöht werden. Dadurch braucht es einen Zählimpuls mehr, bis die 0 erreicht ist. Das hat den gleichen Effekt, als ob das Zählwerk erst einen Impuls später schalten würde, also bei 0xFF, statt bei 0.

Grüße,

Thomas

ro.heg

RCLine User

  • »ro.heg« ist der Autor dieses Themas

Wohnort: Quickborn

  • Nachricht senden

4

Samstag, 8. November 2008, 19:31

mh...danke für Eure Nachrichten, das muß ich erstmal verarbeiten!

Grüße

Rolf

Am besten, ich drucke es mir aus.

ro.heg

RCLine User

  • »ro.heg« ist der Autor dieses Themas

Wohnort: Quickborn

  • Nachricht senden

5

Montag, 10. November 2008, 12:24

Hallo Leute,
ich sitze hier vor dem Ausgedruckten! Und ich dachte, daß die frei wählbaren
Variablen nicht zu den Registern gehören. Rein aus Neugierde habe ich im
Quelltext das ,F weggelöscht (also incf SEKUNDEN_LOW) und dachte, der
Assembler zeigt eine Fehlermeldung... nichts da! Eigentlich hätte ich es doch
weder zum "W" Register noch zum "File Register deklariert .
Liege ich richtig?
Der 16 Bit-Zähler wird mit SEKUNDEN_HIGH u. SEKUNDEN_LOW realisiert.
SEKUNDEN_LOW ist das niederwertige Byte = 8 Bit
SEKUNDEN_HIGH ist das höherwertige Byte = 8 Bit
Das mit dem Zählwerk ist eine gute Idee. Ich muß mir das aber noch dreimal
durchlesen. Von der Logik habe ich aber begriffen, warum der INCF Befehl
einmal durchgeführt werden muß.
Zum Schluß: Habe im Qelltext mal das _LOW gelöscht =113 Error
darauf 2x Klick und der Corser sprang direckt in die Fehlerzeile.
Übrigens steht in meinem Buch, daß der Befehl "RETURN" nur für
PIC16CXX anwendbar sei, "RETLW" für alle anderen!
Thomas hat aber RETURN im Led.asm verwendet und es funktionierte, mh!

Viele Grüße

Rolf

6

Montag, 10. November 2008, 13:15

Hallo Rolf,

Zitat

Original von ro.heg
Hallo Leute,
ich sitze hier vor dem Ausgedruckten! Und ich dachte, daß die frei wählbaren
Variablen nicht zu den Registern gehören. Rein aus Neugierde habe ich im
Quelltext das ,F weggelöscht (also incf SEKUNDEN_LOW) und dachte, der
Assembler zeigt eine Fehlermeldung... nichts da! Eigentlich hätte ich es doch
weder zum "W" Register noch zum "File Register deklariert .
Liege ich richtig?

wie so oft, gibt es auch hier eine sog. "Default"-Einstellung, die immer dann gewählt wird, wenn vom Benutzer keine explizite Angabe gemacht wird. In diesem Fall nimmt der Assembler als Standard als Ziel ",F" an, der Code bleibt also auch ohne ",F" im Quelltext im Ergebnis richtig. Allerdings ist das Weglassen der Zielangabe ",W" oder ",F"im Quelltext nicht zu empfehlen, da hierdurch leichter Fehler gemacht werden können. Deshalb gibt der Assembler im Output-Fenster ja auch die Warnmeldung aus, daß die Angabe der Zieladresse fehlt und als Default-Wert "F" genommen wurde. So bekommst Du zumindest einen Hinweis darauf, daß Du die Zielangabe evtl auch einfach vergessen haben könntest (es könnte ja auch ",W" beabsichtigt sein)!
Warnmeldungen sind zwar keine Fehlermeldungen, trotzdem ist es eine gute Idee, das Programm so zu schreiben, daß auch keine (oder nur wenige) Warnmeldungen im Output-Fenster auftauchen . Wenn Warnmeldungen da sind, sollte man zumindest überprüfen, ob die angemeckerte Programmstelle so in Ordnung ist.

Zitat


Der 16 Bit-Zähler wird mit SEKUNDEN_HIGH u. SEKUNDEN_LOW realisiert.
SEKUNDEN_LOW ist das niederwertige Byte = 8 Bit
SEKUNDEN_HIGH ist das höherwertige Byte = 8 Bit
Das mit dem Zählwerk ist eine gute Idee. Ich muß mir das aber noch dreimal
durchlesen. Von der Logik habe ich aber begriffen, warum der INCF Befehl
einmal durchgeführt werden muß.
Zum Schluß: Habe im Qelltext mal das _LOW gelöscht =113 Error
darauf 2x Klick und der Corser sprang direckt in die Fehlerzeile.

das sind ja nur symbolische Namen für die Register bzw. Speicherzellen. "_LOW" und "_HIGH" haben keine für den Assembler weitergehende Bedeutung, außer daß sie Teile des Namens sind - Du könntest die Variablen genauso auch mit "SEKUNDEN_HOEHERWERTIGESBYTE" und "SEKUNDEN_NIEDERWERTIGESBYTE" bennenen, aber mit "HIGH" und "LOW" ist es halt einfach kürzer und high/low sind sehr gebräuchlich, um die 8 Bit-Hälften von 16-bit Werten zu unterscheiden.

Zitat


Übrigens steht in meinem Buch, daß der Befehl "RETURN" nur für
PIC16CXX anwendbar sei, "RETLW" für alle anderen!
Thomas hat aber RETURN im Led.asm verwendet und es funktionierte, mh!

ja, schau mal ins - naja Du weisst schon... ;)
Da ist das Buch etwas zu pauschal! Mag sein, daß die ersten PIC12xxxx, die es gab, als das Buch geschrieben wurde, den RETURN-Befehl nicht kannten. Der PIC12F508 z.B. kennt den Befehl nicht, der 12F629 dagegen schon (im Zweifel halt immer im Datenblatt unter "Instruction Set" nachschauen). Du kannst auch einfach immer den RETLW-Befehl benutzen (den kennen alle PICs), aber damit ist es z.B. nicht möglich, im Unterprogramm berechnete Werte über das W-Register an das Hauptprogramm zurückzugeben, sondern nur Konstanten, die in der Befehlszeile hinter RETLW stehen.
Und es ist damit auch nicht möglich, Unterprogramme zu schreiben, die das W-Register nicht verändern.

Viele Grüße

Thomas