<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Der+G%C3%A4rtner</id>
		<title>RN-Wissen.de - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Der+G%C3%A4rtner"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Der_G%C3%A4rtner"/>
		<updated>2026-04-12T01:23:54Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11341</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11341"/>
				<updated>2007-04-15T11:19:51Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Compilerdirektiven */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x0F   ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
XORWF 0x22,1 ;Führt die Logische Operation &amp;quot;XOR&amp;quot; (exclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11340</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11340"/>
				<updated>2007-04-15T11:18:43Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* XORWF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x0F   ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
XORWF 0x22,1 ;Führt die Logische Operation &amp;quot;XOR&amp;quot; (exclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11339</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11339"/>
				<updated>2007-04-15T11:17:26Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x0F   ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
XORWF 0x22,1 ;Führt die Logische Operation &amp;quot;XOR&amp;quot; (exclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11338</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11338"/>
				<updated>2007-04-15T11:17:05Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* XORWF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x0F   ;Ladet die Zahl 0x0F ('00001111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x86   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
XORWF 0x22,1 ;Führt die Logische Operation &amp;quot;XOR&amp;quot; (exclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x89 ('10001001')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11309</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11309"/>
				<updated>2007-04-13T19:37:06Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* COMF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11308</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11308"/>
				<updated>2007-04-13T19:36:50Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* COMF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 &amp;quot;1&amp;quot; nun die Led aus wäre und umgekehrt. Um sie wieder bei einer 1 leuchten zu lassen, gibt es folgende Möglichkeit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
COMF,0 TMR1H  ;Ladet das Hightbyte des Timer1 INVERTIERT in das Arbeitsregister.&lt;br /&gt;
MOVWF  PORTB  ;und nun ists auf den LEDs sichtbar. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11307</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11307"/>
				<updated>2007-04-13T19:27:28Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11306</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11306"/>
				<updated>2007-04-13T19:25:44Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* NOP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
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 ein Rechtecksignal mit 400kHz erzeugen. (4000kHz/10Takte)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
loop&lt;br /&gt;
    BSF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    BCF PORTB,0    ;1 Takt //z.b. LED an dem Port an&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    NOP            ;1 Takt&lt;br /&gt;
    GOTO loop      ;2 Takte&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11305</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11305"/>
				<updated>2007-04-13T19:18:26Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* MOVLW */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
===Beispiel===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MOVLW 0xC8   ;Das Arbeitsregister hat nun den Wert C8. Das was vorher drinstand ist WEG.&lt;br /&gt;
MOVWF TMR0   ;TIP: Wenn man das TMR0 Register mit einem Wert füttert, &lt;br /&gt;
             ;dann kann man die Laufzeit bis zum nächsten Überlauf festlegen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11304</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11304"/>
				<updated>2007-04-13T19:12:42Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* MOVF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,0           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#Define DauerL 0x25   ;&lt;br /&gt;
#Define DauerH 0x26   ;Registern namen geben..&lt;br /&gt;
...          &lt;br /&gt;
BCF T1CON,TMR1ON      ;Timer 1 Ausschalten&lt;br /&gt;
MOVF TMR1L,0          ;Timer1 LowByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerL           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BCF STATUS,Z          ;Zeroflag löschen&lt;br /&gt;
MOVF TMR1H,0          ;Timer1 HighByte ins Arbeitsregister kopieren&lt;br /&gt;
MOWF DauerH           ;...und im Vorgesehenen Register speichern.&lt;br /&gt;
BTFSC STATUS,Z      &lt;br /&gt;
goto messen           ;Das Ergebnis war 0!!! Da muss nochmal gemessen werden, war zu kurz...&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11293</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11293"/>
				<updated>2007-04-13T08:45:03Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem (d) nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende. Für die Zahlen 0 bis 9 sind die (h) und&lt;br /&gt;
(d) Zeichen nicht nötig, da sie beide gleich den entsprechenden bin Zahlen sind.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin, hex und dec Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h = 0d      100b = 4h = 4d     1000b = 8h = 8d     1100b = Ch = 12d&lt;br /&gt;
             1b = 1h = 1d      101b = 5h = 5d     1001b = 9h = 9d     1101b = Dh = 13d&lt;br /&gt;
            10b = 2h = 2d      110b = 6h = 6d     1010b = Ah = 10d    1110b = Eh = 14d&lt;br /&gt;
            11b = 3h = 3d      111b = 7h = 8d     1011b = Bh = 11d    1111b = Fh = 15d&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (LP,HS oder XT) &lt;br /&gt;
* Keramik-Resonator mit integrierten Kondensatoren (HS oder XT)&lt;br /&gt;
* Quarzoszillator (EC); genau und stabil&lt;br /&gt;
* Widerstand + Kondensator (RC); keine hohe Frequenzstabilität&lt;br /&gt;
&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 7:&lt;br /&gt;
&lt;br /&gt;
                      movlw   7                b.z.w.           movlw   7             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP Init (Initialisierung) auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x38		; definiere Portpins GPIO, (z.B. 0-2 Aus- und 3-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache GPIO 0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Eine ausgegliederte Beschreibung der Befehle findet sich unter [[PIC Assemblerbefehle]]&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
====Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers====&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Diese Special Funktion Register liegen ALLE in Bank0 und Bank2(Falls vorhanden).&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Bei Port B kann man bei allen Pins einen internen PULL-UP Widerstand mit dem Bit OPTION_REG&amp;lt;RBPU&amp;gt; hinzuschalten (Standardmäßig auf nicht aktiviert, Bit muss gelöscht werden um die Funktion zu aktivieren). Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]]. Bei den &amp;quot;kleinsten&amp;quot; PICs der 12F Serie die nur einen I/O Port (6 Pins) haben, heisst der PORT-Register GPIO.&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TRISx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''TRISx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;TRISB&amp;quot; oder &amp;quot;TRISA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Bei den &amp;quot;kleinsten&amp;quot; PICs der 12F Serie die nur einen I/O Port (6 Pins) haben, heisst der TRIS-Register TRISIO.&lt;br /&gt;
&lt;br /&gt;
Die TRIS-Bytes dienen dazu, einzelne I/O Pins als Eingang oder Ausgang zu definieren. Sie liegen immer genau eine Bank über den jeweiligen PORT-Bytes, d.h. sie liegen alle in Bank1 und Bank3(falls vorhanden.) Besonders zu beachten ist, dass manche Eingebaute Features wie die Serielle Schnittstelle, I2C, SPI usw nicht funktionieren, wenn die Jeweiligen Sende und Empfangspins nicht nicht manuell umgestellt werden, ja es ''muss'' sogar manchmal umgestellt werden (bei I2C z.B.) Egal ist dies jedoch für Komperatoren und AD-Wandler.&lt;br /&gt;
&lt;br /&gt;
Merke:&lt;br /&gt;
* Eine 1 (als &amp;quot;I&amp;quot; für &amp;quot;Input&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Eingang.&lt;br /&gt;
* Eine 0 (als &amp;quot;O&amp;quot; für &amp;quot;Output&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Ausgang.&lt;br /&gt;
&lt;br /&gt;
Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11290</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11290"/>
				<updated>2007-04-13T08:38:13Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* vorgeschlagene Gliederung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Ich würde die Register ANSEL und TIMER nicht speziell und so alleine beschreiben. Die gehören entweder zu den ADCs oder zu den einzelnen Timern. &amp;quot;ANSEL&amp;quot; ist z.b. einer von mind. 4 Registern, die von den ADCs benutzt werden. das Selbe gilt für Timer (stichwort TMR0-2 unterschiedliche Architektur/CCPM/PWM...)&lt;br /&gt;
&lt;br /&gt;
@PICture: passt sehr gut, man sieht ich hab die Matura, aber auch, dass ich NICHT in Deutsch maturiert habe - da fehlts an Retorik, Grammatik und Einfühlungsvermögen für nichteingeweihte beim schreiben ;)&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 22:48, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Kleine Frage am Rande, alle Pins an allen Ports der Midrangeserie sind BIDIREKTIONAL - oder...? Ich bin über einen 18F gestolpert, der da aus der Reihe tanzt. (4550er, die USB-Pins...)--[[Benutzer:Der Gärtner|Der Gärtner]] 22:53, 12. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Nobody is perfect&amp;quot;. Beim jedem Lesen des Artikels finde ich Fehler die ich bisher übersehen habe.&lt;br /&gt;
&lt;br /&gt;
Wenn es um Mid-Range PICs geht, da sind alle Pins an allen Ports bidirektional. Aber bei fast allen diesen PICs gibt es ein Portpin, der nur open drain ist (z.B. beim 12F629 GPIO,3) und ohne pull-up keine 1 ausgeben kann. Übrigens, was sind &amp;quot;Fusebits&amp;quot; ? Ich (und wahrscheinlich jeder Anfänger auch) habe noch nicht gehört. Ich vermute, dass sich hier um &amp;quot;configuration bits&amp;quot; handelt, es müsste aber irgendwo in unserem Artikel definiert werden. Vielleicht am Ende des Artikels machen wir noch ein &amp;quot;Wörterbuch&amp;quot; für Anfänger ? &lt;br /&gt;
&lt;br /&gt;
Ich freue mich sehr, dass immer mehr Autoren des Artikels gibt. Der nächste, aber fast sicher nicht der letzte, ist der BMS, der gerade ein Codeschnipsel für ADC schreibt. Je mehr Autoren um so besser. Die vorgeschlagene Gliederung ist noch offen und kann jederzeit von jedem geändert werden (z.B. bei der Registerbeschreibung) [[Benutzer:PICture|PICture]] 07:50, 13. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11289</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11289"/>
				<updated>2007-04-13T08:36:47Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* vorgeschlagene Gliederung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
**** PIC-Wörterbuch&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Ich würde die Register ANSEL und TIMER nicht speziell und so alleine beschreiben. Die gehören entweder zu den ADCs oder zu den einzelnen Timern. &amp;quot;ANSEL&amp;quot; ist z.b. einer von mind. 4 Registern, die von den ADCs benutzt werden. das Selbe gilt für Timer (stichwort TMR0-2 unterschiedliche Architektur/CCPM/PWM...)&lt;br /&gt;
&lt;br /&gt;
@PICture: passt sehr gut, man sieht ich hab die Matura, aber auch, dass ich NICHT in Deutsch maturiert habe - da fehlts an Retorik, Grammatik und Einfühlungsvermögen für nichteingeweihte beim schreiben ;)&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 22:48, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Kleine Frage am Rande, alle Pins an allen Ports der Midrangeserie sind BIDIREKTIONAL - oder...? Ich bin über einen 18F gestolpert, der da aus der Reihe tanzt. (4550er, die USB-Pins...)--[[Benutzer:Der Gärtner|Der Gärtner]] 22:53, 12. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Nobody is perfect&amp;quot;. Beim jedem Lesen des Artikels finde ich Fehler die ich bisher übersehen habe.&lt;br /&gt;
&lt;br /&gt;
Wenn es um Mid-Range PICs geht, da sind alle Pins an allen Ports bidirektional. Aber bei fast allen diesen PICs gibt es ein Portpin, der nur open drain ist (z.B. beim 12F629 GPIO,3) und ohne pull-up keine 1 ausgeben kann. Übrigens, was sind &amp;quot;Fusebits&amp;quot; ? Ich (und wahrscheinlich jeder Anfänger auch) habe noch nicht gehört. Ich vermute, dass sich hier um &amp;quot;configuration bits&amp;quot; handelt, es müsste aber irgendwo in unserem Artikel definiert werden. Vielleicht am Ende des Artikels machen wir noch ein &amp;quot;Wörterbuch&amp;quot; für Anfänger ? &lt;br /&gt;
&lt;br /&gt;
Ich freue mich sehr, dass immer mehr Autoren des Artikels gibt. Der nächste, aber fast sicher nicht der letzte, ist der BMS, der gerade ein Codeschnipsel für ADC schreibt. Je mehr Autoren um so besser. Die vorgeschlagene Gliederung ist noch offen und kann jederzeit von jedem geändert werden (z.B. bei der Registerbeschreibung) [[Benutzer:PICture|PICture]] 07:50, 13. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11268</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11268"/>
				<updated>2007-04-12T20:53:48Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Allgemeines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** ANSEL&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** TIMER&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Ich würde die Register ANSEL und TIMER nicht speziell und so alleine beschreiben. Die gehören entweder zu den ADCs oder zu den einzelnen Timern. &amp;quot;ANSEL&amp;quot; ist z.b. einer von mind. 4 Registern, die von den ADCs benutzt werden. das Selbe gilt für Timer (stichwort TMR0-2 unterschiedliche Architektur/CCPM/PWM...)&lt;br /&gt;
&lt;br /&gt;
@PICture: passt sehr gut, man sieht ich hab die Matura, aber auch, dass ich NICHT in Deutsch maturiert habe - da fehlts an Retorik, Grammatik und Einfühlungsvermögen für nichteingeweihte beim schreiben ;)&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 22:48, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Kleine Frage am Rande, alle Pins an allen Ports der Midrangeserie sind BIDIREKTIONAL - oder...? Ich bin über einen 18F gestolpert, der da aus der Reihe tanzt. (4550er, die USB-Pins...)--[[Benutzer:Der Gärtner|Der Gärtner]] 22:53, 12. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11267</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11267"/>
				<updated>2007-04-12T20:50:47Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Ausführliche Beschreibung zu den Befehlen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Eine ausgegliederte Beschreibung der Befehle findet sich unter [[PIC Assemblerbefehle]]&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Diese Special Funktion Register liegen ALLE in Bank0 und Bank2(Falls vorhanden).&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TRISx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''TRISx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;TRISB&amp;quot; oder &amp;quot;TRISA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die TRIS-Bytes dienen dazu, einzelne I/O Pins als Eingang oder Ausgang zu definieren. Sie liegen immer genau eine Bank über den jeweiligen PORT-Bytes, d.h. sie liegen alle in Bank1 und Bank3(falls vorhanden.) Besonders zu beachten ist, dass manche Eingebaute Features wie die Serielle Schnittstelle, I2C, SPI usw nicht funktionieren, wenn die Jeweiligen Sende und Empfangspins nicht nicht manuell umgestellt werden, ja es ''muss'' sogar manchmal umgestellt werden (bei I2C z.B.) Egal ist dies jedoch für Komperatoren und AD-Wandler.&lt;br /&gt;
&lt;br /&gt;
Merke:&lt;br /&gt;
* Eine 1 (als &amp;quot;I&amp;quot; für &amp;quot;Input&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Eingang.&lt;br /&gt;
* Eine 0 (als &amp;quot;O&amp;quot; für &amp;quot;Output&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Ausgang.&lt;br /&gt;
&lt;br /&gt;
Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11266</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11266"/>
				<updated>2007-04-12T20:48:36Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Allgemeines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** ANSEL&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** TIMER&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Ich würde die Register ANSEL und TIMER nicht speziell und so alleine beschreiben. Die gehören entweder zu den ADCs oder zu den einzelnen Timern. &amp;quot;ANSEL&amp;quot; ist z.b. einer von mind. 4 Registern, die von den ADCs benutzt werden. das Selbe gilt für Timer (stichwort TMR0-2 unterschiedliche Architektur/CCPM/PWM...)&lt;br /&gt;
&lt;br /&gt;
@PICture: passt sehr gut, man sieht ich hab die Matura, aber auch, dass ich NICHT in Deutsch maturiert habe - da fehlts an Retorik, Grammatik und Einfühlungsvermögen für nichteingeweihte beim schreiben ;)&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 22:48, 12. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11265</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11265"/>
				<updated>2007-04-12T20:48:02Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Allgemeines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** ANSEL&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** TIMER&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Ich würde die Register ANSEL und TIMER nicht speziell und so alleine beschreiben. Die gehören entweder zu den ADCs oder zu den einzelnen Timern. &amp;quot;ANSEL&amp;quot; ist z.b. einer von mind. 4 Registern, die von den ADCs benutzt werden. das Selbe gilt für Timer (stichwort TMR0-2 unterschiedliche Architektur/CCPM/PWM...)&lt;br /&gt;
&lt;br /&gt;
@PICture: passt sehr gut, man sieht ich hab die Matura, aber auch dass ich NICHT in Deutsch maturiert habe - da fehlts an Retorik, Grammatik und Einfühlungsvermögen für nichteingeweihte beim schreiben ;)&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 22:48, 12. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11264</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11264"/>
				<updated>2007-04-12T20:42:48Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* vorgeschlagene Gliederung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** ANSEL&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; TRIS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; PORT &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** TIMER&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe schon dort bischen geändert... Hoffentlich gefällt Dir. :)[[Benutzer:PICture|PICture]] 09:56, 12. Apr 2007 (CEST)&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11263</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11263"/>
				<updated>2007-04-12T20:41:44Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Diese Special Funktion Register liegen ALLE in Bank0 und Bank2(Falls vorhanden).&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== TRISx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''TRISx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TRISx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;TRISB&amp;quot; oder &amp;quot;TRISA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die TRIS-Bytes dienen dazu, einzelne I/O Pins als Eingang oder Ausgang zu definieren. Sie liegen immer genau eine Bank über den jeweiligen PORT-Bytes, d.h. sie liegen alle in Bank1 und Bank3(falls vorhanden.) Besonders zu beachten ist, dass manche Eingebaute Features wie die Serielle Schnittstelle, I2C, SPI usw nicht funktionieren, wenn die Jeweiligen Sende und Empfangspins nicht nicht manuell umgestellt werden, ja es ''muss'' sogar manchmal umgestellt werden (bei I2C z.B.) Egal ist dies jedoch für Komperatoren und AD-Wandler.&lt;br /&gt;
&lt;br /&gt;
Merke:&lt;br /&gt;
* Eine 1 (als &amp;quot;I&amp;quot; für &amp;quot;Input&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Eingang.&lt;br /&gt;
* Eine 0 (als &amp;quot;O&amp;quot; für &amp;quot;Output&amp;quot; zu lesen) eines TRISxx-Bits definiert den zugehörigen PIN am PIC als Ausgang.&lt;br /&gt;
&lt;br /&gt;
Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11262</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11262"/>
				<updated>2007-04-12T20:30:02Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Diese Special Funktion Register liegen ALLE in Bank0 und Bank2(Falls vorhanden).&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|Ja(5)&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''TRISx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;TRISB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11261</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11261"/>
				<updated>2007-04-12T20:27:57Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Diese Special Funktion Register liegen ALLE in Bank0 und Bank2(Falls vorhanden).&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11260</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11260"/>
				<updated>2007-04-12T20:26:33Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  (Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11259</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11259"/>
				<updated>2007-04-12T20:26:13Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|+ Beispiel PICs und ihre Ports  {{Blauetabelle}}(Zahlen in der Klammer sind die Anzahl der Pins des Ports)&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11258</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11258"/>
				<updated>2007-04-12T20:25:14Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe [[PIC Assembler#I/O Ports|I/O Ports]].&lt;br /&gt;
&lt;br /&gt;
{| Beispiel PICs und ihre Ports (Zahlen in der Klammer sind die Anzahl der Pins des Ports) {{Blauetabelle}}&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11257</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11257"/>
				<updated>2007-04-12T20:22:34Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* PORTx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''PORTx'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx7'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx6'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx5'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx4'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx3'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx2'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Rx0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!Das &amp;quot;x&amp;quot; steht in allen Fällen für den Buchstaben des Ports!&lt;br /&gt;
BSP: &amp;quot;PORTB&amp;quot; oder &amp;quot;RA1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Jedes Bit eines PORT-Registers steht für einen Pin (Ein/Ausgang) des Jeweiligen Ports. Je nachdem Ob ein Pin als Ausgang oder als Eingang definiert ist, kann man dort entweder den Wert schreiben oder auslesen. Es hat nicht Jeder PIC gleich viele Ports und es sind auch nicht immer 8 Pins pro Port, es können auch weniger sein. Alle PICs der Midrange-Serie besitzen nur bidirektionale Ports, d.h. sie können sowohl Eingang als auch Ausgang sein. Weiters ist zu beachten, dass einzelne Pins nach dem Reset mit anderen Funktionen belegt sein können. Das gilt im Speziellen für PORTA, wo sich die Komperatoren, AD's (falls vorhanden) und die Oszillatoreingänge (falls in den Fusebits gesetzt) befinden. Siehe dazu !!!!!!!!!&lt;br /&gt;
&lt;br /&gt;
{| Beispiel PICs und ihre Ports (Zahlen in der Klammer sind die Anzahl der Pins des Ports) {{Blauetabelle}}&lt;br /&gt;
|&lt;br /&gt;
|'''PIC16F628A'''&lt;br /&gt;
|'''PIC16F876'''&lt;br /&gt;
|'''PIC16F877'''&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTA'''&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTB'''&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTC'''&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTD'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja&lt;br /&gt;
|-&lt;br /&gt;
|'''PORTE'''&lt;br /&gt;
|/&lt;br /&gt;
|/&lt;br /&gt;
|ja (3)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11256</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11256"/>
				<updated>2007-04-12T19:58:11Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Besondere, oft gebrauchte Register */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Bänke verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben nicht unterstützen (z.B. Maus in Q-Basic).&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem Bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung (z.B. + 5V DC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits.&lt;br /&gt;
Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile. Grundsätzlich gibt es mehrere Möglichkeiten:&lt;br /&gt;
* RC (Widerstand + Kondensator); keine hohe Frequenzgenauigkeit&lt;br /&gt;
* Quarz oder Keramik-Resonator + 2 Kondensatoren (=HS oder XT) bzw. Quarzoszillator; schnell &amp;amp; genau&lt;br /&gt;
* Uhrenquarz (32768Hz) = LP (Low-Power-Mode)&lt;br /&gt;
Die entsprechenden Bauteile werden an die Pins OSC1/OSC2 angeschlossen, um den notwendigen Prozessortakt zu erzeugen. Im Konfiguration-Word &amp;quot;__config&amp;quot; muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an Versorgungsspannung legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und Versorgungsspannung  angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           .---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           `----------´       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    .-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    `--------´&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   .-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   `--------´         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    .---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    `----´&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          `--&amp;gt;V&amp;lt;--´&lt;br /&gt;
                                    &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             .--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             `---------------------´&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------.&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V&amp;lt;-------------´&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                         Warte           V&lt;br /&gt;
                                       n * nop&lt;br /&gt;
                                         V&lt;br /&gt;
                                       P2 laden&lt;br /&gt;
                         Warte2          V&amp;lt;-----------------.&lt;br /&gt;
                                       P1 laden             |&lt;br /&gt;
                         Warte1          V&amp;lt;-------------.   |&lt;br /&gt;
                                       P0 laden         |   |&lt;br /&gt;
                         Warte0          V&amp;lt;---------.   |   |&lt;br /&gt;
                                 P0 decrementieren  |   |   |&lt;br /&gt;
                                         V          |   |   |                  &lt;br /&gt;
                                      P0 = 0 ? N&amp;gt;---´   |   |&lt;br /&gt;
                                         J              |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                 P1 dekrementieren      |   |&lt;br /&gt;
                                         V              |   |&lt;br /&gt;
                                      P1 = 0 ? N&amp;gt;-------´   |&lt;br /&gt;
                                         J                  |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                 P2 dekrementieren          |&lt;br /&gt;
                                         V                  |&lt;br /&gt;
                                      P2 = 0 ? N&amp;gt;-----------´&lt;br /&gt;
                                         J&lt;br /&gt;
                                         V&lt;br /&gt;
                                       return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                              Warte     nop&lt;br /&gt;
                                        ...&lt;br /&gt;
                                        nop&lt;br /&gt;
                                        movlw   0xXX&lt;br /&gt;
                                        movwf   P2&lt;br /&gt;
                              Warte2    movlw   0xXX&lt;br /&gt;
                                        movwf   P1&lt;br /&gt;
                              Warte1    movlw   0xXX&lt;br /&gt;
                                        movwf   P0      &lt;br /&gt;
                              Warte0    decfsz  P0&lt;br /&gt;
                                        goto    Warte0&lt;br /&gt;
                                        decfsz  P1&lt;br /&gt;
                                        goto    Warte1&lt;br /&gt;
                                        decfsz  P2&lt;br /&gt;
                                        goto    Warte2&lt;br /&gt;
                                        return&lt;br /&gt;
   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                     N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                     T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                     P0 = Zahl im Register P0&lt;br /&gt;
                     P1 = Zahl im Register P1&lt;br /&gt;
                     P2 = Zahl im Register P2&lt;br /&gt;
                      n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                     10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                   Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle im W-Register zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detailierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen und zurück in RAM schreiben:&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt	&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT  ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die &amp;quot;__config&amp;quot; Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster (T1) gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der rechte Taster (T2) gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
Jetzt muss die Idee vom Programmierer in ein PAD verfasst werden, z.B. solcher:&lt;br /&gt;
&lt;br /&gt;
                               Start&lt;br /&gt;
                                 V&lt;br /&gt;
                          Initialisierung&lt;br /&gt;
                 .--------------&amp;gt;V&lt;br /&gt;
                 |        T1 gedrückt ? N&amp;gt;-----.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   links-&amp;gt;rechts &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 |       T2 gedrückt ? N&amp;gt;------.&lt;br /&gt;
                 |               J             |&lt;br /&gt;
                 |               V             |&lt;br /&gt;
                 |   rechts-&amp;gt;links &amp;quot;wandern&amp;quot;   |&lt;br /&gt;
                 |               V&amp;lt;------------´&lt;br /&gt;
                 `---------------´&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    movlw b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    clrw                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     goto  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     goto  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     movlw d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     movwf ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     addlw d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits (Low Nibble) eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! Zum Beispiel 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle Interrupts&lt;br /&gt;
::0 = Deaktiviert alle Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 Pin löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port On-Change-Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port on-change-interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port on-change-interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software gelöscht werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT Pin hat stattgefunden (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT Pin hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port On-Change-Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software gelöscht werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* *) Die Flanke auf die reagiert werden soll, wird mit dem Bit OPTION_REG.INTEDG definiert. (steigende = 1 oder fallende = 0)&lt;br /&gt;
* **) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!! Er kann aber den Prozessor vom &amp;quot;Schlaf&amp;quot; aufwecken (z.B. durch einen Tastendruck).&lt;br /&gt;
&lt;br /&gt;
=== PORTx ===&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Codeschnipsel ==&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandler (ADC) ===&lt;br /&gt;
Viele PICs besitzen einen Analog-Digital-Wandler, der eine angelegte Spannung messen kann und diese als Zahl speichert.&lt;br /&gt;
&lt;br /&gt;
Es gibt AD-Wandler mit 8Bit bzw. 10Bit Auflösung, d.h. die Spannung an einem analogen Eingang wird linear 2^8=256 bzw. 2^10=1024 Werten zugeordnet.&lt;br /&gt;
Der höchste Wert, auch Referenzspannung genannt, (255 bzw. 1023; der Controller rechnet die Null auch mit) entspricht der Betriebsspannung des PICs oder wahlweise einer wählbaren Spannung, die an RA3 angelegt werden muss. Der niedrigste Wert entspricht 0 Volt.&lt;br /&gt;
&lt;br /&gt;
Mit dem Analog-Digital-Wandler kann man somit z.B. Sensoren auswerten, die mehr als zwei Zustände ausgeben (Beispiele: Temperatursensor, Helligkeitssensor, Entfernungssensoren usw.) oder Akkuspannungen messen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bevor überhaupt gemessen werden kann, muss einiges eingestellt werden:&lt;br /&gt;
&lt;br /&gt;
a) Eingangsverteilung Analog/Digital bzw.Referenzspannung (Betriebsspannung oder RA3)&lt;br /&gt;
die genauen Einstellungsmöglichkeiten entnehmen sie bitte dem Datenblatt ihres Controllers (Register ADCON1 Bank 1).&lt;br /&gt;
&lt;br /&gt;
b) Wählen des Taktes für den ADC und Einschalten des ADCs&lt;br /&gt;
&lt;br /&gt;
Das Register ADCON0 besitzt 8 Bits, die folgendes bestimmen:&lt;br /&gt;
 Bit0 ADON - schaltet AD-Wandler ein oder aus (Strom sparen)&lt;br /&gt;
 Bit1 - nicht vorhanden&lt;br /&gt;
 Bit2 GO/Done - startet Wandlung / signalisiert, wann Umwandlung beendet ist.&lt;br /&gt;
 Bit3 CHS0 - Channel Select 0 wählt Eingang aus&lt;br /&gt;
 Bit4 CHS1 - Channel Select 1 wählt Eingang aus&lt;br /&gt;
 Bit5 CHS2 - Channel Select 2 wählt Eingang aus&lt;br /&gt;
 Bit6 ADCS0 - AD-Clock-Select wählt Takt&lt;br /&gt;
 Bit7 ADCS1 - AD-Clock-Select wählt Takt&lt;br /&gt;
&lt;br /&gt;
Kümmern wir uns zunächst um den Takt. Mit den zwei Bits ADCS0 und ADCS1 bestimmt man den Takt - hierbei gibt es vier Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
 ADCS1=0, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :2&lt;br /&gt;
 ADCS1=0, ADCS0=1 -&amp;gt; Taktfrequenz des PICs :8&lt;br /&gt;
 ADCS1=1, ADCS0=0 -&amp;gt; Taktfrequenz des PICs :32&lt;br /&gt;
 ADCS1=1, ADCS0=1 -&amp;gt; interner RC-Oszillator des ADCs verwenden&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz des ADCs darf 625kHz nicht überschreiten, dementsprechend ist ADCS0 und ADCS1 zu wählen.&lt;br /&gt;
&lt;br /&gt;
Ist dies vollbracht, so kann man den AD-Wandler einschalten und das Go/Done-Bit löschen.&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;Takt für ADC (OSC/32)&lt;br /&gt;
 bcf ADCON0,6&lt;br /&gt;
 bsf ADCON0,7&lt;br /&gt;
 ;ADC einschalten&lt;br /&gt;
 bsf ADCON0,0 ; ADON=1&lt;br /&gt;
 ;Go/Done-Bit zurücksetzen&lt;br /&gt;
 bcf ADCON0,2&lt;br /&gt;
&lt;br /&gt;
Nun ist der AD-Wandler bereit, Spannungen in Zahlen umzuwandeln.&lt;br /&gt;
Für eine Wandlung muss erst der entsprechende Eingang gewählt werden. Dafür sind die CHS0..CHS2-Bits zuständig:&lt;br /&gt;
&lt;br /&gt;
 CHS2 CHS1 CHS0  gewählter Eingang(falls vorhanden)&lt;br /&gt;
  0    0    0     RA0&lt;br /&gt;
  0    0    1     RA1&lt;br /&gt;
  0    1    0     RA2&lt;br /&gt;
  0    1    1     RA3&lt;br /&gt;
  1    0    0     RA5&lt;br /&gt;
  1    0    1     RE0&lt;br /&gt;
  1    1    0     RE1&lt;br /&gt;
  1    1    1     RE2&lt;br /&gt;
&lt;br /&gt;
 Achtung! RA4 ist kein analoger Eingang, folglich ist er oben nicht aufgelistet !!&lt;br /&gt;
&lt;br /&gt;
Codebeispiel:&lt;br /&gt;
&lt;br /&gt;
 ;RA2 auswählen&lt;br /&gt;
 bcf ADCON0,3&lt;br /&gt;
 bsf ADCON0,4&lt;br /&gt;
 bcf ADCON0,5&lt;br /&gt;
&lt;br /&gt;
Als letztes muss die AD-Routine nur noch gestartet werden. Ist der AD-Wandler fertig, so löscht er das Bit wieder. Das Bit wird nun solange abgefragt, bis der AD-Wandler fertig ist. Den zugeordneten Wert findet man im Register 'ADRES'. &lt;br /&gt;
Code:&lt;br /&gt;
&lt;br /&gt;
    ;start&lt;br /&gt;
    bsf ADCON0,2&lt;br /&gt;
    ;warten,bis es wieder low ist&lt;br /&gt;
 wa btfsz ADCON0,2&lt;br /&gt;
    goto wa&lt;br /&gt;
    ;jetzt ist er fertig&lt;br /&gt;
    ;ADRES in W verschieben, um damit gleich weiter zu arbeiten&lt;br /&gt;
    movf ADRES,W&lt;br /&gt;
&lt;br /&gt;
Die AD-Wandlung ist somit fertig. Liest man mehrere Werte von unterschiedlichen Eingängen ein und möchte diese miteinander vergleichen o.ä., sollte man die Zahlen von ADRES in anderen Registern zwischenspeichern.&lt;br /&gt;
&lt;br /&gt;
Desweiteren ist zu beachten, dass der Analog-Digital-Wandler eine gewisse Pause zwischen den Wandlungen benötigt, die sog. 'Aquisition Time'. Diese Zeitangabe entnehmen sie bitte ihrem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
mögliche Probleme:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a) Der PIC liefert stark schwankende Werte&lt;br /&gt;
-&amp;gt; Mögliche Ursachen dafür sind z.B. nicht stabile Betriebsspannung, falsche Zeiteinstellungen. Abhilfe schafft auch das mehrmalige Einlesen eines Eingangs. Auch können z.B. 8 Werte eingelesen werden und dann der Durchschnitt gebildet werden.&lt;br /&gt;
Evtl. kann ein Kondensator gegen Masse (z.B. 1nF) helfen; Wichtig ist auch eine kleine Verzögerung zwischen Kanalauswahl und Start der Wandlung. In dieser Zeit kann sich der interne Kondensator des ADC's aufladen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
b) Die Spannung an einem Eingang wird erhöht, die Werte der anderen Eingänge werden aber auch beeinflusst. Woran liegt das?&lt;br /&gt;
-&amp;gt; Dann sind Sie Opfer des sog. 'Ghostings' geworden (Werte 'scheinen durch', verschleißen). Die Werte der anderen Eingänge gehen mit, weil der interne Kondensator noch auf die Spannung des Vorgängers aufgeladen ist. Maßnahme: Aquisition Time erhöhen, Werte öfters abfragen, Pause zwischen Kanalauswahl und Start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
c) Der PIC liefert immer die gleichen Werte an einem Eingang, obwohl sich die angelegte Spannung ändert&lt;br /&gt;
-&amp;gt; möglicherweise falsche Eingangsverteilung (ADCON1) eingestellt oder falschen Pin gewählt&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11241</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11241"/>
				<updated>2007-04-12T08:40:53Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Compilerdirektiven */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven werden je nach Compiler unterstützt (-oder eben auch nicht.) Sie geben dem Compiler Anweisungen, die z.b. das Ende des Programms oder einfach nur die Position eines Befehls im Prgrammspeicher angeben.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11240</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11240"/>
				<updated>2007-04-12T08:40:16Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Pseudo Befehle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Compilerdirektiven =&lt;br /&gt;
&lt;br /&gt;
Compilerdirektiven 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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11239</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11239"/>
				<updated>2007-04-12T08:37:46Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* RETFIE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11238</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11238"/>
				<updated>2007-04-12T08:36:18Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11237</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11237"/>
				<updated>2007-04-12T08:35:33Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]] und [[Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11236</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11236"/>
				<updated>2007-04-12T08:35:00Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]] und Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11235</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11235"/>
				<updated>2007-04-12T08:34:17Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* ANDWF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0x84   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
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]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11234</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11234"/>
				<updated>2007-04-12T08:33:12Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xCC (binär: '11001100') und dem Arbeitsregister durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xCF ('11001111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11233</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11233"/>
				<updated>2007-04-12T08:31:30Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11232</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11232"/>
				<updated>2007-04-12T08:30:47Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ANDWF|ANDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11230</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11230"/>
				<updated>2007-04-12T08:29:43Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* Beispiel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ANDLW|ANDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11229</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11229"/>
				<updated>2007-04-12T08:29:18Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* IORLW */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
IORWF 0xCC   ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORWF|IORWF]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11228</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11228"/>
				<updated>2007-04-12T08:27:56Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* IORWF */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x86 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000110'&lt;br /&gt;
IORWF 0x22,1 ;Führt die Logische Operation &amp;quot;OR&amp;quot; oder auch &amp;quot;IOR&amp;quot; (Oder = Inclusives Oder) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('10000111')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
siehe auch [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
und [[PIC Assemblerbefehle#IORLW|IORLW]],[[PIC Assemblerbefehle#ADDWF|ADDWF]],[[PIC Assemblerbefehle#ADDLW|ADDLW]],[[PIC Assemblerbefehle#XORWF|XORWF]],[[PIC Assemblerbefehle#XORLW|XORLW]]&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11217</id>
		<title>PIC Assemblerbefehle</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assemblerbefehle&amp;diff=11217"/>
				<updated>2007-04-12T07:09:50Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Assembler Befehle =&lt;br /&gt;
== ADDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ADDLW''' &lt;br /&gt;
| '''ADD Zahl und W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ADDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k ADD addiert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ADDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ADDWF'''&lt;br /&gt;
|'''ADD W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ADDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ANDLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''ANDLW''' &lt;br /&gt;
| '''AND Zahl mit W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| ANDLW k &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) + k → (W) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verundet und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0xCC ;Ladet Die Zahl 0xCC (Hex) in den Arbeitsregister. &lt;br /&gt;
           ;Sieht Binär so aus: '11001100'&lt;br /&gt;
ANDLW 0xF0 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
           ;mit 0xF0 (binär: '11110000') durch und ladet die Zahl &lt;br /&gt;
           ;wieder ins Arbeitsregister W.&lt;br /&gt;
           ;Nun steht im Arbeitsregister 0xC0 ('11000000')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== ANDWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''ANDWF'''&lt;br /&gt;
|'''AND W mit f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ANDWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .AND. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
MOVLW 0x07   ;Ladet die Zahl 0x07 ('00000111') in das Arbeitsregister...&lt;br /&gt;
MOVWF 0x22   ;...und anschließend in den Register 0x22&lt;br /&gt;
MOVLW 0xCC   ;Ladet Die Zahl 0x84 (Hex) in das Arbeitsregister. &lt;br /&gt;
             ;Sieht Binär so aus: '10000100'&lt;br /&gt;
ANDWF 0x22,1 ;Führt die Logische Operation &amp;quot;AND&amp;quot; (UND) &lt;br /&gt;
             ;mit dem Inhalt des (GPR)Registers mit der Adresse 0x22 &lt;br /&gt;
             ;durch und ladet die Zahl &lt;br /&gt;
             ;danach wieder in den in den Register 0x22 zurück.&lt;br /&gt;
             ;Nun steht an der Adresse 0x22 die Zahl 0x04 ('00000100')&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Mit der Logischen Operation &amp;quot;AND&amp;quot; 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.&lt;br /&gt;
&lt;br /&gt;
siehe [[PIC Assemblerbefehle#Logiktabelle|Logiktabelle]]&lt;br /&gt;
&lt;br /&gt;
== BCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BCF''' &lt;br /&gt;
| '''Bit Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BCF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 0 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BSF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BSF''' &lt;br /&gt;
| '''Bit Set f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BSF f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 0 → (f&amp;lt;b&amp;gt;) &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Bit ‘b’ in Register ‘f’ wird auf 1 gesetzt&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
BSF STATUS, RP0   ;Setzt das Bit RP0 auf 1 -&amp;gt; Wechsel auf Bank1&lt;br /&gt;
BSF TRISB,0       ;Macht den Pin 0 des PORTB's zum Eingang&lt;br /&gt;
BCF STATUS, RP1   ;Löscht das Bit RP0 auf 0 -&amp;gt; Wechsel auf Bank0&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== BTFSC ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSC''' &lt;br /&gt;
| '''Bit Test f, Skip if Clear''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSC f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
Praktisch die Selbe Funktion wie BTFSS, nur dass hier der nachfolgende Befehl übersprungen wird, wenn das zu testende Bit gleich 0 ist, nicht 1.&lt;br /&gt;
Siehe [[PIC Assemblerbefehle#BTFSS|BTFSS]]&lt;br /&gt;
&lt;br /&gt;
== BTFSS ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''BTFSS''' &lt;br /&gt;
| '''Bit Test f, Skip if Set''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| BTFSS f,b&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und 0 ≤ b ≤ 7&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| skip if (f&amp;lt;b&amp;gt;) = 1 &lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
wait_until_set&lt;br /&gt;
     BTFSS PORTB,1           ;Ist Pin0 von PORTB gleich 1?&lt;br /&gt;
     goto wait_until_set     ;Nein. Springe zum Label &amp;quot;wait_until_set&amp;quot;&lt;br /&gt;
     ...                     ;Ja. Jetzt gehts erst weiter.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Dieser Befehl kann immer nur ein einzelnes Bit abfragen. Vorsicht bebei folgendem Versuch damit Bits zu &amp;quot;toggeln&amp;quot; (1 wird 0 und 0 wird 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     ;FALSCH:&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es... (Befehl1)&lt;br /&gt;
     BCF   0x23,2            ;Ja. Dann löschen wir es...  (Befehl2)&lt;br /&gt;
     ...                     ;Fehler in der Denkweise: &lt;br /&gt;
                             ;Der Befehl BCF WIRD IMMER AUSGEFÜHRT!&lt;br /&gt;
                             ;Es heist NICHT ENTEDER Befehl1 ODER Befehl2 - &lt;br /&gt;
                             ;sondern ÜBERSPRINGE Befehl1 wenn die Abfrage WAHR ist, SONST&lt;br /&gt;
                             ;geh einfach weiter (und mach beide)!!!&lt;br /&gt;
     ...&lt;br /&gt;
     ;RICHTIG:&lt;br /&gt;
     ;2xFragen&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     BSF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     BTFSC 0x23,2            ;Ist Bit2 von 0x23 gleich 0?&lt;br /&gt;
     BCF   0x23,2            ;Nein. Dann setzen wir es...&lt;br /&gt;
     ...&lt;br /&gt;
     ...&lt;br /&gt;
     ;oder Blöcke für mehrere Befehle&lt;br /&gt;
     BTFSS 0x23,2            ;Ist Bit2 von 0x23 gleich 1?&lt;br /&gt;
     goto ist_nicht_eins     ;Nein, geh zur Sprungmarke &amp;quot;ist_nicht_eins&lt;br /&gt;
     ...                     ;Ja, hier weitermachen...&lt;br /&gt;
     ...&lt;br /&gt;
     goto weitermachen       ;Anderen Block &amp;quot;überspringen&amp;quot;&lt;br /&gt;
ist_nicht_eins&lt;br /&gt;
     ...                     ;Hier wird der Fall abgehandelt,&lt;br /&gt;
     ...                     ;falls das Ergebnis nicht eins war.&lt;br /&gt;
weitermachen&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CALL ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CALL''' &lt;br /&gt;
| '''Call Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CALL k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (PC) + 1 → TOS,&lt;br /&gt;
k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
(PCLATH&amp;lt;4:3&amp;gt;) → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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).&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    BSF STATUS,RP0&lt;br /&gt;
    BSF TRISB,3        ;PORTB,3 als Ausgang definieren&lt;br /&gt;
    BCF STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
    call toggle_LED    ;Rufe die Subroutine &amp;quot;toggle_LED&amp;quot; auf&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    call toggle_LED    ;Kann auch mehrmals ausgeführt werden.&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
    ...&lt;br /&gt;
loop                   ;Endlossschleife verhindert, &lt;br /&gt;
    goto loop          ;dass das Program bis zur Subroutine ohne Sprung kommt. &lt;br /&gt;
&lt;br /&gt;
toggle_LED             ;Jedes Mal wenn, &amp;quot;CALL toggle_LED&amp;quot; ausgeführt wird, &lt;br /&gt;
                       ;landet das Programm hier.&lt;br /&gt;
    BTFSS PORTB,3      ;Die nächsten 4 Zeilen invertieren die LED. &lt;br /&gt;
    BSF   PORTB,3      ;Siehe BTFSS&lt;br /&gt;
    BTFSC PORTB,3&lt;br /&gt;
    BCF   PORTB,3&lt;br /&gt;
    RETURN             ;geht zurück an die Stelle, wo die Subroutine aufgerufen wurde.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wichtig an der Stelle ist es auch, den Befehl &amp;quot;[[PIC Assemblerbefehle#RETLW|RETLW]]&amp;quot; zu erwähnen. Eigentlich hat er die selbe Funktion wie &amp;quot;RETURN&amp;quot;, nur dass noch ein Zahlenwert in das Arbeitsregister geladen wird.&lt;br /&gt;
&lt;br /&gt;
== CLRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRF''' &lt;br /&gt;
| '''Clear f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (f),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das komplette Byte im Register f wird gelöscht (lauter 0er). Das hat zur Folge, das Z gesetzt wird.&lt;br /&gt;
|}&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  CLRF TMR0   ;Löscht den Inhalt des Registers TMR0&lt;br /&gt;
              ;und setzt ihn damit wieder an den Anfang.&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;Z&amp;quot; nicht gesetzt wird. Also CLRF nur verwenden, wenn es einen nicht stört, dass das Zeroflag gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
== CLRW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRW''' &lt;br /&gt;
| '''Clear W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRW&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → (W),&lt;br /&gt;
1 → Z&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird gelöscht und anschließed das Z-Bit auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== CLRWDT ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''CLRWDT''' &lt;br /&gt;
| '''Clear Watchdog Timer''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| CLRWDT&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
1 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Watchdogtimer (TMR0) wird resettet. es wird ebenfalls der Prescaler resettet. Die Statusbits T0 und PD werden gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== COMF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''COMF''' &lt;br /&gt;
| '''Complement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| COMF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127 und &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== DECF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECF''' &lt;br /&gt;
| '''Decrement f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0x01&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    DECF  0x20,1 ;nun steht 0x00 im Register und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    DECF  0x20,1 ;und nun 0xFF (überlauf!)&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DECFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''DECFSZ''' &lt;br /&gt;
| '''Decrement f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| DECFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GOTO ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''GOTO''' &lt;br /&gt;
| '''uncontitional Branch''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| GOTO k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 2047&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → PC&amp;lt;10:0&amp;gt;,&lt;br /&gt;
PCLATH&amp;lt;4:3&amp;gt; → PC&amp;lt;12:11&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== INCF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCF''' &lt;br /&gt;
| '''Increment f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127, &lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Beispiel====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    MOVLW 0xFE&lt;br /&gt;
    MOVWF 0x20   ;ladet die Zahl 0x01 ins Register 0x20&lt;br /&gt;
    INCF  0x20,1 ;nun steht 0xFF im Register&lt;br /&gt;
    INCF  0x20,1 ;und nun 0x00 (Überlauf!) und das Z-Bit wird auf 1 gesetzt&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INCFSZ ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''INCFSZ''' &lt;br /&gt;
| '''Increment f, skip if 0''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| INCFSZ f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) + 1 → (destination), skip if result = 0&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''IORLW''' &lt;br /&gt;
| '''Inclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| IORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .OR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''IORWF'''&lt;br /&gt;
|'''Inclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|IORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVF'''&lt;br /&gt;
|'''Move f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) + (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Der Inhalt des Registers f wird entweder in das Arbeitsregister W (d=0) oder wieder in sich selbst kopiert (d=1). Das &amp;quot;in sich selber kopieren&amp;quot; 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVLW'''&lt;br /&gt;
|'''Move Literal to W'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Die Zahl k wird in das Arbeitsregister geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== MOVWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''MOVWF'''&lt;br /&gt;
|'''Move W to f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|MOVWF f&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) → (f)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Das Arbeitsregister W wird in das Register f geladen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NOP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''NOP'''&lt;br /&gt;
|'''No Operation'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|NOP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Ein Takt lang wird NICHTS gemacht.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETFIE ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETFIE''' &lt;br /&gt;
| '''Return from Interrupt''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETFIE&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC,&lt;br /&gt;
1 → GIE&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETLW''' &lt;br /&gt;
| '''Return with Literal in W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255 &lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k → (W);&lt;br /&gt;
TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RETURN ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RETURN''' &lt;br /&gt;
| '''Return from Subroutine''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RETURN&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| TOS → PC&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Programm wird an der Stelle fortgesetzt, wo die letzte Subroutine aufgerufen wurde.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RLF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RLF''' &lt;br /&gt;
| '''Rotate Left f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RLF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird links rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RRF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''RRF''' &lt;br /&gt;
| '''Rotate Right f through Carry''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| RRF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| siehe unten&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| / &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Register F wird rechts rum über das Carryflag &amp;quot;rotiert&amp;quot;. 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).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SLEEP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SLEEP''' &lt;br /&gt;
| '''Sleep''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SLEEP&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| 00h → WDT,&lt;br /&gt;
0 → WDT prescaler,&lt;br /&gt;
1 → TO,&lt;br /&gt;
0 → PD&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| TO, PD &lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Powerdownstatusbit (PD) wird gelöscht und das Timeoutstatusbit (TO) wird gesetzt. Der Watchdog wird samt seinem Prescaler Resetet. Danach wird der Prozessor &amp;quot;schlafen&amp;quot; geschickt und der Oszillator angehalten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBLW''' &lt;br /&gt;
| '''Subtract W from Literal''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| k – (W) → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Das Arbeitsregister W wird von der Zahl k Subtrahiert und das Ergebnis wird in W gespeichert.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SUBWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SUBWF''' &lt;br /&gt;
| '''Subtract W from f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SUBWF f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f) – (W) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| C, DC, Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SWAP ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''SWAP''' &lt;br /&gt;
| '''Swap Nibbles in f''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| SWAP f,d&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ f ≤ 127&lt;br /&gt;
d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (f&amp;lt;3:0&amp;gt;) → (destination&amp;lt;7:4&amp;gt;),&lt;br /&gt;
(f&amp;lt;7:4&amp;gt;) → (destination&amp;lt;3:0&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORLW ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
| '''XORLW''' &lt;br /&gt;
| '''Exclusive OR Literal with W''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
| XORLW k&lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
| 0 ≤ k ≤ 255&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
| (W) .XOR. k → (W)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
| Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
| Der Inhalt des W Registers wird mit der 8-Bit Zahl k exklusiv verodert und das Ergebnis landet wieder im W Register&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== XORWF ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''XORWF'''&lt;br /&gt;
|'''Exclusive OR W und f'''&lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|XORWF f,d &lt;br /&gt;
|-&lt;br /&gt;
|Operanten: &lt;br /&gt;
|0 ≤ f ≤ 127 und d ∈ [0,1]&lt;br /&gt;
|-&lt;br /&gt;
|Operation: &lt;br /&gt;
|(W) .OR. (f) → (destination)&lt;br /&gt;
|-&lt;br /&gt;
|Beeinflusste Statusbits: &lt;br /&gt;
|Z&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Pseudo Befehle =&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== #Define == &lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''#Define''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|#Define ''name'' ''string''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Jedes mal wenn 'name' im Programm verwendet wird, ersetzt der Compiler den Ausdruck mit dem  definierten String.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== END ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''END''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|END&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== EQU ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''EQU''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|''name'' EQU ''expr''&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Definiert eine Zahl unter einem Namen. Zum Beispiel können so Registeradressen leicht zu merkende Namen bekommen. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== ORG ==&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|colspan=2 |'''ORG''' &lt;br /&gt;
|-&lt;br /&gt;
|Syntax: &lt;br /&gt;
|ORG expr&lt;br /&gt;
|-&lt;br /&gt;
|Beschreibung: &lt;br /&gt;
|Positioniert Code im Programm an eine Bestimmte Adresse im Programmspeicher.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logiktabelle=&lt;br /&gt;
{|{{Blauetabelle}}&lt;br /&gt;
|'''A'''&lt;br /&gt;
|'''B'''&lt;br /&gt;
|&lt;br /&gt;
|'''AND'''&lt;br /&gt;
|'''OR'''&lt;br /&gt;
|'''NAND'''&lt;br /&gt;
|'''NOR'''&lt;br /&gt;
|'''XOR'''&lt;br /&gt;
|'''XAND'''&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11215</id>
		<title>Diskussion:PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:PIC_Assembler&amp;diff=11215"/>
				<updated>2007-04-12T07:07:28Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== vorgeschlagene Gliederung ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;grün = schon fertig&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;orange = wird bzw. könnte noch ergänzt werden&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einladung zur Diskussion...&amp;lt;/span&amp;gt;&lt;br /&gt;
(wird nach Beendigung des Artikels gelöscht)&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einführung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bit, Byte, Nibble, Bin und Hex &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Speicher und Register &amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Prozessor&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Assembler&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Grundbeschaltung&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Wahl des PICs&amp;lt;/span&amp;gt;&lt;br /&gt;
* Programm&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Allgemeines&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Programdurchlaufdiagram&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hauptprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Unterprogramm&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Initialisierung&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Variablen&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;I/O Ports&amp;lt;/span&amp;gt;&lt;br /&gt;
**** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Hardware&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Einlesen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausgeben&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Pause&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Schnittstellen und Treiber&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Tabellen&amp;lt;/span&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;EEPROM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Vorlage für MPASM&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Für anderen PIC umschreiben&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:orange;&amp;quot;&amp;gt;Das erste...&amp;lt;/span&amp;gt;&lt;br /&gt;
* Interrupts&lt;br /&gt;
** Prinzip&lt;br /&gt;
** Quellen&lt;br /&gt;
** Interrupt Service Routine&lt;br /&gt;
* Optimierung&lt;br /&gt;
** Speicherbedarf&lt;br /&gt;
*** Programmspeicher&lt;br /&gt;
*** RAM&lt;br /&gt;
** Ausführungszeit&lt;br /&gt;
* Fehlersuche&lt;br /&gt;
* Mid-Range (mit 14 bit Befehlslänge)&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Kurzübersicht Prozessorbefehle&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Ausführliche Beschreibung zu den Befehlen&amp;lt;/span&amp;gt;&lt;br /&gt;
** Besondere, oft gebrauchte  Register&lt;br /&gt;
*** ANSEL&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; STATUS &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt; INTCON &amp;lt;/SPAN&amp;gt;&lt;br /&gt;
*** TRIS&lt;br /&gt;
*** PORT&lt;br /&gt;
*** TIMER&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Bänke (sowohl die bei mehr als 2k Befehle als auch die bei den normalen speicher bänken)&amp;lt;/span&amp;gt;&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;Flagsüberprüfung im STATUS-Register&amp;lt;/span&amp;gt;&lt;br /&gt;
** Codeschnipsel&lt;br /&gt;
*** A/D-Wandler&lt;br /&gt;
*** PWM&lt;br /&gt;
*** Interrupts&lt;br /&gt;
*** RS232 mit PC&lt;br /&gt;
*** Tasten&lt;br /&gt;
*** Mausrad&lt;br /&gt;
*** Ausgabe auf LCD Displays&lt;br /&gt;
**** Dot-Matrix &lt;br /&gt;
**** Grafik&lt;br /&gt;
**** Handy&lt;br /&gt;
*** Hilfsmittel&lt;br /&gt;
**** PIC Miniterminal (mit Dot-Matrix LCD und drei Tasten, benötigt nur 2 I/O Pins und 2 ICs)(Hardware)&lt;br /&gt;
**** PIC RAM Monitor (mit eigenem Interrupt, zeigt Registerinhalte sogar wenn das Programm in endloser Schleife läuft, was besonders für Anfänger nutzlich ist, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
**** PIC Trainer (Hilfswerkzeug für PIC Versuchsprogramme, benötigt PIC Miniterminal)&lt;br /&gt;
**** PIC Profiler (zum messen von Ausführungszeit zwischen call und return, benötigt Display oder PIC Miniterminal)&lt;br /&gt;
* High-End (mit 16 bit Befehlslänge)--&amp;gt;(?)&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
-------&lt;br /&gt;
... gelöschte Diskussion ...&lt;br /&gt;
----&lt;br /&gt;
joa. passt doch. ich mach dir dann wieder paar bilder. mal schaun ob ich es heute noch schaffe. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 08:52, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Vielen Dank im voraus!:) Wenn Du die drei Symbole die im PAD auftreten einzeln kopieren kannst, müsste es ziemlich schnell gehen. Nach der neuer Gliederung müsste ich jetzt über Quellcode schreiben, also schon (aber nur) &amp;quot;call&amp;quot; und &amp;quot;goto&amp;quot; einführen. Sonst werde ich alles im Textform (Kommentar) schreiben. Ich meine, dass es unvermeindbar ist, weil irgendwan es sowieso anfangen wird. Ich habe noch eine Frage an Dich. Würdest Du die MPASM Direktiven erklären, die ich von &amp;quot;deinem&amp;quot; in &amp;quot;mein&amp;quot; Teil verschoben habe?[[Benutzer:PICture|PICture]] 09:33, 1. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wie meinst du? ich mache halt noch eine erklärung für alle befehle, brauche nur noch bisschen zeit, werde heute leider nicht dazukommen, da ich unterwegs bin :-/ aber in absehbarer zeit werde ich auch noch die anderen befehle beschreiben, und dann mir ein neues thema suchen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 18:54, 1. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Es hat sich schon erledigt. Ich habe es als unnötig gestuft und gelöscht. Ab jetzt wird ganz einfache Darstellung von PADs verwendet und es bleibt nur einer in Grafik zu verwandeln (PAD). Die alle anderen (PAD1, PAD2, PAD3, PAD4, und die noch kommen...) bleiben so, wie sie sind/werden. Und weiter würdest Du (hoffentlich) nichts mehr für mich zu tun haben. :)[[Benutzer:PICture|PICture]] 00:12, 2. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
jetzt wollte ich mir ein neues thema raussuchen, was ich noch schreiben könnte, aber muss irgendwie zugeben, dass ich mit den befehlen schon mit meinem latein am ende bin :-/ also ich könnte schon bisschen was schreiben, aber so richtig sicher bin ich mir dabei dann nicht immer. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:25, 5. Apr 2007 (CEST)&lt;br /&gt;
------&lt;br /&gt;
Macht ja nichts. Wir arbeiten an dem Artikel bis zum Ende zusammen. Du hast mir schon viel geholfen, dann helfe ich Dir auch immer wieder. Ich versuche möglichst kurz das wichtigste schreiben, aber weiss ich selber nicht, ob das verständlich ist, da ich das alles sehr gut verstehe :). Was Dir nicht gefällt oder nicht genug verständlich ist kannst Du immer ändern (so wie bei der Grundbeschaltung) oder fragen (so wie mit den Buchstaben &amp;quot;C&amp;quot; und &amp;quot;F&amp;quot;). Wie Du sicher bemerkt hast, habe ich in den Befehlen auch ein bischen geändert. Jemand hat gesagt : &amp;quot;Es gibt keine dumme Fragen, nur dumme Antworten&amp;quot; und das stimmt!. Also keine Angst! :) Es gibt auch PN. Für mich ist Deine Meinung sehr wichtig! Ich denke, dass bis Interrupts sollte es schon für Anfänger ausreichen, bin mich aber auch nicht sicher wo eigentlich Ende vom Anfang ist. :) [[Benutzer:PICture|PICture]] 14:24, 5. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
wow! respekt! geht ja ganz schön schnell voran. das eine pad bekommst du auf jeden fall noch, brauche leider noch ein paar tage. noch dazu müsste ich langsam wirklich fürs abi lernen, aber solange noch andere dinge gehen, werde ich auch hier noch bisschen was machen ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:37, 8. Apr 2007 (CEST)&lt;br /&gt;
-----&lt;br /&gt;
Mach Dir bitte mit dem Artikel keinen Stress, ich versuche bloss die freie Tage sinvoll nutzen.:). Es wird danach langsamer gehen, aber die Zeit ist nicht beschränkt. Sogar für die schon als fertig markierte Sachen schreibe ich immer wieder was dazu, was mir noch einfällt.[[Benutzer:PICture|PICture]] 16:11, 8. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
 Bit, Byte, Nibble, Bin und Hex &lt;br /&gt;
also ich würde schon die nummerierung der bits mit aufnehmen. habe mich lange gefragt, wie das funktioniert, weil man ja normalerweise von links nacht rechts zählt und mit 1 anfängt. [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 21:28, 9. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Natürlich! :) Die Numerierung der Bits ist bei jedem Prozessor gleich und fängt immer von links mit 0 (LSB). Ich habe schon eine Idee für erstes ASM Programm, das wird aber noch ein bischen dauern, weil ich das zuerst selber ausprobieren muss (und will). Aber es ist noch weit zum Ende des Artikels. [[Benutzer:PICture|PICture]] 09:27, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
mein fehler. habe da wohl was verwechselt. sorry. die zahlen sind ja doch noch da :-/ [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 12:52, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@Benedikt.Seidl&lt;br /&gt;
&lt;br /&gt;
Schau, bitte, am Anfang des Artikels habe ich noch was neues eingefügt. Als Folge haben wir noch einen Autor (den Gärtner), der schon wichtige Sachen toll ergänzt hat.&lt;br /&gt;
&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Wenn Du willst, kannst auch etwas neues, wass noch nicht grün gekenzeichnet ist, anfangen. :)&lt;br /&gt;
[[Benutzer:PICture|PICture]] 13:17, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
wow! glückwunsch! http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=14953 [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 16:13, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Für Dich das gleiche ! Trotzdem schreibe ich weiter.:)[[Benutzer:PICture|PICture]] 16:59, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Keine Angst, hab auch neues geschrieben ;) Hat wer eine bessere Idee bezüglich Textformation von SFRs? hab mich mal am Datenblatt bedient. Die Assemblerbefehle hab ich heute schon in einen eigenen Artikel geschrieben. Da fehlen nur noch Codeschnippsel. find das Übersichtlicher und werde die DETAILs zu den befehlen von hier bald RAUSLÖSCHEN. (wenn ich mit dem anderen Artikel fertig bin.) --[[Benutzer:Der Gärtner|Der Gärtner]] 18:06, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:Die Asführliche Beschreibung zu den Befehlen hat der Benedikt.Seidl geschrieben, aber ich glaube, dass er nichts dagegen hätte. Dann werden die Codeschnipsel auch dorthin verschoben, oder ? Es wäre gut wenn Du das Link zu Deinem Artikel in diesen Artikel einfügst. Ich weiss nicht wo ich später die Hifsmittel (kleine Programmierwerkzeuge) hin schreiben soll.[[Benutzer:PICture|PICture]] 18:33, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
:ich finde es schon sehr schade, weil das schon viel arbeit gemacht hat hier. das tabellenlayout hat auch vor und nachteile. aber ich versteh nicht, warum du nicht auf meine beschreibung und code-schnipsel zurückgreifst, bzw. meine befehlsliste ergänzt hast? deine infos bzw. beschreibungen sind wahrscheinlich schon technischer und auch ok, aber für den normalen benutzer oder einsteiger sehe ich es eher als hindernis, wenn so komplizierte beschreibungen verwendet werden. &lt;br /&gt;
: trotzdem finde ich es schön, dass du mitarbeitest, gärtner ;-) [[Benutzer:Benedikt.Seidl|Benedikt.Seidl]] 19:18, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Ich denke auch, dass Löschen nicht nötig ist und Dein Artikel wunderbar als Nachschlagewerk benutzt werden kann, wenn sein Link in diesem Artikel eingefügt wird.[[Benutzer:PICture|PICture]] 19:31, 10. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
@ Gärtner&lt;br /&gt;
&lt;br /&gt;
Erst heute habe ich Dein Artikel aufmerksam durchgelesen und folgendes nicht gut gefunden:&lt;br /&gt;
&lt;br /&gt;
- die Wörter &amp;quot;verundert&amp;quot;, &amp;quot;verodert&amp;quot; und &amp;quot;inklusiv verodert&amp;quot; sind vielleicht &amp;quot;cool&amp;quot; aber für jemanden die die logische Operationen gar nicht kennt, ganz unverständlich.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;call&amp;quot; und &amp;quot;retlw&amp;quot; ist überhaupt nichts über funktionsweise im ASM Programm geschrieben, nur über Register, was nicht besonders wichtig ist. Bei &amp;quot;retfie&amp;quot; fehlt die wichtige Information, dass ausführen des Befehls das Bit GIE setzt, was die Interrupts wieder erlaubt.&lt;br /&gt;
&lt;br /&gt;
- bei &amp;quot;clrw&amp;quot; ist falsches Register und bei &amp;quot;end&amp;quot; falsche Funktion gennant. Ausserdem, ich kenne Keine Pseudobefehle, sondern Direktiven für Assemblerprogramm.&lt;br /&gt;
&lt;br /&gt;
Ohne Beipielen vom Code finde ich das ganze ungeeignet für Anfänger. Bleiben wir, bitte, in dem Artikel, der vor allem für Anfänger vorgesehen ist, bei der ausführlicher Beschreibung vom Benedikt.Seidl.[[Benutzer:PICture|PICture]] 09:08, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Code kommt noch, und fehler sind echt vorprogramiert gewesen :)&lt;br /&gt;
Ich hab noch einiges an Dingen vor gehabt, die sowieso hier stehen. Die Begriffe &amp;quot;verundet&amp;quot; und &amp;quot;verodert&amp;quot; sind die einzigen, die ich jemals gehört habe, und JA, ich hab vor beispiele zu Schreiben / vom Seidl zu nehmen. Und wenn ich so scharf aufs Löschen wäre, dann hätt ichs schon gemacht :P&lt;br /&gt;
&lt;br /&gt;
Den Begriff &amp;quot;Pseudobefehle&amp;quot; hab ich vom Sprut, kann ich ruhig ändern.&lt;br /&gt;
&lt;br /&gt;
Werd heute da einiges ergänzen und die Register in diesem Beitrag weiter machen.&lt;br /&gt;
--[[Benutzer:Der Gärtner|Der Gärtner]] 11:09, 11. Apr 2007 (CEST) &lt;br /&gt;
----&lt;br /&gt;
@Gärtner&lt;br /&gt;
&lt;br /&gt;
Das hört sich sehr gut an. Deine Beschreibung von Befehlen ist auch nötig, da kann man sofort die Beschreibung für ein Befehl lesen, das man braucht. Sie hat aber sehr langen Inhaltverzeichnis, länger, als dieser ganzen Artikel. Deswegen finde ich die Idee, das getrennt vom Artikel zu machen sehr gut.:) Übrigens, für mich ist der Sprut kein Experte und ich versuche immer mich an der Dokumentation vom Microchip (z.B. MPASM) zu halten um das ganze einheitlich zu gestalten. Es wäre auch eine Möglichkeit, um unnötige Arbeit zu vermeinden, einfach die ganze Beschreibung vom Seidl in Dein Artikel zu übernehmen (eventuell bischen ergänzen) und danach von unserem Artikel löschen und in dem Menüpunkt &amp;quot;Ausführliche Beschreibung zu den Befehlen&amp;quot; nur den Link zu Deinem Artikel lassen. Das scheint mir sogar optimale Lösung zu sein. Ich habe genauso bei &amp;quot;Interface und Treiber&amp;quot; gemacht. Ich werde erst am Wochenende wieder aktiv.[[Benutzer:PICture|PICture]] 19:02, 11. Apr 2007 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Habe den Register INTCON beschrieben... --[[Benutzer:Der Gärtner|Der Gärtner]] 09:07, 12. Apr 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11190</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11190"/>
				<updated>2007-04-11T14:11:25Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESSE 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
=== INTCON === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''INTCON''' (ADDRESSE 0Bh, 8Bh, 10Bh, 18Bh)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''GIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PEIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TMR0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''INT0IF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RBIF'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''GIE''': Global Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle ausgewählten Interrupts&lt;br /&gt;
::0 = Deaktiviert alle ausgewählten Interrupts&lt;br /&gt;
*Bit 6 '''PEIE''': Peripheral Interrupt Enable Bit&lt;br /&gt;
::1 = Aktiviert alle peripheren Interrupts&lt;br /&gt;
::0 = Deaktiviert alle 	peripheren Interrupts&lt;br /&gt;
*Bit 5 '''TMR0IE''': TMR0 Overflow Interrupt Enable Bit (Overflow von Timer0 löst Interrupt aus)&lt;br /&gt;
::1 = Aktiviert den TMR0 Interrupt&lt;br /&gt;
::0 = Deaktiviert den TMR0 Interrupt&lt;br /&gt;
*Bit 4 '''INT0IE''': RB0/INT External Interrupt Enable Bit (Änderung an RB0 löst Interrupt aus) *)&lt;br /&gt;
::1 = Aktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
::0 = Deaktiviert den RB0/INT Interrupt (Extern ausgelöst)&lt;br /&gt;
*Bit 3 '''RBIE''': RB Port Change Interrupt Enable Bit (Änderung an PortB löst Interrupt aus) **)&lt;br /&gt;
::1 = Aktiviert den RB port change interrupt&lt;br /&gt;
::0 = Deaktiviert den RB port change interrupt&lt;br /&gt;
*Bit 2 '''TMR0IF''': TMR0 Overflow Interrupt Flag Bit&lt;br /&gt;
::1 = TMR0 Register ist Übergelaufen (muss per Software resetet werden)&lt;br /&gt;
::0 = TMR0 register ist nicht Übergelaufen&lt;br /&gt;
*Bit 1 '''INT0IF''': RB0/INT External Interrupt Flag Bit&lt;br /&gt;
::1 = Eine Änderung an RB0/INT hat stattgefunden (muss per Software resetet werden)&lt;br /&gt;
::0 = Eine Änderung an RB0/INT hat nicht stattgefunden &lt;br /&gt;
*Bit 0 '''RBIF''': RB Port Change Interrupt Flag bit&lt;br /&gt;
::1 = Mind. einer der Pins von RB7:RB4 hat sich geändert (muss per Software resetet werden)&lt;br /&gt;
::0 = Keiner der Pins von RB7:RB4 hat sich geändert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*) Die Flanke auf die Reagiert wird mit dem Bit OPTION_REG.INTEDG (pos. = 1 oder neg. = 0) geändert&lt;br /&gt;
**) Der Interrupt klingt verführerischer Weise so, als ob er den gesamten Port überwacht. Dabei reagiert er nur auf RB7:RB4!!!!&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11189</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11189"/>
				<updated>2007-04-11T13:48:46Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11188</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11188"/>
				<updated>2007-04-11T13:47:44Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11187</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11187"/>
				<updated>2007-04-11T13:46:47Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11186</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11186"/>
				<updated>2007-04-11T12:34:10Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[PIC Assembler#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers]]&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11185</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11185"/>
				<updated>2007-04-11T12:31:35Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11184</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11184"/>
				<updated>2007-04-11T12:29:56Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::::&lt;br /&gt;
&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11183</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11183"/>
				<updated>2007-04-11T12:29:37Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11182</id>
		<title>PIC Assembler</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PIC_Assembler&amp;diff=11182"/>
				<updated>2007-04-11T12:29:20Z</updated>
		
		<summary type="html">&lt;p&gt;Der Gärtner: /* STATUS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einladung zur Diskussion... =&lt;br /&gt;
&lt;br /&gt;
Es wird hier versucht die ASM Programmierung von PIC Mikrocontroller zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Damit das enstehende Artikel wirklich nutzlich  wird, ist Ihre Mitwirkung nötig. Bitte schreib uns Deine Meinung, was ewentuell noch geändert (z.B. ergänzt) werden soll in diesem Tread:&lt;br /&gt;
&lt;br /&gt;
http://www.roboternetz.de/phpBB2/viewtopic.php?p=271211#271211&lt;br /&gt;
&lt;br /&gt;
Die Autoren bedanken sich im voraus für jeden Beitrag mit Vorschlägen !&lt;br /&gt;
&lt;br /&gt;
= Einführung =&lt;br /&gt;
&lt;br /&gt;
== Bit, Byte, Nibble, Bin und Hex ==&lt;br /&gt;
&lt;br /&gt;
Ein Mikrocontroller (kurz: µC) kann eigentlich nur durch ein Portpin eine Spannung einlesen bzw. ausgeben. Er kann aber nur erkennen, ob eine Spannung vorhanden ist oder nicht. Wenn fast keine Spannung vorhanden ist erkennt er das als 0 und wenn eine Spannung fast so gross, wie seine Versorgungsspannung anliegt, als 1.&lt;br /&gt;
&lt;br /&gt;
Genauso bei der Ausgabe, wenn er 0 ausgibt ist auf dem Portpin fast keine Spannung, wenn 1, eine Spannung fast gleich gross seiner Versorgungsspannung. Und das ist ein Bit, die kleinste Menge einer Information. Das Bit ist binär, weil er nur zwei unterschiedliche Werte 0 bzw. 1 haben kann.&lt;br /&gt;
&lt;br /&gt;
Wenn wir gleichzeitig (paralell) 8 Bits haben, dann ist es ein Byte, der mehrere Bitkombinationen von 00000000b bis 11111111b enhält, weil ein Bit (X) auf jeder Stelle 0 bzw. 1 sein kann.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#007fff&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;b&amp;quot; bedeutet, das es sich um binäre (kurz: bin) Darstellung (auch Zahl genannt) handelt. Binäre Zahlen sind aber lang, weil jedes Bit eine Stelle benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die Schreibweise zu verkürzen, wurden hexadezimale (kurz: hex) Zahlen eingeführt. Zuerst wurde ein Byte auf zwei 4-Bit Halbbytes (Nibbles) verteilt und danach ein Nibble als Ziffer genommen. Weil 4 Bit mehr als 10 Kombinationen ergeben, haben die Ziffer 0 bis 9 aus dem Dezimalsystem nicht ausgereicht und wurden um Buchstaben A bis F erweitert. Die hexadezimalen Zahlen haben ein &amp;quot;h&amp;quot; Zeichen am Ende.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung zwischen bin und hex Zahlen für ein Nibble zeigt folgende Tabelle:&lt;br /&gt;
&lt;br /&gt;
             0b = 0h           100b = 4h          1000b = 8h          1100b = Ch&lt;br /&gt;
             1b = 1h           101b = 5h          1001b = 9h          1101b = Dh&lt;br /&gt;
            10b = 2h           110b = 6h          1010b = Ah          1110b = Eh&lt;br /&gt;
            11b = 3h           111b = 7h          1011b = Bh          1111b = Fh&lt;br /&gt;
&lt;br /&gt;
Damit kann ein Byte mit zwei hex Ziffern definiert werden z.B. 1100 0011b = C3h. Für zwei Bytes braucht man 4 hex Ziffern z.B.&lt;br /&gt;
&lt;br /&gt;
101 0111 1010 1001b = 57A9h, u.s.w. So wie im Dezimalsystem werden führende Nullen nicht geschrieben, aber in einem PIC Register existieren immer 8 Bits also auch führende Nullen. Zum Beispiel die hex Zahl 3h sieht im Register so aus: 00000011b. Bei einer Wandlung bin-&amp;gt;hex fängt man immer von der rechten Seite der bin Zahl an, da die Anzahl führenden Nullen unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
== Speicher und Register ==&lt;br /&gt;
&lt;br /&gt;
Als Speicher bezeichnet man ein Teil der Hardware, in die eine Information eingeschrieben, in der gespeichert und aus der wieder ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Es gibt eigentlich nur zwei Arten von elektronischen Speicher: flüchtige und nichtflüchtige. Die Information die sich im flüchtigen Speicher befindet, geht verloren, wenn die Versorgungsspannung des Speichers unterbrochen oder abgeschaltet wird. Bei PICs ist es Dataspeicher (RAM).&lt;br /&gt;
&lt;br /&gt;
Wenn die Versorgungsspannung vom nichtflüchtigen Speicher abgeschaltet wird, ist die gespeicherte Information zwar momentan nicht lesbar, bleibt aber erhalten und sobald der Speicher wieder mit Spannung versorgt wird, kann sie ausgelesen werden. Ein PIC hat zwei solche Speicher: Programmspeicher (Flash) und EEPROM.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zwischen den Speicherarten ist, das die flüchtigen direkt (sehr schnell) beschreibbar sind und das Beschreiben den nichtflüchtigen benötigt spezielle Algorithmen, die leider im Vergleich zu direkten Zugriffen langsamer sind.&lt;br /&gt;
&lt;br /&gt;
Ein Speicher besitzt bestimmte Menge von s.g. Speicherstellen. Jede Speicherstelle hat seine individuelle Adresse und kann eine binäre Information mit bestimmter Anzahl von Bits abspeichern. &lt;br /&gt;
&lt;br /&gt;
Bei PIC haben die drei Arten von Speicher, wegen verschiedener Anwendung, auch unterschiedliche Struktur. Die beiden Speicher für Daten (RAM und EEPROM) haben jeweils 8-bitigen und Programmspeicher (Flasch) bei Mid-Range hat 14-bitigen Speicherstellen. Die Anzahl den Speicherstellen im bestimmten Speicher ist vom PIC-Typ abhängig.&lt;br /&gt;
&lt;br /&gt;
Eine 8-bitige Speicherstelle im RAM wird bei PICs Register genannt und kann so skiziert werden:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;table border=0 cellpadding=3 cellspacing=2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=middle bgcolor=&amp;quot;#CCCCCC&amp;quot; style=&amp;quot;border:1px solid #333333&amp;quot;&amp;gt;X&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; MSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=6&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt; LSB &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 6&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 4&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#007fff&amp;quot;&amp;gt;bit 0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;High Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=4 align=middle bgcolor=#ff8305&amp;gt;Low Nibble &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=8 align=middle bgcolor=#810f40&amp;gt; &amp;lt;font color=#ffffff&amp;gt;Byte&amp;lt;/font&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der bit 7 wird als hochwertigste (MSB = Most Significant Bit) und bit0 als niederwertigste (LSB = Least Significant Bit) bezeichnet. Jeder Bit im Register (X) kann gleich 0 bzw. 1 sein.&lt;br /&gt;
&lt;br /&gt;
Um ein Databyte in ein Register schreiben oder aus einem Register lesen, muss zuerst das Register durch seine Adresse gewählt werden. Dafür gibt es beim PIC folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per absolute Adresse:   movwf   0x20&lt;br /&gt;
&lt;br /&gt;
Direkte Adressierung per vorher definierten Namen des Registers (z.B. Temp  equ  0x20):   movwf   Temp&lt;br /&gt;
&lt;br /&gt;
Indirekte Adressierung durch FSR Register, in den die absolute Adresse des Registers Temp eingeschrieben wird und der Wert aus dem Temp sich im INDF Register befindet. Wie vorher wurde Temp  equ  0x20  definiert und weiter:&lt;br /&gt;
&lt;br /&gt;
       movlw   Temp      ;in W-Register wird die absolute Adresse des Registers Temp geladen&lt;br /&gt;
       movwf   FSR       ;diese Adresse wird in das FSR Register kopiert&lt;br /&gt;
       movf    INDF,0    ;der Wert aus dem indirekt adressierten Register Temp wird in das&lt;br /&gt;
                          W-Register geladen.&lt;br /&gt;
&lt;br /&gt;
Weil in jedem 14-bittigem Befehl, der mit Datenspeicher verbunden ist, fur Adresse des ansprechenden Registers nur 7 Bits existieren, die bis zum 7Fh (128d) Register direkt ansprechen können, ist bei PICs der Datenspeicher (RAM) in s.g. Banken verteilt.&lt;br /&gt;
&lt;br /&gt;
Für Aswahl einer Bank sind zwei Bits RP0 und RP1 im STATUS Register zuständig. Die Anzahl von Bänke und ihre Verwendung ist von gesamter Grösse des RAMs abhängig und kann dem Datenblatt des PICs entnommen werden. Siehe: [[#Speicherbankorganisation|Speicherbankorganisation]]&lt;br /&gt;
&lt;br /&gt;
== Prozessor ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von Mid-Range PICs gehört zu den RISC (Reduced Instruction Set Computer) Prozessoren und man hat nur 35 Befehle zu Erlernen, was seine Programmierung deutlich vereinfacht. Jeder Befehl benötigt im Programmspeicher nur eine Speicherstelle und im Quellcode nur eine Zeile. Die Ausführung des Befehls dauert, abhängig vom Befehl zwischen 1-2 Prozessortakten.&lt;br /&gt;
&lt;br /&gt;
Die Prozessoren der Mid-Range Serie von Microchip sind alle in der &amp;quot;Harvard&amp;quot;-Architektur gefertigt. Das Bedeuted, dass der Datenspeicher und Programmspeicher einen eigenen Bus zur CPU besitzen. Der Vorteil zur &amp;quot;von Neumann&amp;quot;-Architektur ist, dass sich die Busgrößen damit unterscheiden können. Das ermöglicht eine größere Bandbreite.&lt;br /&gt;
&lt;br /&gt;
Der Befehl (beim PIC 14 bit) kann in nur einem Takt verarbeitet werden. Daher kommt auch das Aufteilen der Ausführung des Befehls in die 4 verschiedenen Vörgänge. Wärend der neue Befehl eingelesen (&amp;quot;gefatched&amp;quot;) wird, wird der Vorige gerade gelesen (&amp;quot;read&amp;quot;) und der Vorvorige verarbeited (&amp;quot;executed&amp;quot;) und der Vorvorvorige schreibt gerade in den Datenspeicher (&amp;quot;write&amp;quot;). Das heist 4 Befehle werden jeweils um einen Oszillatortaktzyklus verschoben gleichzeitig verarbeitet.&lt;br /&gt;
&lt;br /&gt;
Das  geschieht in vier Perioden des Oszillators. Deswegen die Taktfrequenz des CPUs entspricht durch 4 geteilter Frequenz des Oszillators.&lt;br /&gt;
                 &lt;br /&gt;
                 CPU Vorgang                   Richtung   Speicher&lt;br /&gt;
                 -------------------------------------------------   -&lt;br /&gt;
                 1.Befehl lesen (fatch)        &amp;lt;-------   Flash       |&lt;br /&gt;
                 2.Daten lesen (read)          &amp;lt;-------   RAM         | 1 Prozessortakt =&lt;br /&gt;
                 3.Daten verarbeiten (execute)                        | 4 Oszillatortakte&lt;br /&gt;
                 4.Daten schreiben (write)     -------&amp;gt;   RAM         |  &lt;br /&gt;
                                                                     -&lt;br /&gt;
&lt;br /&gt;
Nur o.g. CPU Vorgänge sind direkt möglich. Es können deswegen keine Befehle aus dem RAM oder EEPROM ausgeführt werden. Um ein Databyte aus einem RAM Register in ein anderes zu kopieren, muss er zuerst aus dem ersten RAM Register in das W-Register (eigenen s.g. Arbeitsregister des CPU) und erst davon in das zweite RAM Register kopiert werden. &lt;br /&gt;
&lt;br /&gt;
Das Lesen/Schreiben aus/in den EEPROM Speicher ist mit Hilfe speziellen Register und Unterprogrammen bei allen Mid-Range PICs möglich. Der Lese und Schreibzugriff auf den Programmspeicher ist aber nur bei wenigen PIC-Typen (z.B. PIC16F87X) möglich. Dies ermöglicht ein &amp;quot;sich selbst Programmieren&amp;quot;, was bei Bootloadern genützt wird.&lt;br /&gt;
&lt;br /&gt;
== Assembler ==&lt;br /&gt;
&lt;br /&gt;
Die Maschinensprache, auch Assembler oder kurz ASM genannt, ist eine Sprache die nur bestimmter CPU versteht. Für einen Menschen ist sie unverständlich, da sie nur aus hex Zahlen besteht.&lt;br /&gt;
&lt;br /&gt;
Um sich die Sprache verständlicher zu machen wurden den hex Zahlen s.g. Mnemonics aus Buchstaben zugewiesen. Jeder Befehl für einen CPU hat somit ein &amp;quot;Namen&amp;quot;, der aus englischer Sprache stammt. Siehe: [[#Kurzübersicht Assembler Befehle|Kurzübersicht Assembler Befehle]]&lt;br /&gt;
 &lt;br /&gt;
Obwohl sie 200 bis 1000 mal schneller als die meisten Hochsprachen ist, wird sie wegen dem grossen Aufwand bei Erstellung umfangreichen Programmen, selten benutzt. Man findet sie aber oft in fast allen Hochsprachen, in eigebundenen Funktionen, überall dort wo die Hochsprachen zu langsam sind oder nötigen Aufgaben (z.B. Maus in Q-Basic) nicht unterstützen.&lt;br /&gt;
&lt;br /&gt;
ASM eignet sich aber sehr gut für kleine Anwendungen (meistens Steuerungen) mit µC, weil nur bei dieser Programmiersprache ein direkter Zusammenhang zwischen einem bit im Programm und einer Spannung am I/O Pin besteht.&lt;br /&gt;
&lt;br /&gt;
Dank der integrierten oder an Portpins angeschlosenen Hardware und dem entsprechenden Program kann ein µC umfangreiche Aufgaben realisieren, die fast unbegrenzt und schwer vorstellbar sind.&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe eines ASM-Programmierers ist,  ein Programm zu schreiben, das das Assemblerprogramm (z.B. MPASM) fehlerfrei in die Machinensprache &amp;quot;übersetzt&amp;quot; und der bestimmte CPU &amp;quot;versteht&amp;quot;. Sie endet eigentlich erst dann, wenn das geschriebene Programm so wie geplannt funktioniert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PAD_beispiel.png|thumb|80px|Beispiel für ein PAD]]&lt;br /&gt;
&lt;br /&gt;
Weil ASM Programme nicht besonders durchschaubar sind, wurde als Hilfsmittel ein Programmablaufdiagramm (kurz: PAD) erfunden. Beim Programmerstellung fängt man damit an ein PAD zu erstellen, das die wichtigsten Programmschritte enthält.&lt;br /&gt;
&lt;br /&gt;
Weiter werden alle Befehle nach dem PAD mit einem üblichen Texteditor in eine Textdatei mit Erweiterung .asm (Quellcode) geschrieben, durch ein Assemblerprogramm (für PICs: MPASM oder [http://gputils.sourceforge.net/ GPASM]) von dem für Menschen noch verständlichen Code in die Maschinensprache &amp;quot;übersetzt&amp;quot; und als Texdatei mit Erweiterung .hex gespeichert. Diese Datei wird danach in den Programmspeicher des µC übertragen (&amp;quot;gebrannt&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm MPASM kann kostenlos von der Homepage des Herstellers von PICs [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002] runtergeladen werden. Es muss zuerst vom Downloads die &amp;quot;MPLAB IDE v7.50 Full Zipped Installation&amp;quot; runtergeladen und erst danach können gewählte Programme (z.B. nur MPASM) intalliert werden. Für MPASM benutzer werden auch folgende .pdf Dateien empfohlen:&lt;br /&gt;
&lt;br /&gt;
MPASM/MPLINK User's Guide (2628 KB) [Benutzerhandbuch]    &lt;br /&gt;
&lt;br /&gt;
MPASM™/MPLINK™ PICmicro® Quick Chart (81 KB) [Kurzübersicht]    &lt;br /&gt;
   &lt;br /&gt;
Nach dem Eischalten der Betriebsspannung des µC, fängt der CPU an, sich im Programmspeicher befindliches Programm mit dem Befehl, der an der Adresse 0 steht, auszuführen.&lt;br /&gt;
&lt;br /&gt;
Aber wann das Programm endet? Natürlich wenn die Versorgungsspannung abgeschaltet wird. Nein! Das ist die einfachste Lösung um ein laufendes Programm auf zufälliger Stelle zu unterbrechen,&lt;br /&gt;
aber keine um ihn auf einer definierten Stelle zu beenden.&lt;br /&gt;
&lt;br /&gt;
Wenn an den µC angeschlossene externe Hardware (z.B. Grafikdisplay), eine bestimmte Befehlsfolge vor dem Abschalten benötigt oder wichtige Daten (in EEPROM oder Flash) abgespeichert werden sollen, darf die Spannung erst dann abgeschaltet werden, wenn der CPU eine Meldung ausgibt, dass er sich schon auf der &amp;quot;STOP&amp;quot; Stelle des Programms befinet. Es muss auch&lt;br /&gt;
definiert werden (z.B. durch eine Tastenkombination), wann der CPU zum letzten Fragment des ASM Programms vor dem &amp;quot;STOP&amp;quot; gehen soll.&lt;br /&gt;
&lt;br /&gt;
== Grundbeschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der Prozessor von einem PIC kann sofort nach dem Einschalten der Versorgungsspannung(+5VDC) arbeiten. Allerdings nur, wenn er den Takt, in dem er die Befehle ausführen soll, vorgegeben hat. Manche PICs besitzen einen internen RC-Oszillator, (z.B. PIC12F629, PIC16F630, PIC16F628, u.s.w.). Bei diesen reicht es bereits Spannung anzulegen und sie laufen bereits. Die meisten haben ihn aber nicht (z.B. PIC16F84, PIC16F870, u.s.w.) und brauchen fürs Funktionieren zusätzliche Bauteile (Widerstand + Kondensator (RC), Quarz + 2 Kondensatoren (HS oder XT) oder Keramik-Resonator(HS oder XT), bzw. Quarzoszillator) die an Pins OSC1/OSC2 angeschlossen werden um notwendigen Prozessortakt zu erzeugen. Durch das Konfiguration-Word muss noch angegeben werden, welcher Oszillator verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Desweiteren existiert ein MCLR-Pin, der beim PIC einen Neustart (=Reset) auslösen kann (Low-Pegel). Diesen Pin sollte man, wenn er in &amp;quot;__config&amp;quot; aktiviert ist, über einen Widerstand (pull-up) an +5V legen, damit der PIC anfängt, sein Programm abzuarbeiten. Der Anschluss wird auch für die Programmierung benötigt. Beim sog. High-Voltage-Programming wird MCLR auf ca. 12-14 Volt gelegt, um den PIC in den Programmiermodus zu schalten. Bei manchen PICs kann dieser Anschluss auch als normalen I/O Pin eingestellt werden. In dem Fall, bei ICSP Benutzung, soll noch eine Diode zwischen den pull-up und +5V angeschlossen werden, um die an MCLR Pin angeschlossene Hardware während der Programmierung zu schützen. &lt;br /&gt;
&lt;br /&gt;
Bei externen Oszillatoren bleibt der Pin OSC2 nicht angeschlossen und kann als I/O benutzt werden. Falls ein interner Oszillator benutzt wird, können beide OSC Pins als I/O dienen.&lt;br /&gt;
&lt;br /&gt;
Damit ein Programm zuverlässig ausgeführt werden kann, muss die Versorgungspannung störungsfrei sein. Dafür wird ein Keramik-Vielschicht-Kondensator 100 nF möglichts am kürzesten direkt zwischen VDD und VSS Pins geschaltet.&lt;br /&gt;
&lt;br /&gt;
Folgende Skizzen zeigen die Grundbeschaltung eines PICs:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Pic-entstoer.png|thumb|160px|Entstörkondensator beim PIC]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qz-os.png|thumb|160px|Quarz ]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Qos-os.png|thumb|160px|externer Quarzoszillator]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Rc-os.png|thumb|160px|externer RC-Oszillator]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Wahl des PICs ==&lt;br /&gt;
&lt;br /&gt;
Es gibt PIC µC die im Typenbezeichnung den Buchstaben &amp;quot;C&amp;quot; oder &amp;quot;F&amp;quot; haben.&lt;br /&gt;
&lt;br /&gt;
Die älteren mit &amp;quot;C&amp;quot; haben EPROM Programmspeicher und die gibt es in zwei Versionen: ohne und mit Fenster (aus Quarz-Glass) fürs Löschen des EPROMs mit UV Strahlung. Bei denen ohne Fenster kann der Programmspeicher nur einmal beschrieben und nicht mehr gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die neuen mit &amp;quot;F&amp;quot; besitzen einen Flash-Programmspeicher, der bis zu 100 000 mal mit angelegter Spannung gelöscht und danach neu beschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
Für die Wahl eines PICs für bestimmte Anwendung wichtig sind:&lt;br /&gt;
 &lt;br /&gt;
- Max. Taktfrequenz des Prozessors.&lt;br /&gt;
&lt;br /&gt;
- Grösse des Datenspeichers (für Variablen).&lt;br /&gt;
&lt;br /&gt;
- Grösse des Programmspeichers (für Programm).&lt;br /&gt;
&lt;br /&gt;
- Integrierte Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Freie I/O Pins für externe Hardware (Display, Tasten, u.s.w.).&lt;br /&gt;
&lt;br /&gt;
- Vorhandene Betriebspannung (Netzteil, Akku, Batterie).&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird meistens für die Programmerstellung ein grösserer PIC genommen (wenn möglich pinkompatibler z.B. PIC16F628 für PIC16F84 oder PIC16F630 für PIC12F629) und erst nach der Optimierung des lauffägiges Programms, der tatsächlich nötiger, da seine Parameter am Anfang nur geschätzt werden können. Wenn man viel Programme für verschiedene PICs entwickelt, optimal wäre der grösste PIC16F877 mit 20 MHz max. Taktfrequenz. &lt;br /&gt;
&lt;br /&gt;
Diese Lösung hat auch den Vorteil, dass während der Programmerstellung kurze Hilfsprogramme (z.B. PIC Trainer) in den Programmspeicher kopiert und benutzt werden können, da sie sowohl ein bischen Programmspeicher und RAM als auch 2 freie I/O Pins fürs PIC Miniterminal brauchen.&lt;br /&gt;
&lt;br /&gt;
= Programm =&lt;br /&gt;
&lt;br /&gt;
== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Jedes Program kann man auf klenere Fragmente unterteilen, die auf bestimmter Weise miteinander verknüpft sind und gemeinsam die Aufgabe des Programms erfüllen. Das wichtigste Teil eines Programms ist s.g. Hautprogram (kurz:HP), das eine führende Rolle spielt. Dem HP sind fast alle andere Programmteile untergeordnet (weiter als Unterprogramm (kurz:UP) genannt) und werden nach Bedarf von ihm aufgerufen um eine bestimmte Aufgabe zu erledigen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur eines Programs ist aber komplizierter, da ein UP kann auch ein oder mehrere UPs nacheinander aufrufen. Ganz unten sind die UP1s, die ganz einfache Sachen erledigen. Höher ist das nächste Ebene mit UP2s die schon mehr komplizierten Aufgaben durch ein Aufruf der UP1s erledigen können, u.s.w. Bei Mid-Range PICs (12FXXX und 16FXXX) können maximal bis zu 8 Ebenen benutzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:HP-UP.png|Hauptprogramm - Unterprogramm]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann jederzeit aufgerufen werden, je nach dem was gerade eledigt werden muss. Weil das nicht egal ist, welches UP augerufen wird, da jedes nur eine bestimmte Funktion im Programm hat, muss der Programmierer dafür sorgen, dass alles richtig nach Programablaufdiagramm, und nicht chaotisch, abläuft.&lt;br /&gt;
&lt;br /&gt;
Die Programmierung in ASM ist änlich wie bei Hochsprachen, wenn man sich Bibliotheken mit Prozessorspezifischen UPs erstellt. Um ein lauffähiges Programm zu erstellen, braucht man nur benötigte UPs ins Program kopieren und ein geignetes HP, das sie aufruft, schreiben.&lt;br /&gt;
&lt;br /&gt;
Ein ASM Programm (Quellcode) muss in einer Texdatei .asm in der vom Assemblerprogramm erwarteter Form verfasst werden, um fehlerfreie Konvertierung in die Maschinensprache (Assemblierung) zu gewährleisten. Dieses Prozess verläuft in der Form eines Dialoges.&lt;br /&gt;
&lt;br /&gt;
Der Programmierer schreibt und gibt es dem Assemblerprogram zum Übersetzen. Alles was das Programm nicht versteht oder nicht richtig ist, erscheint als Fehlermeldungen, die der Programmierer kennen muss um die Fehler korrigieren zu können. Eine .hex Datei wird erst dannn erstellt, wenn das Assemblerprogramm keine Fehler mehr im Quellcode findet. Deswegen sehr wichtig ist, sich mit dem Assemblerprogramm vertaut zu machen, um die Dialogzeit zu minimieren.&lt;br /&gt;
&lt;br /&gt;
== Programmdurchlaufdiagramm ==&lt;br /&gt;
&lt;br /&gt;
Der Programdurchlaufdiagram (kurz: PAD) ist eine vorläufige und laufend änderbare Stufe zwischen einer Idee und ihrer Verwirklichung. Er wird erst dann fertig, wenn nach ihm erstelltes ASM Program auf einem µC so wie gewünscht funktioniert. Jedes sein Symbol (ausser &amp;quot;Start/Stop&amp;quot;) muss später als Befehlsreihenfolge für den bestimmten CPU in den Quellcode übertragen werden. Die Anschriften &amp;quot;Ein&amp;quot; und &amp;quot;Aus&amp;quot; gehören nicht zu Symbolen des PADs und wurden nur zur Erklärung benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD ist sehr eifach zu erstellen, weil dafür nur drei Symbole benötigt sind:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Bild:PAD_kurz.png|Symbole des PAD]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Das &amp;quot;Start/Stopp&amp;quot; Symbol bedeutet, dass das gesamte Programm sich im stabilen Zustand befindet und nicht &amp;quot;läuft&amp;quot;. Anstatt &amp;quot;Stopp&amp;quot; kann auch &amp;quot;Schlaf&amp;quot; (Sleep) agewendet werden, da das Programm in dem Fall auch nicht aktiv ist. Das &amp;quot;Tun&amp;quot; Symbol stellt meistens ein UP mit Reihenfolge von Befehlen dar. Das &amp;quot;Prüfen&amp;quot; bedeutet eine Prüfung bestimmter Bedingung und abhängig davon einen weiteren Lauf eines Programms, endweder in der &amp;quot;ja&amp;quot; (J) oder &amp;quot;nein&amp;quot; (N) Richtung. &lt;br /&gt;
&lt;br /&gt;
Als allgemeinnutziges Standard für µCs kann man folgender PAD bezeichnen:&lt;br /&gt;
&lt;br /&gt;
 PAD                                _____&lt;br /&gt;
                                   /     \&lt;br /&gt;
         Spannung ein (Ein) -----&amp;gt;( Start )&lt;br /&gt;
                                   \_____/&lt;br /&gt;
                                      |                   -&lt;br /&gt;
                                      V                    |&lt;br /&gt;
                              .---------------.            |&lt;br /&gt;
                              |Initialisierung|            |&lt;br /&gt;
                              '---------------'            |&lt;br /&gt;
                                      |                    |&lt;br /&gt;
                           +---------&amp;gt;|                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |  .---------------.            |&lt;br /&gt;
                           |  | Hauptprogramm |            |&lt;br /&gt;
                           |  '---------------'            |&lt;br /&gt;
                           |          |                    |&lt;br /&gt;
                           |          V                    |&lt;br /&gt;
                           |          |                     &amp;gt; Gesamtes Programm&lt;br /&gt;
                           |         / \                   | &lt;br /&gt;
                           |       /Ende?\____             |&lt;br /&gt;
                           |       \     /J   |            |&lt;br /&gt;
                           |         \ /      |            |&lt;br /&gt;
                           |          |       |            |&lt;br /&gt;
                           |          V       |            |&lt;br /&gt;
                           |         N|       |            |&lt;br /&gt;
                           +----------+       |            |&lt;br /&gt;
                                              V            |&lt;br /&gt;
                                      .---------------.    |&lt;br /&gt;
                                      |    Beenden    |    |&lt;br /&gt;
                                      '---------------'    |&lt;br /&gt;
                                              |            |&lt;br /&gt;
                                              V           -&lt;br /&gt;
                                            _____&lt;br /&gt;
                                           /     \&lt;br /&gt;
         Spannung aus (Aus) &amp;lt;-------------( Stopp )&lt;br /&gt;
                                           \_____/&lt;br /&gt;
&lt;br /&gt;
Das Hauptprogram wird in einer endlosen Schleife ausgeführt, die durch die Prüfung &amp;quot;Ende?&amp;quot; unterbrochen werden kann. In dem Fall wird vor dem Beenden des gesamten Programms noch ein UP &amp;quot;Beenden&amp;quot; ausgeführt, das z.B. Daten in EEPROM speichert.&lt;br /&gt;
&lt;br /&gt;
Es ist nicht nötig immer die Symbole zu zeichnen, man kann sich sie vorstellen und nur den Text schreiben. Die Prüfungen werden mit &amp;quot;?&amp;quot; gekenzeichnet und die Zeichen &amp;quot;V&amp;quot;, &amp;quot;&amp;lt;&amp;quot; und &amp;quot;&amp;gt;&amp;quot; zeigen die Richtung des weiteren Verlaufs. Dann sieht der PAD so aus:&lt;br /&gt;
&lt;br /&gt;
 PAD1                                Ein &amp;gt; Start&lt;br /&gt;
                                             V                 - &lt;br /&gt;
                                      Initialisierung           |&lt;br /&gt;
                                    /-------&amp;gt;V                  |&lt;br /&gt;
                                    |  Hauptprogramm             &amp;gt; Gesamtes Programm&lt;br /&gt;
                                    |        V                  | &lt;br /&gt;
                                    |      Ende? J &amp;gt; Beenden    |&lt;br /&gt;
                                    |        N          V      -&lt;br /&gt;
                                    |        V        Stopp &amp;gt; Aus&lt;br /&gt;
                                    \--------/&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden aus Platzgründen meistens die vereinfachten PADs benutzt.&lt;br /&gt;
&lt;br /&gt;
Der PAD1 kann aber für Hauptprogramme, die in beliebigem Moment unterbrochen werden dürfen, deutlich vereifacht werden, da die Prüfung &amp;quot;Ende?&amp;quot; ob das Hauptprogram beendet werden soll, und das UP &amp;quot;Beenden&amp;quot;, entfallen. &lt;br /&gt;
&lt;br /&gt;
Die meisten ASM Programme für µC sind deswegen nach solchem PAD erstelt:&lt;br /&gt;
&lt;br /&gt;
 PAD2                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -          &lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                   /-------&amp;gt;V          |&lt;br /&gt;
                                   |  Hauptprogramm     &amp;gt; Gesamtes Programm&lt;br /&gt;
                                   |        V          |&lt;br /&gt;
                                   \--------/         _|&lt;br /&gt;
                                        &lt;br /&gt;
Für Testprogramme wird meistens fogender PAD angewendet, weil es ziemlich einfach festzustellen&lt;br /&gt;
ist (z.B. durch Stromverbrauchmessung des µCs), wann sich der CPU schon im Schlaf befindet. Erst dann, darf die Betriebspannung des µCs ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
 PAD3                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                     Initialisierung   |&lt;br /&gt;
                                            V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf &amp;gt; Aus&lt;br /&gt;
&lt;br /&gt;
Und eine batteriebetriebene Uhr wird überwiegend so gestaltet:&lt;br /&gt;
&lt;br /&gt;
 PAD4                               Ein &amp;gt; Start&lt;br /&gt;
                                            V         -&lt;br /&gt;
                       Interrupt     Initialisierung   |&lt;br /&gt;
             Timer-------------------------&amp;gt;V           &amp;gt; Gesamtes Programm&lt;br /&gt;
                                      Hauptprogramm    |&lt;br /&gt;
                                            V         -&lt;br /&gt;
                                         Schlaf&lt;br /&gt;
&lt;br /&gt;
In dem Fall reicht es aus, wenn der CPU jede Minute vom Timer aufgeweckt wird, um die Zeit zu aktualisieren. Eine Uhr ist immer (ausser Batteriewechsel) ununterbrochen mit Spannung versorgt.&lt;br /&gt;
&lt;br /&gt;
Für komplizierte Programme ist es unmöglich ein PAD zu erstellen, in dem jeder CPU Befehl sein eigenes Symbol hat. Man beschränkt sich nur auf alle Prüfungen, die über den Lauf des Programms entscheiden, und ganze UPs (z.B. &amp;quot;Initialisierung&amp;quot;) nur als ein Symbol verwendet. Für jedes UP wird dann ein eigener PAD erstelt.&lt;br /&gt;
&lt;br /&gt;
Das Erstellen von PAD bei ASM Programmen ist sehr wichtig und darf nicht unterschätzt werden. Je stärker ein Programmierer glaubt, dass er das ohne PAD schaft, um so mehr Zeit wird er danach bei Fehlersuche oder Änderungen im ASM Programm verlieren. Für einfache ASM Programme, die gut kommentiert sind, reicht es meistens aus, ein PAD nur &amp;quot;im Kopf&amp;quot; zu erstellen, aber ganz ohne PAD geht es sicher nicht. &lt;br /&gt;
&lt;br /&gt;
Wenn ein ASM Programm nicht wie geplannt funktioniert, wird zuerst ein Fehler im PAD gesucht. Und erst wenn er i.O. ist, im als fehlerhaft festgestellten Codefragment.&lt;br /&gt;
&lt;br /&gt;
== Hauptprogramm ==&lt;br /&gt;
&lt;br /&gt;
Wie sein Namen schon vermuten lässt, ist das Hauptprogram das wichtigste Teil des gesamten Programms. Meistens ist es auch das kleinste Teil, vor allem, wenn die UPs sehr komplex sind. Seine Aufgabe ist die benötigte UPs in bestimmter Reihenfolge nachainander aufzurufen, um die alle Funktionen des gesamten Programms zu realisieren. &lt;br /&gt;
&lt;br /&gt;
Das HP ist meistens als endlose Schleife , wie im PAD2, aufgebaut. Weil die endlose Schleife sehr schnell läuft, werden die alle, die durch die UPS realisierte Aufgaben quasi gleichzeitig ausgeführt. Wenn es unerwünscht ist, müssen einige UPs als Verzögerungen realisiert werden.&lt;br /&gt;
&lt;br /&gt;
Typischer PDA für ein HP sieht so aus:&lt;br /&gt;
&lt;br /&gt;
                                           Haupt    /---&amp;gt;V&lt;br /&gt;
                                                    |   UP1&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UP2&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   ...&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    |   UPn&lt;br /&gt;
                                                    |    V&lt;br /&gt;
                                                    \----/&lt;br /&gt;
&lt;br /&gt;
In den Quellcode wird es so eigeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                          Haupt   call    UP1	&lt;br /&gt;
                                                  call    UP2&lt;br /&gt;
                                                  ...........&lt;br /&gt;
                                                  call    UPn&lt;br /&gt;
                                                  goto    Haupt&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird das HP schrittweise erstellt. Am Anfang wird sich nur ein UP im HP befinden und die folgenden kommen nach dessen Erstellung und Prüfen dazu, bis das HP fertig wird.&lt;br /&gt;
&lt;br /&gt;
== Unterprogramm ==&lt;br /&gt;
&lt;br /&gt;
Unterprogramm wird durch übergeordnetes Programmteil (Aufrufer) aufgerufen und nach seinem Ausführen, wird zurück zum Aufrufer gesprungen. Der Rückkehr zum Aufrufer wird durch &amp;quot;return&amp;quot; Befehl, der sich am Ende jedes UPs befinden muss, erreicht. Und das ist der einzige Unterschied zwischen einem HP und einem UP.&lt;br /&gt;
&lt;br /&gt;
Jedes UP hat folgender PAD:&lt;br /&gt;
&lt;br /&gt;
                                vom Aufrufer -------&amp;gt;     V&lt;br /&gt;
                                                         Tun&lt;br /&gt;
                                                          V&lt;br /&gt;
                         zurück zum Aufrufer &amp;lt;-------   return &lt;br /&gt;
&lt;br /&gt;
Ein HP von einem ASM Programm kann in anderem, mehr umfangreichem ASM Program als UP benutzt werden, wenn der sich am Ende des HPs befindlicher Befehl &amp;quot;goto&amp;quot; durch &amp;quot;return&amp;quot; ersetzt wird. Ein Beispiel dazu:&lt;br /&gt;
&lt;br /&gt;
             Haupt1  call    UP11                          Haupt1  call    UP11&lt;br /&gt;
                     call    UP21                                  call    UP21&lt;br /&gt;
                     ...........             -------&amp;gt;              ...........&lt;br /&gt;
                     call    UPn1                                  call    UPn1 &lt;br /&gt;
                     goto    Haupt1                                return &lt;br /&gt;
&lt;br /&gt;
Jetzt können wir im mehr komplexen HP (Haupt) das Haupt1 als Unterprogramm aufrufen:&lt;br /&gt;
&lt;br /&gt;
                                   Haupt    call    UP1      &lt;br /&gt;
                                            call    Haupt1&lt;br /&gt;
                                            ...........&lt;br /&gt;
                                            call    UPn&lt;br /&gt;
                                            goto    Haupt&lt;br /&gt;
&lt;br /&gt;
Jedes UP kann auch von einem anderen übergeordneten UP aufgerufen werden, wenn das was es realisiert, benötigt wird.&lt;br /&gt;
&lt;br /&gt;
In der Praxis wird oft ein UP von mehreren anderen UPs benutzt. Zum Beispiel um LCD Display zu steuern, brauchen wir entweder ein Befehl (Cmd) oder ein Zeichen (Data) an Display zu schicken. In beiden Fällen wird ein Byte geschickt, einmal mit RS=0 (Befehl) und einmal mit RS=1 (Zeichen) laut folgendem PDA:&lt;br /&gt;
&lt;br /&gt;
                                        &amp;quot;Cmd&amp;quot;   &amp;quot;Data&amp;quot; &lt;br /&gt;
                                          V       V&lt;br /&gt;
                                        RS=0    RS=1&lt;br /&gt;
                                          V       V &lt;br /&gt;
                                          \--&amp;gt;+&amp;lt;--/&lt;br /&gt;
                                              |&lt;br /&gt;
                                              V&lt;br /&gt;
                                   &amp;quot;Send&amp;quot; Byte schicken&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird z.B. in den Quellcode so eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                     Cmd     bcf     RS&lt;br /&gt;
                                             goto    Send&lt;br /&gt;
                                     Data    bsf     RS&lt;br /&gt;
                                     Send    ............&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Das UP &amp;quot;Send&amp;quot; ist den UPs &amp;quot;Cmd&amp;quot; und &amp;quot;Data&amp;quot; untergeordnet, da es von beiden benutzt wird, kann aber weder &amp;quot;Cmd&amp;quot; noch &amp;quot;Data&amp;quot; benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Initialisierung ===&lt;br /&gt;
&lt;br /&gt;
Damit der PIC ein Programm asführen kann, muss er vollständig und richtig initialisiert werden. Deswegen als erstes UP, das vom HP aufgerufen wird , ist &amp;quot;Initialisierung&amp;quot; (kurz: Init)&lt;br /&gt;
&lt;br /&gt;
==== Variablen ====&lt;br /&gt;
&lt;br /&gt;
Weil nach dem Einschalten der Spannung im RAM sich zufällige Werte befinden, wird meistens als erstes, der benutzte Bereich des RAMs (z.B. 20h bis 7Fh) gelöscht. Es wird einfach und sparsam mit einer Schleife, die indirekte Adressierung verwendet, gemacht:&lt;br /&gt;
&lt;br /&gt;
                                                   V&lt;br /&gt;
                             Adresse des ersten Registers in FSR laden (20h)&lt;br /&gt;
                             /--------------------&amp;gt;V&lt;br /&gt;
                  RAMClr     |Indirekt adressierter Register löschen (INDF)&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |              Adresse erhöhen&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             |        Letzte Adresse + 1 (80h) J&amp;gt;Return&lt;br /&gt;
                             |                     N&lt;br /&gt;
                             |                     V&lt;br /&gt;
                             \---------------------/&lt;br /&gt;
&lt;br /&gt;
Es wird wie folgt in Quellcode eingeschrieben:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x20&lt;br /&gt;
                                             movwf   FSR&lt;br /&gt;
                                    RAMClr   clrf    INDF&lt;br /&gt;
                                             incf    FSR,1&lt;br /&gt;
                                             btfss   FSR,7&lt;br /&gt;
                                             goto    RAMClr&lt;br /&gt;
                                             return&lt;br /&gt;
&lt;br /&gt;
Danach können den benötigtenen Variablen die gewünschte Werte angegeben werden:&lt;br /&gt;
&lt;br /&gt;
                                             movlw   0x3C&lt;br /&gt;
                                             movwf   LimH&lt;br /&gt;
                                             movlw   0x5A&lt;br /&gt;
                                             movwf   LimL&lt;br /&gt;
                                             u.s.w.&lt;br /&gt;
&lt;br /&gt;
Somit sind die Variablen initialisiert.&lt;br /&gt;
&lt;br /&gt;
==== I/O Ports ====&lt;br /&gt;
&lt;br /&gt;
Nach dem Einschalten der Spannung sind die für Komparatoren oder A/D Wandler benutzte Pins als analoge Eingänge initialisiert.  Wenn sie alle als digitale I/Os verwendet werden sollen, müssen sie als solche definiert werden. Das geschieht durch Eischreiben in entsprechenden Register (CMCON bzw. ADCON1) des Wertes 0x07:&lt;br /&gt;
&lt;br /&gt;
                      movlw   0x07             b.z.w.           movlw   0x07             &lt;br /&gt;
                      movwf   CMCON                             movwf   ADCON1&lt;br /&gt;
&lt;br /&gt;
Wenn einige als Analoge Eingänge benutzt werden sollen, mussen die entsprechende Werte dem Datenblatt des jeweiligen PICs entnommen werden. &lt;br /&gt;
&lt;br /&gt;
Danach werden alle Ports nacheinander gelöscht und die gewünschte Werte die an den Pins vor dem Start des Hauptprogramms ausgegeben werden sollen, geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                       clrf    PORTA&lt;br /&gt;
                                       movlw   0x37&lt;br /&gt;
                                       movwf   PORTA &lt;br /&gt;
                                       usw.&lt;br /&gt;
&lt;br /&gt;
Anchliessend werden für jeden Port die Werte in TRIS Register eingeschrieben, wobei ein Bit einem Pin entspricht. Ein Pin wird in TRIS Register durch 1 als Eingang und durch 0 als Ausgang definiert. Beispielweise beim PORTB sollen B7,B5 und B3 als Eingänge und restliche Pins als Ausgänge definiert werden. Das ergibt den Wert 10101000b = A8h, der in den TRISB Register geschrieben werden muss. Weil die alle TRIS Register sich in der Bank1 befinden, muss im STATUS-Register auf Bank1 und danach zurück auf Bank 0 umgeschaltet werden:&lt;br /&gt;
&lt;br /&gt;
                                       bsf     STATUS,RP0&lt;br /&gt;
                                       movlw   0xA8&lt;br /&gt;
                                       movwf   TRISB&lt;br /&gt;
                                       bcf     STATUS,RP0&lt;br /&gt;
&lt;br /&gt;
Bei einem Umschalten der Bank können selbstverständlich alle TRIS Register nacheinander beschrieben werden.&lt;br /&gt;
&lt;br /&gt;
==== Hardware ====&lt;br /&gt;
&lt;br /&gt;
Die für ASM Programm benutzte Hardware kann auf integrierte und externe geteilt werden. Für eine Initialisierung der integrierten Hardware (Komparatoren, A/D Wandler, Timer, USART, I²C, SPI, PWM, u.s.w.), müssen entsprechende SFRs (Spezial Function Registers) laut Datenblatt des PICs definiert werden.&lt;br /&gt;
&lt;br /&gt;
Die externe Hardware muss nach Datenblättern der Herstellern initialisiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Einlesen ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit von einem Portpin einzulesen und in ein bestimmtes Register zu Kopieren wird folgender PAD benutzt, weil ein PIC kein Befehl dafür hat:&lt;br /&gt;
&lt;br /&gt;
                                             V&lt;br /&gt;
                               Bit im Zielregister löschen&lt;br /&gt;
                                             V&lt;br /&gt;
                                    Quellbit = 0 ? J&amp;gt;-------\&lt;br /&gt;
                                             N              |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                Bit im Zielregister setzen  |&lt;br /&gt;
                                             V              |&lt;br /&gt;
                                             +--------------/&lt;br /&gt;
                                             V&lt;br /&gt;
&lt;br /&gt;
Wenn wir z.B. ein bit3 von PortA als bit1 in den Register Tasten kopieren wollen, dann wird es in Quellcode so geschrieben:&lt;br /&gt;
&lt;br /&gt;
                                        bcf     Tasten,1&lt;br /&gt;
                                        btfsc   PORTA,3&lt;br /&gt;
                                        bsf     Tasten,1&lt;br /&gt;
&lt;br /&gt;
Natürlich wenn ein ganzer Byte vom Port in das W-Register eingelesen wird, kann mann den gleich in das Zielregister schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben ===&lt;br /&gt;
&lt;br /&gt;
Um ein Bit an einem Portpin auszugeben wird ein bestimmter Bit mit &amp;quot;bcf&amp;quot; gelöscht oder mit &amp;quot;bsf&amp;quot; gesetzt. Zum Beispiel bit4 im PORTA:&lt;br /&gt;
&lt;br /&gt;
                                        bcf   PORTA,4.&lt;br /&gt;
&lt;br /&gt;
Um ein Byte auszugeben wird er einfach zuerst in das W-Register geladen und danach an Port übergeben, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        movlw  0x12&lt;br /&gt;
                                        movwf  PORTA&lt;br /&gt;
&lt;br /&gt;
=== Pause ===&lt;br /&gt;
&lt;br /&gt;
Um eine Pause (Warten) im Programm anzulegen wird der &amp;quot;nop&amp;quot; Befehl benutzt, während dessen Ausführung der CPU nichts macht. Mit einem &amp;quot;nop&amp;quot; kann eine Zeit gleich 4 Takten (Perioden) des Oszillators realisiert werden. Um eine Zeit z.B. 1 Sekunde zu erreichen braucht man bei einem Quarzoscillator 4 MHz &amp;quot;nur&amp;quot; 1 000 000 Takten zu Programmieren, was in keinen Programmspeicher von PIC passt. Deswegen werden mehrfache s.g. Warteschleifen angewendet. In der Praxis werden Schleifen mit max. 3 Ebenen benutzt.&lt;br /&gt;
&lt;br /&gt;
Solche Warteschleife funktioniert nach einem im folgendem PAD abgebildetem Prinzip:&lt;br /&gt;
&lt;br /&gt;
                              Warte           V&lt;br /&gt;
                                            n * nop&lt;br /&gt;
                                              V&lt;br /&gt;
                                            P2 laden&lt;br /&gt;
                              Warte2          V&amp;lt;-----------------\&lt;br /&gt;
                                            P1 laden             |&lt;br /&gt;
                              Warte1          V&amp;lt;-------------\   |&lt;br /&gt;
                                            P0 laden         |   |&lt;br /&gt;
                              Warte0          V&amp;lt;---------\   |   |&lt;br /&gt;
                                      P0 decrementieren  |   |   |&lt;br /&gt;
                                              V          |   |   |                  &lt;br /&gt;
                                           P0 = 0 ? N&amp;gt;---/   |   |&lt;br /&gt;
                                              J              |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                      P1 dekrementieren      |   |&lt;br /&gt;
                                              V              |   |&lt;br /&gt;
                                           P1 = 0 ? N&amp;gt;-------/   |&lt;br /&gt;
                                              J                  |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                      P2 dekrementieren          |&lt;br /&gt;
                                              V                  |&lt;br /&gt;
                                           P2 = 0 ? N&amp;gt;-----------/&lt;br /&gt;
                                              J&lt;br /&gt;
                                              V&lt;br /&gt;
                                            return&lt;br /&gt;
&lt;br /&gt;
Das wird in Quellcode so aussehen:&lt;br /&gt;
&lt;br /&gt;
                                   Warte     nop&lt;br /&gt;
                                             ...&lt;br /&gt;
                                             nop&lt;br /&gt;
                                             movlw   0xXX&lt;br /&gt;
                                             movwf   P2&lt;br /&gt;
                                   Warte2    movlw   0xXX&lt;br /&gt;
                                             movwf   P1&lt;br /&gt;
                                   Warte1    movlw   0xXX&lt;br /&gt;
                                             movwf   P0      &lt;br /&gt;
                                   Warte0    decfsz  P0&lt;br /&gt;
                                             goto    Warte0&lt;br /&gt;
                                             decfsz  P1&lt;br /&gt;
                                             goto    Warte1&lt;br /&gt;
                                             decfsz  P2&lt;br /&gt;
                                             goto    Warte2&lt;br /&gt;
                                             return   							 &lt;br /&gt;
Anstatt &amp;quot;movlw   0xXX&amp;quot; kann auch &amp;quot;movf  PauseX,0&amp;quot; angewendet werden, wenn die Schleife mit verschiedenen Werten P0, P1 und P2 aus den Register Pause0, Pause1 und Pause2 benutzt wird.&lt;br /&gt;
&lt;br /&gt;
Die gesammte Anzahl den CPU Takten (N) lässt sich aus folgender Formel berechnen:&lt;br /&gt;
&lt;br /&gt;
                          N = P2 * [ P1 * (3 * P0 + 5) + 7 ] + n + 10&lt;br /&gt;
&lt;br /&gt;
und die Wartezeit (T) in Sekunden:&lt;br /&gt;
&lt;br /&gt;
                          T = 4 * N / Fosc&lt;br /&gt;
&lt;br /&gt;
Wobei:&lt;br /&gt;
&lt;br /&gt;
                          P0 = Zahl im Register P0&lt;br /&gt;
                          P1 = Zahl im Register P1&lt;br /&gt;
                          P2 = Zahl im Register P2&lt;br /&gt;
                           n = Anzahl &amp;quot;nop&amp;quot;s&lt;br /&gt;
                          10 = Ausführungszeit von &amp;quot;call&amp;quot; + &amp;quot;return&amp;quot; + 3 * (&amp;quot;movlw&amp;quot; + &amp;quot;movwf&amp;quot;)&lt;br /&gt;
                        Fosc = Frequenz des Oszillators (z.B. Quartz)&lt;br /&gt;
&lt;br /&gt;
Die &amp;quot;nop&amp;quot;s sind notwendig um jede Wartezeit einzustellen zu können.&lt;br /&gt;
&lt;br /&gt;
Mit solcher dreifachen Schleife die max. Wartezeit ist ca. 50 000 000 CPU Takten, was bei 4 MHz Quarz ca. 50 Sekunden entspricht.&lt;br /&gt;
&lt;br /&gt;
Für kürzere Wartezeiten werden doppelte oder einzelne Schleifen benutzt.&lt;br /&gt;
&lt;br /&gt;
=== Schnittstellen und Treiber ===&lt;br /&gt;
&lt;br /&gt;
Als Schnittstelle wird externe Hadware, die zum steuern eines an sie angeschlossenes &amp;quot;Gerätes&amp;quot; dient, genannt. Das ASM Programm,  das die Steuerung ermöglicht ist ein Treiber. Als Beispiel siehe: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=22749]&lt;br /&gt;
&lt;br /&gt;
=== Tabellen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Arten von Tabellen: Sprungtabellen (computed goto) die &amp;quot;goto&amp;quot; Befehle enthalten und Wertetabellen (lookup table) in denen feste Werte in &amp;quot;retlw&amp;quot; gespeichert sind. Der wichtigste Unterschied zwischen dennen ist, dass die Sprungtabellen werden mit &amp;quot;goto&amp;quot; eingesprungen und steuern den Programlauf abhängig vom Inhalt des W-Registers und  die Wertetabellen werden mit &amp;quot;call&amp;quot; aufgerufen und liefern abhängig von Inhalt des W-Registers ein Wert an den Aufrufer zurück. &lt;br /&gt;
&lt;br /&gt;
Beide werden in Programmspeicher erstellt und können vom CPU nicht geändert werden. Sie können nur bis zu 256 Speicherstellen belegen, da in den W-Register auch nur so viel veschiedenen Zahlen &amp;quot;passen&amp;quot;. Sie Fangen also (fast) immer bei einer Adresse XX00h an und enden bei XXFFh. Der Hochwertige Byte &amp;quot;XX&amp;quot; der Adresse an der sich der Anfang einer Tabelle befindet, muss vor dem Einsprung in die Tabelle ins PCLATH Register eingeschrieben werden, wenn die Tabelle weit vom Aufrufer liegt. In der Praxis werden solche Tabellen am oberen Ende des Programmspeichers angelegt, damit sie den ASM Code nicht unterbrechen.&lt;br /&gt;
&lt;br /&gt;
Eine Sprungtabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     goto   Marke0&lt;br /&gt;
                              XX01     goto   Marke1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     goto   Marke254&lt;br /&gt;
                              XXFF     goto   Marke255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              goto     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, der die Wahl wohin gesprungen wird bestimmt&lt;br /&gt;
&lt;br /&gt;
Nach ausführen der obiger Befehlsfolge, wird das ASM Programm z.B. für Twert=0x01 weiter ab Marke1 &amp;quot;laufen&amp;quot; bis es an &amp;quot;return&amp;quot; kommt. Dann springt es zurüch zum Aufrufer der Tabelle.&lt;br /&gt;
&lt;br /&gt;
Eine Wertetabelle wird so aufgebaut:&lt;br /&gt;
&lt;br /&gt;
                                 ORG  (XX-1)FF &amp;lt;--- eine Direktive für Assemblerprogramm, wo es &lt;br /&gt;
                                                    die Tabelle im Programmspeicher plazieren soll&lt;br /&gt;
                           Adresse     Inhalt&lt;br /&gt;
                           -------------------------                      &lt;br /&gt;
                 Tab1     (XX-1)FF     addwf  PCL,1&lt;br /&gt;
                              XX00     retlw  Wert0&lt;br /&gt;
                              XX01     retlw  Wert1&lt;br /&gt;
                              .......................&lt;br /&gt;
                              XXFE     retlw  Wert254&lt;br /&gt;
                              XXFF     retlw  Wert255&lt;br /&gt;
&lt;br /&gt;
Und so aufgerufen:&lt;br /&gt;
&lt;br /&gt;
                              movlw    0xXX&lt;br /&gt;
                              movwf    PCLATH&lt;br /&gt;
                              movf     TWert,0&lt;br /&gt;
                              call     Tab1&lt;br /&gt;
&lt;br /&gt;
wobei:&lt;br /&gt;
&lt;br /&gt;
                               0xXX = Hochwertiger Byte der Adresse von Tab1&lt;br /&gt;
                              TWert = ein Wert, für welchen, an den Aufrufer bestimmter&lt;br /&gt;
                                      Wert aus der Tabelle zurückgeliefert wird&lt;br /&gt;
&lt;br /&gt;
Solche Wertetabellen werden z.B. als Zeichengeneratoren für Grafikdisplays benutzt.&lt;br /&gt;
&lt;br /&gt;
=== EEPROM === &lt;br /&gt;
&lt;br /&gt;
Alle PICs besitzen EEPROM in dem je nach Typ können 64 bis 256 Databytes gespeichert werden. Weil die detalierte Beschreibung der Schreib- und Lesevorgänge ziemlich lang wäre, werden nur geprüfte UPs kurz erklärt.&lt;br /&gt;
&lt;br /&gt;
EEPROM beschreiben:&lt;br /&gt;
&lt;br /&gt;
 EEWrite         movlw	0x20	    &amp;lt;------ ab der RAM Adresse wird gespeichert&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4           &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	    &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EEWLoop         call	EEWrite1&lt;br /&gt;
 		incf	FSR,1	    &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EEWLoop&lt;br /&gt;
 		return	&lt;br /&gt;
 &lt;br /&gt;
 EEWrite1        bcf	INTCON,GIE  &amp;lt;------ Interrupts sperren&lt;br /&gt;
 		movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0  &amp;lt;------ auf Bank1 umschalten&lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		movf	INDF,0&lt;br /&gt;
 		movwf	EEDATA&lt;br /&gt;
 		bsf	EECON1,WREN&lt;br /&gt;
 		movlw	0x55&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		movlw	0xAA&lt;br /&gt;
 		movwf	EECON2&lt;br /&gt;
 		bsf	EECON1,WR&lt;br /&gt;
 		bcf	EECON1,WREN&lt;br /&gt;
 		btfsc	EECON1,WR&lt;br /&gt;
 		goto	$-1          &amp;lt;------ warten bis WR=0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		bsf	INTCON,GIE   &amp;lt;------ Interrupts erlauben&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
EEPROM lesen (zurückschreiben):&lt;br /&gt;
&lt;br /&gt;
 EERead          movlw	0x20	     &amp;lt;------ ab der Adressse werden die Bytes in RAM abgelegt		&lt;br /&gt;
 		movwf	FSR&lt;br /&gt;
 		movlw	4	     &amp;lt;------ soviel Bytes&lt;br /&gt;
 		movwf	Temp	     &amp;lt;------ Schleifenzähler&lt;br /&gt;
 EERLoop         call	EERead1&lt;br /&gt;
 		incf	FSR,1        &amp;lt;------ nächste Adresse&lt;br /&gt;
 		decfsz	Temp,1&lt;br /&gt;
 		goto	EERLoop&lt;br /&gt;
 		return&lt;br /&gt;
 &lt;br /&gt;
 EERead1         movf	FSR,0&lt;br /&gt;
 		bsf	STATUS,RP0   &amp;lt;------ auf Bank1 umschalten &lt;br /&gt;
 		movwf	EEADR&lt;br /&gt;
 		bsf	EECON1,RD&lt;br /&gt;
 		movf	EEDATA,0&lt;br /&gt;
 		bcf	STATUS,RP0   &amp;lt;------ zurück auf Bank 0 umschalten&lt;br /&gt;
 		movwf	INDF&lt;br /&gt;
 		return&lt;br /&gt;
&lt;br /&gt;
== Vorlage für MPASM ==&lt;br /&gt;
&lt;br /&gt;
 	list      P=12F629		; Prozessor definieren&lt;br /&gt;
 	include &amp;quot;P12F629.inc&amp;quot;		; entsprechende .inc Datei für MPASM&lt;br /&gt;
 	__config _CP_OFF &amp;amp; _WDT_OFF &amp;amp; _PWRTE_ON &amp;amp; _MCLRE_OFF &amp;amp; _INTRC_OSC_NOCLKOUT   ; Konfiguration&lt;br /&gt;
 #define	_DTT1	GPIO,0			; Portpins benennen&lt;br /&gt;
 #define	_CKT2	GPIO,1&lt;br /&gt;
 #define	_T3	GPIO,2&lt;br /&gt;
 #define	_RNG	GPIO,3&lt;br /&gt;
 #define	_INT	GPIO,4&lt;br /&gt;
 #define	_RL	GPIO,5&lt;br /&gt;
 SecondL	equ	0x20			; Variablen definieren (Register benennen)&lt;br /&gt;
 SecondH	equ	0x21&lt;br /&gt;
 MinuteL	equ	0x22&lt;br /&gt;
 MinuteH	equ	0x23&lt;br /&gt;
 StundeL equ	0x24&lt;br /&gt;
 StundeH equ	0x25&lt;br /&gt;
 		org 	0x0000		; Direktive für MPASM&lt;br /&gt;
 		call	Init		; rufe UP &amp;quot;Initialisierung&amp;quot; auf&lt;br /&gt;
 Haupt		............		; Hauptprogramm als endlose Schleife&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		goto	Haupt		; gehe zum Anfang des Hauptprogramms (zurück)&lt;br /&gt;
 UP1		............		; Unterprogramme&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 		############&lt;br /&gt;
 UPn		............&lt;br /&gt;
 		Eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return&lt;br /&gt;
 Init		clrf	GPIO		; lösche Port&lt;br /&gt;
 		bsf	STATUS,RP0	; auf Bank1 umschalten&lt;br /&gt;
 		call	0x3FF		; hole Kalibrationswert&lt;br /&gt;
 		movwf	OSCCAL		; kalibriere internen RC oscillator&lt;br /&gt;
 		bcf	OPTION_REG,7	; aktiviere pull-ups&lt;br /&gt;
 		movlw	0x30		; definiere Portpins GPIO, (z.B. 0-3 Aus- und 4-5 Eingänge)&lt;br /&gt;
 		movwf	TRISIO		; schreibe in TRIS Register&lt;br /&gt;
 		bcf	STATUS,RP0	; auf Bank0 umschalten&lt;br /&gt;
 		movlw	7		; schalte Komparator aus&lt;br /&gt;
 		movwf	CMCON		; und mache RA0-2 als digital I/O&lt;br /&gt;
 		............&lt;br /&gt;
 		eigener Code&lt;br /&gt;
 		............&lt;br /&gt;
 		return			; springe zurück (zum Haupt)&lt;br /&gt;
 		end			; Ende des Codes zum &amp;quot;Übersetzen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Variablen können auch kürzer mit s.g. cblock definiert werden:&lt;br /&gt;
&lt;br /&gt;
 cblock 0x20 &lt;br /&gt;
 SecondL&lt;br /&gt;
 SecondH&lt;br /&gt;
 MinuteL&lt;br /&gt;
 MinuteH&lt;br /&gt;
 StundeL&lt;br /&gt;
 StundeH&lt;br /&gt;
 endc&lt;br /&gt;
&lt;br /&gt;
Bei sehr vielen Variablen sind aber die Registeradressen nicht so übersichtlich.&lt;br /&gt;
&lt;br /&gt;
== Für anderen PIC umschreiben ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Vorraussetzung ist, das der PIC2, auf dem das vorhande ASM Programm (für PIC1) laufen soll, zumindest für das ASM Program nötige interne Hardware hat. Der Code benötigt keine Änderungen.&lt;br /&gt;
&lt;br /&gt;
Wenn der Port vom PIC2 anderen Namen hat, muss man das im Quellcode umdefinieren, z.B.:&lt;br /&gt;
&lt;br /&gt;
                                        #define   GPIO   equ   PORTB&lt;br /&gt;
                                        #define   TRISIO equ   TRISB&lt;br /&gt;
&lt;br /&gt;
Dann wird das Assemblerprogramm, wenn es GPIO findet, immer PORTB nehmen. Das gleiche Betrifft die __config Ausdrücke, die entsprechend der .ini Datei für den PIC2, geändert werden müssen. &lt;br /&gt;
&lt;br /&gt;
Das Assemblerprogramm findet sicher alles, was ihm nicht &amp;quot;passt&amp;quot; und bringt Fehlermeldungen, auf die man entsprechend reagieren muss.&lt;br /&gt;
&lt;br /&gt;
== Das erste... ==&lt;br /&gt;
&lt;br /&gt;
Hier wird detailiert das ganze Prozess der Erstellung eines ASM Programms beschrieben.&lt;br /&gt;
&lt;br /&gt;
Die Idee:&lt;br /&gt;
&lt;br /&gt;
Es gibt 4 Leds, die mit 2 Tastern gesteuert werden sollen. Nach dem Einschalten soll keine LED leuchten. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von links nach rechts &amp;quot;wandern&amp;quot; und von der letzten rechten Position wieder nach ganz linke &amp;quot;springen&amp;quot;. Solange der linke Taster gedrückt ist, sollte eine leuchtende LED von rechts nach links &amp;quot;wandern&amp;quot; und von der letzten linken Position wieder nach ganz rechte &amp;quot;springen&amp;quot;. Solange beide Taster gedrückt sind soll die leuchtende LED von links nach rechts und zurück &amp;quot;wandern&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dafür nötige Hardware zeigt folgende Skizze:&lt;br /&gt;
&lt;br /&gt;
        .-----------------------------------------------.&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                   PIC12F629                   |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        |                                               |&lt;br /&gt;
        | GPIO,3  GPIO,4  GPIO,5  GPIO,2  GPIO,1  GPIO,0|&lt;br /&gt;
        '-----------------------------------------------'&lt;br /&gt;
           4|      3|      2|      5|      6|      7|&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            |       |      .-.     .-.     .-.     .-.&lt;br /&gt;
            |       |      | |     | |     | |     | |&lt;br /&gt;
            |       |   470| |  470| |  470| |  470| |&lt;br /&gt;
            |       |      '-'     '-'     '-'     '-'&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
         \  o    \  o       |       |       |       |&lt;br /&gt;
          \       \         V -&amp;gt;    V -&amp;gt;    V -&amp;gt;    V -&amp;gt;&lt;br /&gt;
           \.      \.       -       -       -       -&lt;br /&gt;
         T1 o    T2 o  LED1 |  LED2 |  LED3 |  LED4 |&lt;br /&gt;
            |       |       |       |       |       |&lt;br /&gt;
            +-------+-------+---+---+-------+-------+&lt;br /&gt;
                                |&lt;br /&gt;
                               ===&lt;br /&gt;
                               GND&lt;br /&gt;
&lt;br /&gt;
= Midrange =&lt;br /&gt;
&lt;br /&gt;
== Kurzübersicht Assembler Befehle ==&lt;br /&gt;
&amp;lt;font style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|ADDLW||Add literal and W &lt;br /&gt;
|-&lt;br /&gt;
|ADDWF||Add W and f &lt;br /&gt;
|-&lt;br /&gt;
|ANDLW||AND literal with W &lt;br /&gt;
|-&lt;br /&gt;
|ANDWF||AND W with f&lt;br /&gt;
|-&lt;br /&gt;
|BCF||Bit Clear f &lt;br /&gt;
|-&lt;br /&gt;
|BSF||Bit Set f &lt;br /&gt;
|-&lt;br /&gt;
|BTFSC||Bit Test f, Skip if Clear &lt;br /&gt;
|-&lt;br /&gt;
|BTFSS||Bit Test f, Skip if Set &lt;br /&gt;
|-&lt;br /&gt;
|CALL||Call subroutine &lt;br /&gt;
|-&lt;br /&gt;
|CLRF||Clear f&lt;br /&gt;
|-&lt;br /&gt;
|CLRW||Clear W&lt;br /&gt;
|-&lt;br /&gt;
|CLRWDT||Clear Watchdog Timer &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|COMF||Complement f&lt;br /&gt;
|-&lt;br /&gt;
|DECF||Decrement f&lt;br /&gt;
|-&lt;br /&gt;
|DECFSZ||Decrement f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|GOTO||Go to address or label&lt;br /&gt;
|-&lt;br /&gt;
|INCF||Increment f&lt;br /&gt;
|-&lt;br /&gt;
|INCFSZ||Increment f, Skip if 0&lt;br /&gt;
|-&lt;br /&gt;
|IORLW||Inclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|IORWF||Inclusive OR W with f&lt;br /&gt;
|-&lt;br /&gt;
|MOVF||Move f&lt;br /&gt;
|-&lt;br /&gt;
|MOVLW||Move literal to W &lt;br /&gt;
|-&lt;br /&gt;
|MOVWF||Move W to f&lt;br /&gt;
|-&lt;br /&gt;
|NOP||No Operation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=top |&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
|RETFIE||Return from interrupt &lt;br /&gt;
|-&lt;br /&gt;
|RETLW||Return with literal in W &lt;br /&gt;
|-&lt;br /&gt;
|RETURN||Return from Subroutine &lt;br /&gt;
|-&lt;br /&gt;
|RLF||Rotate Left f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|RRF||Rotate Right f through Carry&lt;br /&gt;
|-&lt;br /&gt;
|SLEEP||Go into standby mode &lt;br /&gt;
|-&lt;br /&gt;
|SUBLW||Subtract W from literal &lt;br /&gt;
|-&lt;br /&gt;
|SUBWF||Subtract W from f&lt;br /&gt;
|-&lt;br /&gt;
|SWAPF||Swap nibbles in f&lt;br /&gt;
|-&lt;br /&gt;
|XORLW||Exclusive OR literal with W &lt;br /&gt;
|-&lt;br /&gt;
|XORWF||Exclusive OR W with f&lt;br /&gt;
|}&lt;br /&gt;
[[:bild:pic_asm_short.jpg|Kurzübersicht zum Ausdrucken]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ausführliche Beschreibung zu den Befehlen==&lt;br /&gt;
&lt;br /&gt;
Erklärungen zu den Verwendeten Platzhaltern:&lt;br /&gt;
*'''k''' stellt einen fest definierten Wert da. z.B. &amp;lt;tt&amp;gt;0x20&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;d'42'&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;b'00101010'&amp;lt;/tt&amp;gt;&lt;br /&gt;
*'''W''' steht für das W-Register.&lt;br /&gt;
*'''d''' steht für ''destination'' (Ziel). Im code wird d durch ein &amp;lt;tt&amp;gt;w&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (der Wert wird in das W-Register gespeichert ) oder &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (der Wert wird in das  davor definierte Register gespeichert)&lt;br /&gt;
*'''b''' steht für Bitnummer im Register (eine Zahl zwischen 0 und 7)&lt;br /&gt;
*'''R''' steht für ein Register&lt;br /&gt;
*'''fett''' geschrieben Bedeutet, dass es ein Platzhalter ist und im Quellcode durch eine Registeradresse oder einen Wert ersetzt werden muss&lt;br /&gt;
*&amp;lt;tt&amp;gt;Schreibmaschinenstil&amp;lt;/tt&amp;gt; bedeutet, dass es so im Quellcode geschrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and literal - Addiere W und Zahl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ADDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Add W and f - Addiere W und f &amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R+W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- and&lt;br /&gt;
 1000&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; ANDWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;AND W with f - ???&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ and\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche ANDWF&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BCF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Clear f  - Bit b im R wird gelöscht&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BCF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gelöscht. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    MOVLW b'11111111'     ;es wird b'11111111' in das W-Register geschrieben&lt;br /&gt;
    BCF W,2               ;es wird bit 2 im W-Register gelöscht.&lt;br /&gt;
                          ;das Ergebnis ist: b'11111011'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BSF R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Set f  - Bit b im R wird gesetzt&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BSF&amp;lt;/tt&amp;gt; wird das Bit '''b''' im Register '''R''' gesetzt. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
    CLRW                   ;es wird b'00000000' in das W-Register geschrieben&lt;br /&gt;
    BSF W,2                ;es wird bit 2 im W-Register gesetzt.&lt;br /&gt;
                           ;das Ergebnis ist: b'00000100'&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSC R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Clear  - Wenn das Bit b im Register R 0 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSC&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 0 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSC W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 0 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser Sprungbefehl ausgeführt.&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;BTFSS R,b&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Bit Test f, Skip if Set  - Wenn das Bit b im Register R 1 ist, überspringe den nächsten Befehl&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem Befehl &amp;lt;tt&amp;gt;BTFSS&amp;lt;/tt&amp;gt; kann eine Verzweigung im Programmablauf bewirkt werden. Wenn das Bit '''b''' im Register '''R''' 1 ist, wird der nächste Befehl übersprungen. Ein Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW b'00000001'     ;es wird die Zahl 1 in das W-Register kopiert.&lt;br /&gt;
     BTFSS W,0             ;es wird bit 0 geprüft.&lt;br /&gt;
                           ;wenn es 1 ist, wird der nächste Befehl übersprungen&lt;br /&gt;
     GOTO  IST_NULL        ;springt zur Marke &amp;quot;IST_NULL&amp;quot;&lt;br /&gt;
     GOTO  IST_EINS        ;springt zur Marke &amp;quot;IST_EINS&amp;quot; &amp;lt;- in diesem Fall wird dieser&lt;br /&gt;
                           ;Sprungbefehl ausgeführt, da der Befehl&lt;br /&gt;
                           ;darüber übersprungen wurde.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CALL&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Call Subroutine  - Rufe Unterprogramm auf&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl wird ein Unterprogramm aufgerufen. Mit dem &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt;-Befehl wird das Unterprogramm beendet und man kehrt zum Befehl nach dem &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt;-Befehl zurück. Das Unterprogramm wird so definiert, dass im Quellcode der Name des Unterprogramms nicht eingerückt steht. Ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
     MOVLW d'13'           ;in das W-Register wird 13d geladen&lt;br /&gt;
     CALL  Unterprogramm1  ;es wird das Unterprogramm &amp;quot;Unterprogramm1&amp;quot; aufgerufen&lt;br /&gt;
     MOVWF ergebnis        ;das W-Register wird in das Register &amp;quot;ergebnis&amp;quot; kopiert.&lt;br /&gt;
                          ;im Register &amp;quot;ergebnis&amp;quot; steht nun 23d&lt;br /&gt;
       &lt;br /&gt;
 Unterprogramm1            ;zählt 10 zum W-Register&lt;br /&gt;
     ADDLW d'10'           ;es wird 10d zum W-Register addiert&lt;br /&gt;
     RETURN                ;kehre zurück zum Aufrufer&lt;br /&gt;
&amp;lt;/dl&amp;gt;&amp;lt;/dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear f - Schreibe 0 in das Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register '''R''' wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRW&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear W - Schreibe 0 in W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register (&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;) wird mit Nullen gefüllt (gelöscht).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;CLRWDT&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Clear Watchdog Timer - Setzt den Watchdog-Timer zurück&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird der WDT (Watchdog-Timer) zurückgesetzt und der Zähler des WDT  auf 0 gesetzt, zusätzlich werden die STATUS-bits TO und PD gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;COMF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Complement f - negiere alle bits im Register R&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Von der Binärzahl im Register '''R''' werden die 0 mit 1 und 1 mit 0 ersetzt. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Ein kleines Beispiel: aus &amp;lt;tt&amp;gt;AAh&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;10101010b&amp;lt;/tt&amp;gt;) wird &amp;lt;tt&amp;gt;55h&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;01010101b&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;DECFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Decrement f, Skip if 0 - Subtrahiert 1 vom Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Vom Wert des Registers '''R''' wird 1 subtrahiert und das Ergebnis entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;GOTO&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go to address - Gehe zu Adresse/Sprungmarke&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Nach dem GOTO Befehl wird das Programm ab der Adresse weiter ausgeführt, die nach dem GOTO-Befehl steht. Diese Adresse wird durch so genannte Sprungmarke definiert, welche, im Gegensatz zu den Befehlen nicht eingerückt im Quellcode stehen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f - Addiere 1 zum Register f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das C-Flag im STATUS-Register nicht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;INCFSZ R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Increment f, Skip if 0 - Addiere 1 zum Regiser f, überspringe wenn 0&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Zum Wert des Registers '''R''' wird 1 addiert und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).  Der Zusatz SZ steht für ''skip if zero'', d.h. wenn das Ergebnis der Rechnung Null ist, wird der nächste Befehl übersprungen. Dieser Befehl wird für Schleifen mit bestimmter Anzahl der Durchläufe benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Register, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Ooperation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- or&lt;br /&gt;
 1110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; IORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ or\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche IORLW&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move f - Bewege f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das Register R wird in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder wieder in R kopiert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Letzteres mag sinnlos scheinen, ist aber nützlich, da durch den Befehl das Z-Bit im STATUS-Regsiter gesetzt wird, falls R Null ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move literal to W - Bewege Zahl in W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der festgelegte Wert k wird in das W-Register kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;MOVWF R&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Move W to f - Bewege W-Register in das Register F&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Das W-Register wird in das Register '''R''' kopiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOP&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;No Operation - Kein Befehl zum Ausführen (warte)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Dieser Befehl macht nichts. Er verbraucht nur Zeit, welche sich einfach mit folgender Formel berechnen lässt. &amp;lt;math&amp;gt;t=\frac{4}{f}&amp;lt;/math&amp;gt;,wobei &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; für die Frequenz des Oszillators steht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETFIE&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from interrupt - Kehre zurück aus der Unterbrechung&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Mit diesem Befehl wird die Interrupt Service Routine (ISR) beendet und das Programm wird an der Zeile weiter ausgeführt, vor der es durch den Interrupt angehalten wurde. Es werden auch alle Interrupts wieder erlaubt (das GIE bit wird gesetzt). Siehe hierzu auch [[#Interrupt | Interrupt]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return with literal in W - Kehre zurück mit Zahl k im W-Register&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETLW&amp;lt;/tt&amp;gt; zurück in die nächste Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde. Der in k angegebene Wert wird dabei in das W-Register geschrieben. Dieser Befehl wird vor allem für s.g Wertetabellen (eng: lookup tables) verwendet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RETURN&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Return from Subroutine - Kehre zurück zum Übergeordneten Programmteil&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Wurde ein Programmteil mit dem Befehl &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; aufgerufen, dann springt man mit dem Befehl &amp;lt;tt&amp;gt;RETURN&amp;lt;/tt&amp;gt; zurück zu der nächsten Zeile nach der Zeile aus der das &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; Befehl ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RLF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Left f through Carry - Rotiere das Register f mithilfe des Carry-bits nach links&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach links verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das Bit 0 des Registers R geschoben. Bit 7 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  c  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  7  6 5 4 3 2 1 0 c ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RRF R,d&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Rotate Right f through Carry - Rotiere das Register f mithilfe des Carry-bits nach rechts&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Alle Bits im Register '''R''' werden um eine Position nach rechts verschoben. Dabei wird das Carry bit (&amp;lt;tt&amp;gt;STATUS,C&amp;lt;/tt&amp;gt;) in das 7.Bit des Registers R geschoben. Bit 0 aus dem Register '''R''' wird in das Carry bit &amp;quot;geschoben&amp;quot;. Das Ergebnis wird entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
:Zur Verdeutlichung:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 |C| |-Register  R-| ;C steht für das Carry-bit, STATUS,C&lt;br /&gt;
  C  7 6 5 4 3 2 1 0 ;vor dem Verschieben&lt;br /&gt;
  0  C 7 6 5 4 3 2 1 ;nach dem Verschieben&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SLEEP &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Go into standby mode - Versetze den Mirokontroller in Bereitschaftsmodus&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Der µC wird in den Sleep-Mode versetzt, in dem er weniger Strom verbraucht. Er kann durch einen Reset, einem Watchdog-Timer-Reset oder durch einen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBLW k &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from literal - Ziehe W von Zahl ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;k-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; SUBWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Subtract W from f - Ziehe W von f ab&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird die Rechenoperation &amp;lt;math&amp;gt;R-W&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Dieser Befehl beeinflusst das STATUS-Register. Siehe hierzu  [[#Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register|Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Register]]&lt;br /&gt;
&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    d'20'       ;schreibe 20 in das W-Register&lt;br /&gt;
 movwf    Register1   ;bewegt das W-Register in das Register1&lt;br /&gt;
 movlw    d'10'       ;schreibt 10 in das W-Register&lt;br /&gt;
 SUBWF    Register1,F ;schreibt Register1(20)-W(10) in Register1&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;SWAPF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Swap nibbles in f  - Vertausche die Halbbytes (Nibbles)&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es werden die höheren 4 bit (bit7-bit4) mit den niedrigeren 4 bit (bit3-bit0) eines Registers vertauscht und entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
:Beispiel:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 movlw    b'00001111' ;schreibe b'00001111' in das W-Register&lt;br /&gt;
 movwf    Register1   ;kopiert das W-Register in das Register1&lt;br /&gt;
 SWAPF    Register1,W ;vertauscht die ersten 4 bit mit den letzen&lt;br /&gt;
                      ;4 bit in Register 1 und schreibt es in das W-Register&lt;br /&gt;
                      ;im W-Register steht nun b'11110000'&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORLW k&amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR literal with W&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ k&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss in das W-Register gespeichert. Dieser Befehl setzt das Z bit des STATUS-Registers, falls W=k und das Ergebnis 0 ist.&lt;br /&gt;
:Zur Verdeutlichung der Operation:&lt;br /&gt;
&amp;lt;dl&amp;gt;&amp;lt;dd&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
 1100&lt;br /&gt;
 1010&lt;br /&gt;
 ---- xor&lt;br /&gt;
 0110&lt;br /&gt;
&amp;lt;/dd&amp;gt;&amp;lt;/dl&amp;gt;&amp;lt;!-- zum einrücken da--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt; XORWF R,d &amp;lt;/b&amp;gt; &amp;lt;i style=&amp;quot;color:grey;&amp;quot;&amp;gt;Exclusive OR W with f&amp;lt;/i&amp;gt;&amp;lt;hr&amp;gt;&lt;br /&gt;
:Es wird bitweise die logische Funktion &amp;lt;math&amp;gt;W\ xor\ R&amp;lt;/math&amp;gt; ausgeführt und das Ergebniss entweder in das W-Register ('''d'''=&amp;lt;tt&amp;gt;W&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) oder in R gespeichert ('''d'''=&amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;). Vergleiche XORLW&lt;br /&gt;
==Besondere, oft gebrauchte Register==&lt;br /&gt;
&lt;br /&gt;
=== STATUS === &lt;br /&gt;
Der Statusregister beinhaltet den Status der Recheneinheit ALU (Arithmetic-Logic Unit), Resetinformationen und die beiden Bits zur Wahl der Speicherbank&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;table style=&amp;quot;text-align: center;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;8&amp;quot; style&amp;gt;'''STATUS''' (ADDRESS 03h, 83h, 103h, 183h)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr style=&amp;quot;border:0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R-1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;width:60px;&amp;quot;&amp;gt;R/W-x&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''IRP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''RP0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''TO'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''PD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''Z'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''DC'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;background:#00ffff;&amp;quot;&amp;gt;'''C'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit7&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td colspan=&amp;quot;6&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Bit0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Bit 7 '''IRP''': Register Bank Select Bit (für indirekte Adressierung)&lt;br /&gt;
:: 1 = Bank 2, 3 (100h-1FFh)&lt;br /&gt;
:: 0 = Bank 0, 1 (00h-FFh)&lt;br /&gt;
*Bit 6-5 '''RP&amp;lt;1:0&amp;gt;''': Register Bank Select Bits (für direkte Adressierung)&lt;br /&gt;
:: 11 = Bank 3 (180h-1FFh)&lt;br /&gt;
:: 10 = Bank 2 (100h-17Fh)&lt;br /&gt;
:: 01 = Bank 1 (80h-FFh)&lt;br /&gt;
:: 00 = Bank 0 (00h-7Fh) &lt;br /&gt;
*Bit 4 '''TO''': Time-out Bit&lt;br /&gt;
:: 1 = Nach Power-up, CLRWDT Befehl oder SLEEP Befehl&lt;br /&gt;
:: 0 = A Watchdogtimer time-out ist eingetreten&lt;br /&gt;
*Bit 3 '''PD''': Power-Down Bit&lt;br /&gt;
:: 1 = Nach Power-up oder durch den CLRWDT&lt;br /&gt;
:: 0 = Nach einem SLEEP befehl&lt;br /&gt;
*Bit 2 '''Z''': Zero bit&lt;br /&gt;
:: 1 = Das Ergebnis einer arithmetischen oder logischen Operation ist 0&lt;br /&gt;
:: 0 = Das Ergebnis einer arithmetischen oder logischen Operation ist NICHT 0&lt;br /&gt;
*Bit 1 '''DC''': Digit carry/borrow bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des 4.Niedrigsten Bits eines Rechenergebnisses existiert&lt;br /&gt;
*Bit 0 '''C''': Carry/borrow Bit (ADDWF, ADDLW, SUBLW und SUBWF Befehle)&lt;br /&gt;
:: 1 = Ein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
:: 0 = Kein Carry-out des MSB eines Rechenergebnisses existiert&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Borrowbit&amp;quot; (to borrow = etwas borgen) dient zum erkennen, wenn ein Übertrag einer Rechenoperation exisitiert. 250+10 ergibt zum Beispiel 4, und setzt dabei das Borrowbit auf 1. Damit kann das Programm erkennen, wenn wieder einmal ein Ergebnis größer als 255 herauskam.&lt;br /&gt;
Bei Subtraktionen (SUBLW und SUBWF) verhält sich das Carry Bit umgekehrt als bei Additionen (ADDWF und ADDLW)!! 55-6=49 setzt Carry auf 1 aber 10-25=241 löscht das Carry-Flag zum Beispiel.&lt;br /&gt;
&lt;br /&gt;
==Speicherbankorganisation==&lt;br /&gt;
===Programmspeicher===&lt;br /&gt;
Die Mid-Range MCUs haben einen 2-8k großen Programmspeicher. Dieser hat aber in jeder Speicherzelle nicht 8, sondern 14 Bit - also genau die Länge eines Befehls. Die aktuelle Stelle im Programm wird im PC (Program Counter) verwaltet. Er speichert immer die aktuelle Position im Programmspeicher. Bei einem PIC mit 8k Adressen muss er also die Adressen 0000-1FFF speichern können. Daraus folgt die Größe von 13 Bit für den PC. Der Programmspeicher ist in mehrere Bänke geteilt, die alle 2k groß sind. Das Programm springt ohne zutun des Benutzers von einer in die Nächste. Wenn man aber selber springen will, muss man die Register PCLATH (Program Counter Latch High) oder PCL (Program Counter Least Significant Byte) mit der Sprungadresse beschreiben.&lt;br /&gt;
&lt;br /&gt;
===Datenspeicher===&lt;br /&gt;
Der Datenspeicher besteht aus den Special Function Registern (SFR) und den General Purpose&lt;br /&gt;
Registern (GPR). Die SFRs sind für die Funktionen des PICs zuständig (Interrupts, Timer, ADCs, CCPM...) und die GPRs für die Speicherung von Variablen und Daten.&lt;br /&gt;
&lt;br /&gt;
Da immer nur 7 Bit der (Ziel)Adresse in einem Befehl gespeichert werden können, sind nur 7Fh (128d) Adressen im Datenbereich möglich. Deswegen wurde das &amp;quot;Banking&amp;quot; eingeführt. 2 Bit im Statusregister (welcher in allen Bänken der selbe ist und auch an der gleichen Stelle sitzt) geben die akutelle &amp;quot;Bank&amp;quot; an und sind nichts anderes als die 2 höchstwertigsten (MSB) Bits der Adresse. Damit lassen sich max. 4 Bänke ansprechen. Je nach PIC gibt es 2-4 Bänke. Die beiden Bits im Register STATUS heißen RP0 (STATUS&amp;lt;5&amp;gt;) und RP1 (STATUS&amp;lt;6&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Wechseln der Bänke mit RP0 und RP1&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|| RP1&lt;br /&gt;
|| RP0&lt;br /&gt;
|-&lt;br /&gt;
| Bank0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|-&lt;br /&gt;
| Bank2&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Bank3&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Bild:PIC midrange register.JPG]]&lt;br /&gt;
# '''FETTE Register''' sind in allen PICs vorhanden&lt;br /&gt;
#  können je nach PIC unimplementierte Bereiche beinhalten - diese werden immer als 0 gelesen. (DATENBLATT!!)&lt;br /&gt;
# siehe 2&lt;br /&gt;
# Könnten je nach PIC auch nicht in Bank0 gemapped werden, sind dann eigenständige Register.&lt;br /&gt;
# je nach PIC kann es diese Bänke geben oder nicht geben.&lt;br /&gt;
&lt;br /&gt;
==Überprüfung von Rechenergebnissen mit Hilfe des STATUS-Registers==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Subtraktionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| negativ&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ Auswirkungen auf das STATUS-Register bei Additionen&lt;br /&gt;
|-&lt;br /&gt;
| Ergebnis&lt;br /&gt;
|| STATUS,C&lt;br /&gt;
|| STATUS,Z&lt;br /&gt;
|-&lt;br /&gt;
| positiv&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Überlauf&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|0&lt;br /&gt;
|-&lt;br /&gt;
| Null&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Category:PIC]]&lt;/div&gt;</summary>
		<author><name>Der Gärtner</name></author>	</entry>

	</feed>