2. Einführung/Assembler Programmierung 2.1 Einführung

Werbung
2. Einführung/Assembler Programmierung
Es soll eine einfache Einführung in die Fuktionsweise des PIC16F84A gegeben
werden. Anhand eines Beispielprogramms werden einige grundlegende
Assemblerbefehle besprochen.
Empfohlene Literatur:
PIC16F84A.pdf
(Das Datenblatt des Prozessors)
Mid-Range_MCU_Family_Reference_Manual.pdf
2.1 Einführung
2.1.1 Übersicht
Der PIC16F84A ist ein Mikrocontroller, der eine CPU, Programm- und
Datenspeicher und I/O-Ports auf einem Chip vereint.
Die CPU kennt 35 Assemblerbefehle.
Features:
•
13 Ein- /Ausgänge (I/Os)
•
einen integrierten 8-Bit Timer / Zähler
•
Verschiedene Interrupts
•
einen RAM mit 68 Byte freier Kapazität
•
integrierter EEPROM (nicht flüchtiger Speicher)
•
Programmspeicher mit 1024 Worten (bis zu 10.000 mal beschreibbar)
•
Taktfrequenz bis 5MHz
2-1
2.1.2 Blockschaltbild des Prozessors
13
Program Counter
Data Bus
8
EEPROM Data Memory
FLASH
Program
Memory
8 Level Stack
(13-bit)
1K x 14
Program
Bus
14
RAM
File Registers
EEDATA
68 x 8
7
RAM Addr
EEPROM
Data Memory
64 x 8
EEADR
Addr Mux
Instruction Register
7
Direct Addr
5
TMR0
Indirect
Addr
FSR reg
RA4/T0CKI
STATUS reg
8
MUX
Power-up
Timer
Instruction
Decode &
Control
Timing
Generation
Oscillator
Start-up Timer
8
ALU
Power-on
Reset
Watchdog
Timer
I/O Ports
RA3:RA0
W reg
RB7:RB1
RB0/INT
OSC2/CLKOUT
OSC1/CLKIN
MCLR
VDD, VSS
Die PIC Prozessoren besitzen eine Harvard-Architektur, das bedeutet dass Programmund Datenspeicher getrennt sind:
Es gibt einen Flash-Program-Memory in den das Programm des Prozessors geladen wird
(man spricht hier vom „Flashen“). Dieser Flash Speicher kann bis zu 1024 Befehle
speichern; sie bleiben auch nach dem Entfernen der Betriebsspannung gespeichert.
Im RAM stehen 88 jeweils ein Byte breite Register zur Verfügung. Ein Teil davon (die SFR
Special Function Register) wird verwendet um die Ein- und Ausgänge, den Timer,
Interrups und andere "on-chip" Funktionen zu steuern. Die restlichen Register (68 Stück)
sind vom Anwender frei verwendbar, in ihnen lassen sich also Variablen und Flaggen
abspeichern (GPR = General Purpose Register).
Des weiteren verfügt der PIC über einen EEPROM, in dem Werte nicht-flüchtig
abgespeichert werden können. Das heisst die Daten bleiben - im Gegensatz zu den im
RAM gespeicherten – auch nach dem Entfernen der Betriebsspannung erhalten.
2-2
2.1.3 Register (RAM)
File Address
File Address
00h
Indirect addr. (1)
Indirect addr. (1)
80h
01h
TMR0
OPTION_REG
81h
02h
PCL
PCL
82h
03h
STATUS
STATUS
83h
04h
FSR
FSR
84h
05h
PORTA
TRISA
85h
06h
PORTB
TRISB
86h
07h
—
—
87h
08h
EEDATA
EECON1
88h
09h
EEADR
EECON2(1)
89h
0Ah
PCLATH
PCLATH
8Ah
0Bh
INTCON
INTCON
8Bh
8Ch
0Ch
68
General
Purpose
Registers
(SRAM)
Mapped
(accesses)
in Bank 0
4Fh
50h
7Fh
CFh
D0h
Bank 0
FFh
Bank 1
Unimplemented data memory location, read as ’0’.
Note 1: Not a physical register.
Der Datenspeicher ist in zwei Bänke aufgeteilt. Die Umschaltung zwischen den
Bänken erfolgt durch Bit 5 im STATUS -Register (STATUS, RP0):
RP0 = 0: Bank 0
RP0 = 1: Bank 1
Wie zu erkennen ist, werden alle Speicherplätze bis 0x0B von den SFR
verwendet. Das erste freie Register, das zum Abspeichern von Daten verwendet
werden darf liegt bei 0x0C.
Eine wichtige Ausnahme vom Speicherbereich ist das W (working) Register. Es
liegt nicht im RAM sondern gehört zu der ALU. Die ALU speichert darin z.B.
Rechenergebnisse ab.
2-3
2.1.4 Befehlssatz
Parameter
Beschreibung
f (file)
Ein Register
d (destination)
Ergebnis speichern in
d = 0 → w (working register)
d = 1 → f (file, ein Register)
k
Konstante
b (bit)
Position eines einzelnen Bits innerhalb eines Registers
2-4
2.1.5 Ein-/Ausgänge
Der PIC16F84A besitzt insgesamt 13 I/O Ports: PORTA (5 Bit) und PORTB (8 Bit)
welche über die Register PORTA und PORTB angesteuert bzw. ausgelesen werden
können. Sie können über die TRIS-Register (TRISA, TRISB) individuell als Einbzw. Ausgänge geschaltet werden. Wird ein TRIS-Bit geöscht, so wird der
entsprechende Pin ein Ausgang, wird das Bit gesetzt ein Eingang.
Merke:
Tris-Bit gelöscht:
Tris-Bit gesetzt:
0 = 0utput
1 = 1nput
2.1.6 Timer0
Der Timer0 (TMR0) ist wahlweise ein vom Prozessortakt abhängiger 8-Bit Timer
oder ein Zähler. Dies kann im Option-Register durch Bit 5 ( OPTION_REG, T0CS)
festgelegt werden; Man schaltet damit eigentlich nur die Taktquelle des Zählers
um.
T0CS gelöscht: Zähler incrementiert mit Prozessortakt
T0CS gesetzt: Zähler zählt Impulse an PORTA,4
Das Register TMR0, in dem gezählt wird, kann beschrieben und gelesen werden.
Zur Verringerung der Zählfrequenz kann dem Zähler ein Prescaler vorgeschaltet
werden. Dieser ist alternativ beim Watchdog-Timer oder TMR0 einsetzbar. Die
Zuweisung erfolgt durch das Bit 3 des Option-Register (OPTION_REG, PSA).
PSA gelöscht: Prescaler wird TMR0 zugeordnet
PSA gesetzt: Prescaler wird dem Watchdog-Timer zugeordnet
Der Wert des Prescalers (Teilungsfaktor) wird durch die Bits 2-0 im OptionRegister bestimmt (siehe Datenblatt Kap. 2.3.2.).
Sobald der Timer von 0xFF nach 0x00 überläuft, wird Bit 2 (T0IF) im INTCONRegister (INTCON, T0IF) gesetzt und ein Interrupt ausgelöst, sofern dieser
aktiviert ist.
2-5
2.2 Assembler Programmierung
Im Folgenden werden einige wenige Assembler-Befehle (Mnemonics) aus dem
Befehlssatz des PIC16F84a besprochen.
Weitere Mnemonics werden wir in den folgenden Übungen behandeln.
Für eine ausführliche Beschreibung aller Befehle siehe PIC16F84A-Datenblatt
Kapitel 7.1.
2.2.1 Byte-bezogene Mnemonics
Mnemonic Argument Beschreibung
verändert in
STATUS
clrf
f
löscht das Register f
Z
movwf
f
kopiert Inhalt von W nach f
none
movf
f, d
kopiert Inhalt von f nach W (d=0)
oder nach f (d=1)
Z
rlf
f, d
rotiert f nach links durch Carry,
Ergebnis in W (d=0) oder f (d=1)
C
rrf
f, d
rotiert f nach rechts durch Carry,
Ergebnis in W (d=0) oder f (d=1)
C
Zur Beschreibung der Parameter siehe 2.1.4
2.2.2 Bit-bezogene Mnemonics
Mnemonic Argument Beschreibung
verändert in
STATUS
bsf
f, b
setzt das Bit b in f
none
bcf
f, b
löscht das Bit b in f
none
btfss
f, b
überspringt den nächsten Befehl, none
wenn in f das Bit b gesetzt ist
btfsc
f, b
überspringt den nächsten Befehl, none
wenn in f das Bit b gelöscht ist
Zur Beschreibung der Parameter siehe 2.1.4
2.2.3 Literal- und Steuerungs-Mnemonics
Mnemonic Argument Beschreibung
verändert in
STATUS
movlw
k
lädt den Wert k in W
none
goto
k
setzt das Programm an Stelle k
fort
none
call
k
ruft das Unterprogramm k auf
none
return
-
rückkehr vom Unterprogramm
none
Zur Beschreibung der Parameter siehe 2.1.4
2-6
2.2.4 Beispiele
Beispiel 1:
In das Register 0x0C soll der Wert 1
movlw 1
geschrieben werden. Da der
Datenbus keinen Zugriff auf den
movwf 0x0C
Programmspeicher hat ist dies nur
über den Umweg über das Arbeistsregister möglich.
Beispiel 2:
Das Register 0x0E soll auf den Wert
des Registers 0x0D gesetzt werden:
movf
0x0D, W
movwf 0x0C
Beispiel 3:
Der Inhalt des Registers 0x0C soll
mit zwei multipliziert werden und im
selben Register gespeichert werden
rlf
0x0C, f
Beispiel 4:
Eine Einfache Schleife
loop
incf PORTA,f
goto loop
...
Beispiel 5:
Aufruf eines Unterprogramms
call
Sub
...
Sub
...
...
return
Beispiel 6:
Der dritte Pin des Port A (PORTA, 3) soll als Ausgang geschaltet werden, und auf
1 gesetzt werden
bsf
bcf
bcf
bsf
STATUS, RP0 ;Umschalten auf Bank1
;(dort liegt das TrisA Register)
TRISA, 3
;Tris-Bit löschen, damit der
;Pin als Ausgang geschaltet wird
STATUS, RP0 ;Umschalten auf Bank0 (dort liegt
;das PortA Register)
PORTA, 3
;Port auf High setzen
2-7
2.3 Vollständiger Befehlssatz
Es folgt eine Aufstellung des kompletten Befehlssatzes des PIC16F84A.
Für eine ausführliche Beschreibung der einzelnen Befehle siehe PIC16F84A-Datenblatt
Kapitel 7.1.
2.3.1 Wichtige Flaggen im Status-Register
Pos.
Name
Funktion
0
C
(Carry)
Überlauf des 8ten Bits
1
DC
(Digit Carry)
Überlauf des 4ten Bits
2
Z
(Zero)
Ergebnis ist 0
2.3.2 Speicherbefehle
Mnemonic
Parameter
Beschreibung
Status-Flags
CLRW
-
Clear w
Z
CLRF
f
Clear f
Z
MOVLW
k
Move Literal to w
-
MOVWF
f
Move w to f
-
MOVF
f,d
Move f to d
Z
BCF
f,b
Bit Clear f<b>
-
BSF
f,b
Bit Set f<b>
-
Zur Beschreibung der Parameter siehe 2.1.4.
2-8
2.3.3 Arithmetische- und Logische Befehle
Mnemonic
Parameter
Beschreibung
Status-Flags
ADDLW
k
Add literal k to w
C,DC,Z
SUBLW
k
Subtract w from literal k
C,DC,Z
ANDLW
k
AND literal k with w
Z
IORLW
k
Inclusive OR literal k with w
Z
XORLW
k
Exclusive OR literal k with w
Z
ADDWF
f,d
Add w to f
C,DC,Z
SUBWF
f,d
Subtract w from f
C,DC,Z
ANDWF
f,d
AND w with f
Z
IORWF
f,d
Inclusive OR w with f
Z
XORWF
f,d
Exclusive OR w with f
Z
INCF
f,d
Increment f
Z
DECF
f,d
Decrement f
Z
COMF
f,d
Complement f
Z
RLF
f,d
Rotate left f
C
RRF
f,d
Rotate right f
C
SWAPF
f,d
Swap nibbles in f
-
Beispiel:
Zum Register 0x10 soll der Wert 5
movlw
5
addiert werden:
addwf
0x10, f
Der Wert des Registers 0x11 soll um
incf
0x11, w
1 erhöht werden und das Ergebnis in
movwf
0x12
Beispiel:
0x12 gespeichert werden:
2-9
2.3.4 Sprungbefehle, Labels, Stack
Mnemonic
Parameter
Beschreibung
GOTO
k
Go to address k
CALL
k
Call subroutine at adress k
RETURN
-
Return from subroutine
RETLW
k
Return from subroutine with literal k in w
RETFIE
-
Return from interrupt
An jeder Stelle im Assembler-Quellcode können sogenannte Labels gesetzt
werden, die bei der Assemblierung in die Adressen des jeweils nächsten Befehls
aufgelöst werden.
Labels stehen üblicherweise an erster Position in einer Befehlszeile, alle anderen
Ausdrücke nach einem white space (Tab/Leerzeichen).
Beispiel: Einfache Schleife
loop
incf PORTA,f
goto loop
Ebenfalls nützlich ist der $-Operator, der stets die Adresse des aktuellen Befehls
repräsentiert.
Beispiel: Einfache Schleife mit
incf
$-Operator
goto $-1
2-10
PORTA,f
Beispiel: Aufruf eines
...
Unterprogrammes
call
Sub
...
Sub ...
...
return
Beim Aufruf eines Unterprogramms wird der aktuelle Wert des Programmzählers
automatisch auf dem Stack abgelegt. Bei einem Rücksprung aus dem
Unterprogramm wird der oberste Eintrag des Stacks zurück in den Programmzähler
geschrieben, so daß die Ausführung an der richtigen Stelle fortgesetzt wird. Der
Stack des PIC16F84A ist 8 Ebenen tief, es sind daher nur 8 Unterprogrammebenen möglich.
Vorsicht: Bei mehr als 8 aufeinanderfolgenden CALL-Anweisungen wird der erste
Eintrag im Stack ohne Warnung des Assemblers überschrieben!
2-11
2.3.5 Bedingte Verzweigungen
Mnemonic
Parameter
Beschreibung
DECFSZ
f,d
Decrement f, skip if zero
INCFSZ
f,d
Increment f, skip if zero
BTFSC
f,b
Bit test f<b>, skip if clear
BTFSS
f,b
Bit test f<b>, skip if set
Trifft ein Test zu, so wird die nächste Anweisung übersprungen!
Beispiel: Bedingte Ausführung einer Anweisung
AL = AL + 5;
if( STATUS<C>==1 )
AH = AH + 1;
movlw
5
addwf
AL,f
btfsc
STATUS,C
incf
AH,f
Beispiel: Bedingte Ausführung eines Anweisungsblocks
if( A==B )
{
Block_1
}
else
movf
A,w
subwf
B,w
btfss
STATUS,Z
goto
Block_2
Block_1 ...
{
...
Block_2
goto
}
Block_2 ...
...
Block_2_END
2-12
Block_2_END
Beispiel: Schleife
for( i=10; i>0; i-- )
{
...
}
[ äquivalent zu ]
i=10;
do {
movlw
0x0A
movwf
i
loop
...
...
i--;
} while( i>0 );
2-13
decfsz
i,f
goto
loop
2.3.6 Sonstige Befehle
Mnemonic
Parameter
Beschreibung
NOP
-
No operation
SLEEP
-
Standby-Modus
CLRWDT
-
Clear Watchdog Timer
2.3.7 Zahlenformate
Basis
Syntax
Dezimal
Hexadezimal
Oktal
Binär
d'122'
h'7A'
o'172'
b'1111010'
'z'
D'122'
H'7A'
O'172'
B'1111010'
A'z'
.'122'
0x7A
172o
1111010b
.122
PiKdev
122d
7Ah
2-14
ACII
2.4 Metabefehle
Neben den Assembler-Befehlen existieren noch zahlreiche Metabefehle, die vom
Assembler vor der eigentlichen Code-Generierung bearbeitet werden. Nützliche
Metabefehle sind z.B:
Befehl
Funktion
processor processor
Stellt den verwendeten Prozessor ein.
include "file"
(Wie in C.) Fügt an dieser Stelle die Datei file ein.
include <file>
"file“ : Sucht file im Projektordner.
#include "file"
<file> : Sucht file im Include-Pfad.
#include <file>
#define name [string]
(Wie in C.) Definiert name := string.
#undefine name
(Wie in C.) Definition aufheben.
org addr
Der folgende Code wird ab Adresse addr im
Programmspeicher abgelegt. (Wichtig z.B. für
Interruptroutinen!)
name equ addr
Der Adresse addr wird das Label name zugeordnet
(z.B. zur Definition von Variablen).
cblock addr
label_1, label_2
label_3
...
endc
Definiert fortlaufende Labels ab Adresse addr
banksel addr
Generiert automatisch den nötigen Code zur Auswahl
der Speicherbank in der die Adresse addr liegt.
end
Muß am Ende eines Programms stehen.
(z.B. zur Definition von Variablenblöcken).
2-15
Herunterladen