Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter fuer schwierige und grosse Gaerten im Test

(Beispiel)
K (Logiktabelle)
 
(20 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 75: Zeile 75:
 
Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.
 
Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.
  
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]
+
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]] und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]
  
 
== ANDWF ==
 
== ANDWF ==
Zeile 103: Zeile 103:
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
 
MOVWF 0x22  ;...und anschließend in den Register 0x22
 
MOVWF 0x22  ;...und anschließend in den Register 0x22
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister.  
+
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister.  
 
             ;Sieht Binär so aus: '10000100'
 
             ;Sieht Binär so aus: '10000100'
 
ANDWF 0x22,1 ;Führt die Logische Operation "AND" (UND)  
 
ANDWF 0x22,1 ;Führt die Logische Operation "AND" (UND)  
Zeile 114: Zeile 114:
 
Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.
 
Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.
  
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]
+
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]
  
 
== BCF ==
 
== BCF ==
Zeile 225: Zeile 225:
 
     ...
 
     ...
 
wait_until_set
 
wait_until_set
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?
+
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?
 
     goto wait_until_set    ;Nein. Springe zum Label "wait_until_set"
 
     goto wait_until_set    ;Nein. Springe zum Label "wait_until_set"
 
     ...                    ;Ja. Jetzt gehts erst weiter.
 
     ...                    ;Ja. Jetzt gehts erst weiter.
Zeile 413: Zeile 413:
 
| Alle Bits des Registers f werden invertiert (1 wird 0 und 0 wird 1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert.
 
| Alle Bits des Registers f werden invertiert (1 wird 0 und 0 wird 1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert.
 
|}
 
|}
 +
 +
===Beispiel===
 +
Wenn die LEDs am Ausgang des PICs einmal mal mehr als die ~20mA Verbrauchen, lohnt es sich sie gegen die Versorgungsspannung zu hängen. Der Nachteil dabei ist, dass nun bei einer logischen "1" nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:
 +
 +
<pre>
 +
...
 +
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.
 +
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar.
 +
</pre>
  
 
== DECF ==
 
== DECF ==
Zeile 568: Zeile 577:
 
...
 
...
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
IORWF 0xCC  ;Führt die Logische Operation "OR" oder auch "IOR" (Oder = Inclusives Oder)  
+
IORWF 0xCC  ;Führt die Logische Operation "AND" (UND)  
            ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22
+
          ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl
            ;Sieht Binär so aus: '10000110'
+
          ;wieder ins Arbeitsregister W.
            ;danach wieder in den in den Register 0x22 zurück.
+
          ;Nun steht im Arbeitsregister 0xCF ('11001111')
            ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')
+
 
...
 
...
 
</pre>
 
</pre>
Zeile 606: Zeile 614:
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
 
MOVLW 0x07  ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
 
MOVWF 0x22  ;...und anschließend in den Register 0x22
 
MOVWF 0x22  ;...und anschließend in den Register 0x22
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister.  
+
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister.  
 
             ;Sieht Binär so aus: '10000110'
 
             ;Sieht Binär so aus: '10000110'
 
IORWF 0x22,1 ;Führt die Logische Operation "OR" oder auch "IOR" (Oder = Inclusives Oder)  
 
IORWF 0x22,1 ;Führt die Logische Operation "OR" oder auch "IOR" (Oder = Inclusives Oder)  
Zeile 618: Zeile 626:
  
 
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]
 
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]
+
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]
  
 
== MOVF ==
 
== MOVF ==
Zeile 640: Zeile 648:
 
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das "in sich selber kopieren" hat den Sinn, zu überprüfen, ob das Register leer ist. Wenn dem nämlich so wäre, dann würde das Z-Bit gesetzt werden.
 
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das "in sich selber kopieren" hat den Sinn, zu überprüfen, ob das Register leer ist. Wenn dem nämlich so wäre, dann würde das Z-Bit gesetzt werden.
 
|}
 
|}
 +
 +
 +
====Beispiel====
 +
<pre>
 +
#Define DauerL 0x25  ;
 +
#Define DauerH 0x26  ;Registern namen geben..
 +
...         
 +
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten
 +
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren
 +
MOWF DauerL          ;...und im Vorgesehenen Register speichern.
 +
BCF STATUS,Z          ;Zeroflag löschen
 +
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren
 +
MOWF DauerH          ;...und im Vorgesehenen Register speichern.
 +
BTFSC STATUS,Z     
 +
goto messen          ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...
 +
...
 +
...
 +
</pre>
  
 
== MOVLW ==
 
== MOVLW ==
Zeile 661: Zeile 687:
 
|Die Zahl k wird in das Arbeitsregister geladen
 
|Die Zahl k wird in das Arbeitsregister geladen
 
|}
 
|}
 +
===Beispiel===
 +
<pre>
 +
MOVLW 0xC8  ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.
 +
MOVWF TMR0  ;TIP: Wenn man das TMR0 Register mit einem Wert füttert,
 +
            ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.
 +
</pre>
  
 
== MOVWF ==
 
== MOVWF ==
Zeile 703: Zeile 735:
 
| Ein Takt lang wird NICHTS gemacht.
 
| Ein Takt lang wird NICHTS gemacht.
 
|}
 
|}
 +
===Beispiel===
 +
Folgende Schleife würde nun ohne Timer oder ähnlichem einfach 10 Takte dauern. Vorallem dann sinnvoll, wenn im Vergleich zur Taktfrequenz hohe Frequenzen erzeugt werden müssen. Bei einem PIC mit z.B 4Mhz Takt würde folgende Schleife seehr seehr einfach ein Rechtecksignal mit 400kHz erzeugen. (4000kHz/10Takte)
 +
 +
<pre>
 +
...
 +
loop
 +
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an
 +
    NOP            ;1 Takt
 +
    NOP            ;1 Takt
 +
    NOP            ;1 Takt
 +
    NOP            ;1 Takt
 +
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an
 +
    NOP            ;1 Takt
 +
    NOP            ;1 Takt
 +
    GOTO loop      ;2 Takte
 +
...
 +
</pre>
  
 
== RETFIE ==
 
== RETFIE ==
Zeile 723: Zeile 772:
 
|-
 
|-
 
|Beschreibung:  
 
|Beschreibung:  
| Dieser Befehl steht am Ende der Interrupt Service Routine - aber auch NUR dort!!! Damit wird das Programm wieder an der Stelle fortgesetzt, wo es von einem Interrupt unterbrochen wurde.
+
| Dieser Befehl steht am Ende der Interrupt Service Routine - aber auch NUR dort!!! Damit wird das Programm wieder an der Stelle fortgesetzt, wo es von einem Interrupt unterbrochen wurde. Weiters ist zu  erwähnen, dass das GIE-Bit des INTCON-Registers, was alle Interrupts ein- und ausschaltet wieder gesetzt wird.
 
|}
 
|}
  
Zeile 943: Zeile 992:
 
|-
 
|-
 
|Beschreibung:  
 
|Beschreibung:  
|Der Inhalt des W Registers wird mit dem Register f exklusiv erodert und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)
+
|Der Inhalt des W Registers wird mit dem Register f exklusiv verodert und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)
 
|}
 
|}
  
= Pseudo Befehle =
+
====Beispiel====
 +
<pre>
 +
...
 +
MOVLW 0x0F  ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...
 +
MOVWF 0x22  ;...und anschließend in den Register 0x22
 +
MOVLW 0x86  ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister.
 +
            ;Sieht Binär so aus: '10000110'
 +
XORWF 0x22,1 ;Führt die Logische Operation "XOR" (exclusives Oder)
 +
            ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22
 +
            ;durch und ladet die Zahl
 +
            ;danach wieder in den in den Register 0x22 zurück.
 +
            ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')
 +
...
 +
</pre>
 +
Was ist in dem Beispiel Passiert? Wenn man sich unsere Zahl 0x0F als Maske vorstellt, dann sind überall dort wo in der binären Schreibweise 1ser waren, ist immer nachher der inverse Wert von unserer Zahl im Arbeitsregister gewesen. Bei den Stellen wo in der Maske eine 0 war, hat sich nichts geändert. D.h. mit dieser Operation kann man einfach Stellen in einem Byte gezielt invertieren.
 +
 
 +
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]
 +
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORLW|XORLW]]
 +
 
 +
= Compilerdirektiven =
  
Pseudobefehle werden je nach Compiler unterstützt. (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms angeben oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.
+
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Aber alle die hier aufgeführt werden, werden vom Compiler MPASM (Im MPLAB integriert) unterstützt. Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.
  
 
== #Define ==  
 
== #Define ==  
Zeile 1.046: Zeile 1.114:
 
|0
 
|0
 
|0
 
|0
|1
+
|0
 
|0
 
|0
 
|}
 
|}

Aktuelle Version vom 8. September 2007, 18:22 Uhr

Assembler Befehle

ADDLW

ADDLW ADD Zahl und W
Syntax: ADDLW k
Operanten: 0 ≤ k ≤ 255
Operation: (W) + k → (W)
Beeinflusste Statusbits: C, DC, Z
Beschreibung: Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register

ADDWF

ADDWF ADD W und f
Syntax: ADDWF f,d
Operanten: 0 ≤ f ≤ 127 und d ∈ [0,1]
Operation: (W) + (f) → (destination)
Beeinflusste Statusbits: C, DC, Z
Beschreibung: Der Inhalt des W Registers wird mit dem Register f addiert und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)

ANDLW

ANDLW AND Zahl mit W
Syntax: ANDLW k
Operanten: 0 ≤ k ≤ 255
Operation: (W) + k → (W)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register

Beispiel

...
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. 
           ;Sieht Binär so aus: '11001100'
ANDLW 0xF0 ;Führt die Logische Operation "AND" (UND) 
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl 
           ;wieder ins Arbeitsregister W.
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')
...

Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.

siehe Logiktabelle und IORWF,IORLW,ANDWF,XORWF,XORLW

ANDWF

ANDWF AND W mit f
Syntax: ANDWF f,d
Operanten: 0 ≤ f ≤ 127 und d ∈ [0,1]
Operation: (W) .AND. (f) → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des W Registers wird mit dem Register f verundet und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)

Beispiel

...
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
MOVWF 0x22   ;...und anschließend in den Register 0x22
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. 
             ;Sieht Binär so aus: '10000100'
ANDWF 0x22,1 ;Führt die Logische Operation "AND" (UND) 
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 
             ;durch und ladet die Zahl 
             ;danach wieder in den in den Register 0x22 zurück.
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')
...

Mit der Logischen Operation "AND" lässt sich sehr schön ein Teil eines Bytes auf 0 setzen. Und zwar werden alle Teile auf 0 gesetzt, wo eine 0 im 2.Byte steht, dort wo eine 1 stand, bleibt alles erhalten.

siehe Logiktabelleund IORWF,IORLW,ANDLW,XORWF,XORLW

BCF

BCF Bit Clear f
Syntax: BCF f,b
Operanten: 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7
Operation: 0 → (f)
Beeinflusste Statusbits: /
Beschreibung: Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt

Beispiel

...
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -> Wechsel auf Bank1
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -> Wechsel auf Bank0
...

Setzt ganz einfach ein Bit eines Registers auf 1. Dabei kann man die Stelle im Register als Zahl angeben, oder aber auch den Namen, wenn man die Stelle nicht weis und sofern das Bit einen hat.

BSF

BSF Bit Set f
Syntax: BSF f,b
Operanten: 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7
Operation: 0 → (f<b>)
Beeinflusste Statusbits: /
Beschreibung: Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt

Beispiel

...
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -> Wechsel auf Bank1
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -> Wechsel auf Bank0
...

Setzt ganz einfach ein Bit eines Registers auf 0. Dabei kann man die Stelle im Register als Zahl angeben, oder aber auch den Namen, wenn man die Stelle nicht weis und sofern das Bit einen hat.

BTFSC

BTFSC Bit Test f, Skip if Clear
Syntax: BTFSC f,b
Operanten: 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7
Operation: skip if (f<b>) = 0
Beeinflusste Statusbits: /
Beschreibung: Wenn das Bit b im Register f 0 ist, dann wird der nachfolgende Befehl nicht und stattdessen ein NOP ausgeführt. Wenn das Bit b 1 ist, dann wird der nächste Befehl ausgeführt.

Beispiel

Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1. Siehe BTFSS

BTFSS

BTFSS Bit Test f, Skip if Set
Syntax: BTFSS f,b
Operanten: 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7
Operation: skip if (f<b>) = 1
Beeinflusste Statusbits: /
Beschreibung: Wenn das Bit b im Register f 1 ist, dann wird der nachfolgende Befehl nicht und stattdessen ein NOP ausgeführt. Wenn das Bit b 0 ist, dann wird der nächste Befehl ausgeführt.

Beispiel

     ...
wait_until_set
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?
     goto wait_until_set     ;Nein. Springe zum Label "wait_until_set"
     ...                     ;Ja. Jetzt gehts erst weiter.

Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu "toggeln" (1 wird 0 und 0 wird 1):

     ...
     ;FALSCH:
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)
     ...                     ;Fehler in der Denkweise: 
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - 
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST
                             ;geh einfach weiter (und mach beide)!!!
     ...
     ;RICHTIG:
     ;2xFragen
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?
     BSF   0x23,2            ;Nein. Dann setzen wir es...
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?
     BCF   0x23,2            ;Nein. Dann setzen wir es...
     ...
     ...
     ;oder Blöcke für mehrere Befehle
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke "ist_nicht_eins
     ...                     ;Ja, hier weitermachen...
     ...
     goto weitermachen       ;Anderen Block "überspringen"
ist_nicht_eins
     ...                     ;Hier wird der Fall abgehandelt,
     ...                     ;falls das Ergebnis nicht eins war.
weitermachen
     ...

CALL

CALL Call Subroutine
Syntax: CALL k
Operanten: 0 ≤ k ≤ 2047
Operation: (PC) + 1 → TOS,

k → PC<10:0>, (PCLATH<4:3>) → PC<12:11>

Beeinflusste Statusbits: /
Beschreibung: Als erstes wird die Rückkehradresse (PC+1) in den Stack geschrieben. Dann Die 11bit Sprungadresse in den PC geladen (die 2 MSB kommen aus dem PCLATH).

Beispiel

    ...
    BSF STATUS,RP0
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren
    BCF STATUS,RP0

    call toggle_LED    ;Rufe die Subroutine "toggle_LED" auf
    ...
    ...
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.
    ...
    ...
    ...
loop                   ;Endlossschleife verhindert, 
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. 

toggle_LED             ;Jedes Mal wenn, "CALL toggle_LED" ausgeführt wird, 
                       ;landet das Programm hier.
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. 
    BSF   PORTB,3      ;Siehe BTFSS
    BTFSC PORTB,3
    BCF   PORTB,3
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.

Wichtig an der Stelle ist es auch, den Befehl "RETLW" zu erwähnen. Eigentlich hat er die selbe Funktion wie "RETURN", nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.

CLRF

CLRF Clear f
Syntax: CLRF f
Operanten: 0 ≤ f ≤ 127
Operation: 00h → (f),

1 → Z

Beeinflusste Statusbits: Z
Beschreibung: Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.

Beispiel

  ...
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0
              ;und setzt ihn damit wieder an den Anfang.
  ...

Man könnte auch zuerst den Wert 0x00 in das Arbeitsregister laden und dann von dort in den Register seiner Wahl, nur mit dem Unterschied, dass mit der (längeren) Methode das Zeroflag "Z" nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.

CLRW

CLRW Clear W
Syntax: CLRW
Operanten: /
Operation: 00h → (W),

1 → Z

Beeinflusste Statusbits: Z
Beschreibung: Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.

CLRWDT

CLRWDT Clear Watchdog Timer
Syntax: CLRWDT
Operanten: /
Operation: 00h → WDT,

0 → WDT prescaler, 1 → TO, 1 → PD

Beeinflusste Statusbits: TO, PD
Beschreibung: Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.

COMF

COMF Complement f
Syntax: COMF f,d
Operanten: 0 ≤ f ≤ 127 und

d ∈ [0,1]

Operation: (f) → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Alle Bits des Registers f werden invertiert (1 wird 0 und 0 wird 1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert.

Beispiel

Wenn die LEDs am Ausgang des PICs einmal mal mehr als die ~20mA Verbrauchen, lohnt es sich sie gegen die Versorgungsspannung zu hängen. Der Nachteil dabei ist, dass nun bei einer logischen "1" nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:

...
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. 

DECF

DECF Decrement f
Syntax: DECF f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: (f) – 1 → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Das Register f wird decrementiert (f=f-1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert.

Beispiel

    ...
    MOVLW 0x01
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt
    DECF  0x20,1 ;und nun 0xFF (überlauf!)
    ...

DECFSZ

DECFSZ Decrement f, skip if 0
Syntax: DECFSZ f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: (f) – 1 → (destination), skip if result = 0
Beeinflusste Statusbits: Z
Beschreibung: Das Register f wird decrementiert (f=f-1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert. Danach wird überprüft, ob das Ergebnis 0 war. Wenn ja, dann wird an Stelle des nächsten Befehls ein NOP durchgeführt.

GOTO

GOTO uncontitional Branch
Syntax: GOTO k
Operanten: 0 ≤ k ≤ 2047
Operation: k → PC<10:0>,

PCLATH<4:3> → PC<12:11>

Beeinflusste Statusbits: /
Beschreibung: Goto veranlasst einen Sprung an die Adresse k im Programmspeicher. Es werden aber nur die 11 niedrigstens Bit der Adresse mit GOTO bestimmt, die beiden höchsten werden aus dem Register PCLATH geladen.

INCF

INCF Increment f
Syntax: INCF f,d
Operanten: 0 ≤ f ≤ 127,

d ∈ [0,1]

Operation: (f) + 1 → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Das Register f wird incrementiert (f=f+1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert.

Beispiel

    ...
    MOVLW 0xFE
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20
    INCF  0x20,1 ;nun steht 0xFF im Register
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt
    ...

INCFSZ

INCFSZ Increment f, skip if 0
Syntax: INCFSZ f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: (f) + 1 → (destination), skip if result = 0
Beeinflusste Statusbits: Z
Beschreibung: Das Register f wird incrementiert (f=f-1) und das Ergebnis entweder in den Arbeitsregister W (d=0) oder wieder in das Register f (d=1) gespeichert. Danach wird überprüft, ob das Ergebnis 0 war. Wenn ja, dann wird an Stelle des nächsten Befehls ein NOP durchgeführt.

IORLW

IORLW Inclusive OR Literal with W
Syntax: IORLW k
Operanten: 0 ≤ k ≤ 255
Operation: (W) .OR. k → (W)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register

Beispiel

...
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
IORWF 0xCC   ;Führt die Logische Operation "AND" (UND) 
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl 
           ;wieder ins Arbeitsregister W.
           ;Nun steht im Arbeitsregister 0xCF ('11001111')
...

Was ist in dem Beispiel Passiert? Wenn man sich unsere Zahl 0x86 als Maske vorstellt, dann sind überall dort wo in der binären Schreibweise 1ser waren, immer nach der Operation 1ser gestanden, egal ob da vorher eine 1 oder eine 0 war. Bei den Stellen wo in der Maske eine 0 war, hat sich nichts geändert. D.h. mit dieser Operation kann man einfach Stellen in einem Byte gezielt setzen.

siehe auch Logiktabelle und IORWF,ANDWF,ANDLW,XORWF,XORLW

IORWF

IORWF Inclusive OR W und f
Syntax: IORWF f,d
Operanten: 0 ≤ f ≤ 127 und d ∈ [0,1]
Operation: (W) .OR. (f) → (destination)
Beeinflusste Statusbits: C, DC, Z
Beschreibung: Der Inhalt des W Registers wird mit dem Register f verodert und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)

Beispiel

...
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...
MOVWF 0x22   ;...und anschließend in den Register 0x22
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. 
             ;Sieht Binär so aus: '10000110'
IORWF 0x22,1 ;Führt die Logische Operation "OR" oder auch "IOR" (Oder = Inclusives Oder) 
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 
             ;durch und ladet die Zahl 
             ;danach wieder in den in den Register 0x22 zurück.
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')
...

Was ist in dem Beispiel Passiert? Wenn man sich unsere Zahl 0x86 als Maske vorstellt, dann sind überall dort wo in der binären Schreibweise 1ser waren, immer nach der Operation 1ser gestanden, egal ob da vorher eine 1 oder eine 0 war. Bei den Stellen wo in der Maske eine 0 war, hat sich nichts geändert. D.h. mit dieser Operation kann man einfach Stellen in einem Byte gezielt setzen.

siehe auch Logiktabelle und IORLW,ANDWF,ANDLW,XORWF,XORLW

MOVF

MOVF Move f
Syntax: MOVF f,d
Operanten: 0 ≤ f ≤ 127 und d ∈ [0,1]
Operation: (W) + (f) → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das "in sich selber kopieren" hat den Sinn, zu überprüfen, ob das Register leer ist. Wenn dem nämlich so wäre, dann würde das Z-Bit gesetzt werden.


Beispiel

#Define DauerL 0x25   ;
#Define DauerH 0x26   ;Registern namen geben..
...          
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren
MOWF DauerL           ;...und im Vorgesehenen Register speichern.
BCF STATUS,Z          ;Zeroflag löschen
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren
MOWF DauerH           ;...und im Vorgesehenen Register speichern.
BTFSC STATUS,Z      
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...
...
...

MOVLW

MOVLW Move Literal to W
Syntax: MOVLW k
Operanten: 0 ≤ k ≤ 255
Operation: k → (W)
Beeinflusste Statusbits: /
Beschreibung: Die Zahl k wird in das Arbeitsregister geladen

Beispiel

MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, 
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.

MOVWF

MOVWF Move W to f
Syntax: MOVWF f
Operanten: 0 ≤ f ≤ 127
Operation: (W) → (f)
Beeinflusste Statusbits: /
Beschreibung: Das Arbeitsregister W wird in das Register f geladen

NOP

NOP No Operation
Syntax: NOP
Operanten: /
Operation: /
Beeinflusste Statusbits: /
Beschreibung: Ein Takt lang wird NICHTS gemacht.

Beispiel

Folgende Schleife würde nun ohne Timer oder ähnlichem einfach 10 Takte dauern. Vorallem dann sinnvoll, wenn im Vergleich zur Taktfrequenz hohe Frequenzen erzeugt werden müssen. Bei einem PIC mit z.B 4Mhz Takt würde folgende Schleife seehr seehr einfach ein Rechtecksignal mit 400kHz erzeugen. (4000kHz/10Takte)

...
loop
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an
    NOP            ;1 Takt
    NOP            ;1 Takt
    NOP            ;1 Takt
    NOP            ;1 Takt
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an
    NOP            ;1 Takt
    NOP            ;1 Takt
    GOTO loop      ;2 Takte
...

RETFIE

RETFIE Return from Interrupt
Syntax: RETFIE
Operanten: /
Operation: TOS → PC,

1 → GIE

Beeinflusste Statusbits: /
Beschreibung: Dieser Befehl steht am Ende der Interrupt Service Routine - aber auch NUR dort!!! Damit wird das Programm wieder an der Stelle fortgesetzt, wo es von einem Interrupt unterbrochen wurde. Weiters ist zu erwähnen, dass das GIE-Bit des INTCON-Registers, was alle Interrupts ein- und ausschaltet wieder gesetzt wird.

RETLW

RETLW Return with Literal in W
Syntax: RETLW k
Operanten: 0 ≤ k ≤ 255
Operation: k → (W);

TOS → PC

Beeinflusste Statusbits: /
Beschreibung: Der Wert k wird in das W Register geschrieben, dann die Returnadresse aus dem Stack geholt und in den PC geladen. Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.

RETURN

RETURN Return from Subroutine
Syntax: RETURN
Operanten: /
Operation: TOS → PC
Beeinflusste Statusbits: /
Beschreibung: Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.

RLF

RLF Rotate Left f through Carry
Syntax: RLF f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: siehe unten
Beeinflusste Statusbits: /
Beschreibung: Das Register F wird links rum über das Carryflag "rotiert". D.h. das MSB landet im Carryflag und das Carryflag landet im LSB. Das Ergebnis landet entweder im Arbeitsregister W (d=0) oder wieder im Register f (d=1).

RRF

RRF Rotate Right f through Carry
Syntax: RRF f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: siehe unten
Beeinflusste Statusbits: /
Beschreibung: Das Register F wird rechts rum über das Carryflag "rotiert". D.h. das Carryflag landet im MSB und das LSB landet im Carryflag. Das Ergebnis landet entweder im Arbeitsregister W (d=0) oder wieder im Register f (d=1).


SLEEP

SLEEP Sleep
Syntax: SLEEP
Operanten: /
Operation: 00h → WDT,

0 → WDT prescaler, 1 → TO, 0 → PD

Beeinflusste Statusbits: TO, PD
Beschreibung: Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor "schlafen" geschickt und der Oszillator angehalten.

SUBLW

SUBLW Subtract W from Literal
Syntax: SUBLW k
Operanten: 0 ≤ k ≤ 255
Operation: k – (W) → (W)
Beeinflusste Statusbits: C, DC, Z
Beschreibung: Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.

SUBWF

SUBWF Subtract W from f
Syntax: SUBWF f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: (f) – (W) → (destination)
Beeinflusste Statusbits: C, DC, Z
Beschreibung: Das Arbeitsregister W wird vom Register f Subtrahiert und das Ergebnis wird entweder im Arbeitsregister W (d=0) oder dem Register f (d=1) gespeichert.

SWAP

SWAP Swap Nibbles in f
Syntax: SWAP f,d
Operanten: 0 ≤ f ≤ 127

d ∈ [0,1]

Operation: (f<3:0>) → (destination<7:4>),

(f<7:4>) → (destination<3:0>)

Beeinflusste Statusbits: /
Beschreibung: Das obere und das untere Nibble des Registers f werden vertauscht. Das Ergebnis wird entweder im Arbeitsregister W (d=0) oder dem Register f (d=1) gespeichert.

XORLW

XORLW Exclusive OR Literal with W
Syntax: XORLW k
Operanten: 0 ≤ k ≤ 255
Operation: (W) .XOR. k → (W)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register

XORWF

XORWF Exclusive OR W und f
Syntax: XORWF f,d
Operanten: 0 ≤ f ≤ 127 und d ∈ [0,1]
Operation: (W) .OR. (f) → (destination)
Beeinflusste Statusbits: Z
Beschreibung: Der Inhalt des W Registers wird mit dem Register f exklusiv verodert und das Ergebnis landet entweder im W Register (d=0) oder im Register f (d=1)

Beispiel

...
MOVLW 0x0F   ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...
MOVWF 0x22   ;...und anschließend in den Register 0x22
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. 
             ;Sieht Binär so aus: '10000110'
XORWF 0x22,1 ;Führt die Logische Operation "XOR" (exclusives Oder) 
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 
             ;durch und ladet die Zahl 
             ;danach wieder in den in den Register 0x22 zurück.
             ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')
...

Was ist in dem Beispiel Passiert? Wenn man sich unsere Zahl 0x0F als Maske vorstellt, dann sind überall dort wo in der binären Schreibweise 1ser waren, ist immer nachher der inverse Wert von unserer Zahl im Arbeitsregister gewesen. Bei den Stellen wo in der Maske eine 0 war, hat sich nichts geändert. D.h. mit dieser Operation kann man einfach Stellen in einem Byte gezielt invertieren.

siehe auch Logiktabelle und IORLW,IORWF,ANDWF,ANDLW,XORLW

Compilerdirektiven

Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Aber alle die hier aufgeführt werden, werden vom Compiler MPASM (Im MPLAB integriert) unterstützt. Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.

#Define

#Define
Syntax: #Define name string
Beschreibung: Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem definierten String.

END

END
Syntax: END
Beschreibung: Sollte am Ende jedes Programmes stehen, um dem Compiler zu sagen, dass das Programm hier zu Ende ist. Ohne diesem Befehl (sollte) es auch keine Schwierigkeiten geben.

EQU

EQU
Syntax: name EQU expr
Beschreibung: Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen.

ORG

ORG
Syntax: ORG expr
Beschreibung: Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.

Logiktabelle

A B AND OR NAND NOR XOR XAND
0 0 0 0 1 1 0 1
0 1 0 1 1 0 1 0
1 0 0 1 1 0 1 0
1 1 1 1 0 0 0 0

LiFePO4 Speicher Test