ABI-AVR-Formelsammlung ITG-GBS-SHA

Für den AT90S2313 und ATmega32

SREG: Status Register Bit   Registers and Operands
C Carry flag in Status Register 0 PC Program Counter
Z Zero flag in Status Register 1 Rd Destination (and source) Working Register in the register file
N Negative flag in Status Register 2 Rd(n) Bit n of the destination Working Register
V Two’s complement overflow indicator 3 Rr Source Working Register in the register file
S N $ V, for signed tests 4 P I/O-Register and Port-Register
H Half carry flag in Status Register 5 K Constant data
T Transfer bit used by BLD and BST instructions 6 k Constant address
I Global interrupt enable/disable flag 7 b Bit in the Working Register or I/O-Register
Logic Operations s Bit in the Status Register
&: AND #: OR $: exclusive OR X,Y,Z Indirect Address Register (X=R27:R26, Y=R29:R28, Z=R31:R30)
Hinweis für die Immediate-Befehle (X), (Y), (Z) Contents at indirect address X, Y or Z
* Befehl nicht erlaubt für Register R0...R15 q Displacement for direct addressing

DATA TRANSFER INSTRUCTIONS

Mnemonic Operands Description Operation Flags # Clocks Mega32
MOV Rd, Rr Move Between Working Registers Rd:=Rr None 1
MOVW Rd, Rr Copy Register Word Rd+1:Rd := Rr+1:Rr None 1 X
LDI Rd, K Load Immediate * Rd:=K None 1
LD Rd, X Load Indirect Rd:=(X) None 2
LD Rd, X+ Load Indirect and Post-increment Rd:= (X),X:= X+1 None 2
LD Rd, -X Load Indirect and Pre-decrement X:= X-1,Rd:=(X) None 2
LD Rd, Y Load Indirect Rd:=(Y) None 2
LD Rd, Y+ Load Indirect and Post-increment Rd:= (Y),Y:= Y+1 None 2
LD Rd, -Y Load Indirect and Pre-decrement Y:= Y-1,Rd:=(Y) None 2
LDD Rd, Y+q Load Indirect with Displacement Rd:=(Y+q) None 2
LD Rd, Z Load Indirect Rd:=(Z) None 2
LD Rd, Z+ Load Indirect and post-increment Rd:= (Z),Z:= Z+1 None 2
LD Rd, -Z Load Indirect and pre-decrement Z:= Z-1,Rd:=(Z) None 2
LDD Rd, Z+q Load Indirect with Displacement Rd:=(Z+q) None 2
LDS Rd, k Load Direct from SRAM Rd:=(k) None 2
ST X, Rr Store Indirect (X):=Rr None 2
ST X+, Rr Store Indirect and post-increment (X):=Rr,X:= X+1 None 2
ST -X, Rr Store Indirect and pre-decrement X:= X-1,(X):= Rr None 2
ST Y, Rr Store Indirect (Y):=Rr None 2
ST Y+, Rr Store Indirect and post-increment (Y):=Rr,Y:= Y+1 None 2
ST -Y, Rr Store Indirect and pre-decrement Y:= Y-1,(Y):= Rr None 2
STD Y+q, Rr Store indirect with Displacement (Y+q):=Rr None 2
ST Z, Rr Store Indirect (Z):=Rr None 2
ST Z+, Rr Store Indirect and post-increment (Z):=Rr,Z:= Z+1 None 2
ST -Z, Rr Store Indirect and pre-decrement Z:= Z-1,(Z):= Rr None 2
STD Z+q, Rr Store indirect with Displacement (Z+q):=Rr None 2
STS k, Rr Store Direct to SRAM (k):= Rr None 2
LPM Load Program Memory R0:=(Z) None 3
LPM Rd, Z Load Program Memory Rd := (Z) None 3 X
LPM Rd, Z+ Load Program Memory and Post-Inc Rd := (Z), Z := Z+1 None 3 X
SPM Store Program Memory (Z) := R1:R0 None - X
IN Rd, P In Port Rd:=P None 1
OUT P, Rr Out Port P:=Rr None 1
PUSH Rr Push Working Register on Stack STACK:=Rr None 2
POP Rd Pop Working Register from Stack Rd:=STACK None 2

BIT AND BIT-TEST INSTRUCTIONS

Mnemonic Operands Description Operation Flags # Clocks Mega32
SBI P, b Set Bit in Port-Register I/O(P,b):= 1 None 2
CBI P, b Clear Bit in Port-Register I/O(P,b):=0 None 2
SBR Rd, K Set Bit(s) in Working Register Rd:= Rd # K Z,N,V,S 1
CBR Rd, K Clear Bit(s) in Working Register Rd:= Rd & (0xFF-K) Z,N,V,S 1
LSL Rd Logical Shift Left Rd(n+1):= Rd(n), Rd(0):=0 Z,C,N,V,H 1
LSR Rd Logical Shift Right Rd(n):= Rd(n+1), Rd(7):=0 Z,C,N,V 1
ROL Rd Rotate Left through Carry Rd(0):= C, Rd(n+1):= Rd(n), C:=Rd(7) Z,C,N,V,H 1
ROR Rd Rotate Right through Carry Rd(7):= C, Rd(n):= Rd(n+1), C:=Rd(0) Z,C,N,V 1
ASR Rd Arithmetic Shift Right Rd(n):=Rd(n+1), n=0...6 Z,C,N,V 1
SWAP Rd Swap Nibbles Rd(3...0):=Rd(7...4), Rd(7...4):=Rd(3...0) None 1
BSET S Flag Set SREG(s):=1 SREG(s) 1
BCLR S Flag Clear SREG(s):=0 SREG(s) 1
BST Rr, b Bit Store from Working Register to T T:=Rr(b) T 1
BLD Rd, b Bit Load from T to Working Register Rd(b):=T None 1
SEC Set Carry C:=1 C 1
CLC Clear Carry C:=0 C 1
SEN Set Negative Flag N:=1 N 1
CLN Clear Negative Flag N:=0 N 1
SEZ Set Zero Flag Z:=1 Z 1
CLZ Clear Zero Flag Z:=0 Z 1
SEI Global Interrupt Enable I:=1 I 1
CLI Global Interrupt Disable I:=0 I 1
SES Set Signed Test Flag S:=1 S 1
CLS Clear Signed Test Flag S:=0 S 1
SEV Set Twoís Complement Overflow V:=1 V 1
CLV Clear Twoís Complement Overflow V:=0 V 1
SET Set T in SREG T:=1 T 1
CLT Clear T in SREG T:=0 T 1
SEH Set Half-carry Flag in SREG H:=1 H 1
CLH Clear Half-carry Flag in SREG H:=0 H 1
NOP No Operation None 1
SLEEP Sleep None 3
WDR Watchdog Reset None 1
BREAK Break For On-Chip Debug Only None N/A X

ARITHMETIC AND LOGIC INSTRUCTIONS

Mnemonic Operands Description Operation Flags # Clocks Mega32
ADD Rd, Rr Add Two Working Registers Rd:=Rd + Rr Z,C,N,V,H,S 1
ADC Rd, Rr Add with Carry Two Working Registers Rd:=Rd + Rr + C Z,C,N,V,H,S 1
ADIW Rdl, K Add immediate to Word Rdh:Rdl:=Rdh:Rdl + K Z,C,N,V,S 2
SUB Rd, Rr Subtract Two Working Registers Rd:=Rd - Rr Z,C,N,V,H,S 1
SUBI Rd, K Subtract Constant from Working Register * Rd:=Rd - K Z,C,N,V,H,S 1
SBC Rd, Rr Subtract with Carry Two Working Registers Rd:=Rd - Rr - C Z,C,N,V,H,S 1
SBCI Rd, K Subtract with Carry Constant from Working Registers * Rd:=Rd - K - C Z,C,N,V,H,S 1
SBIW Rdl, K Subtract Immediate from Word Rdh:Rdl:=Rdh:Rdl - K Z,C,N,V,S 2
AND Rd, Rr Logical AND Working Registers Rd:= Rd & Rr Z,N,V,S 1
ANDI Rd, K Logical AND Working Register and Constant * Rd:= Rd & K Z,N,V,S 1
OR Rd, Rr Logical OR Working Registers Rd:= Rd # Rr Z,N,V,S 1
ORI Rd, K Logical OR Working Register and Constant * Rd:= Rd # K Z,N,V,S 1
EOR Rd, Rr Exclusive OR Working Registers Rd:= Rd $ Rr Z,N,V,S 1
COM Rd Oneís Complement (Inversion) Rd:= 0xFF - Rd Z,C,N,V,S 1
NEG Rd Twoís Complement Rd:= 0x00 - Rd Z,C,N,V,H,S 1
INC Rd Increment Rd:= Rd + 1 Z,N,V,S 1
DEC Rd Decrement Rd:= Rd - 1 Z,N,V,S 1
TST Rd Test for Zero or Minus Rd:= Rd & Rd Z,N,V,S 1
CLR Rd Clear Working Register Rd:= 0x00 Z,N,V,S 1
SER Rd Set Working Register Rd:= 0xFF None 1
MUL Rd, Rr Multiply Unsigned R1:R0 := Rd x Rr Z,C 2 X
MULS Rd, Rr Multiply Signed R1:R0 := Rd x Rr Z,C 2 X
MULSU Rd, Rr Multiply Signed with Unsigned R1:R0 := Rd x Rr Z,C 2 X
FMUL Rd, Rr Fractional Multiply Unsigned R1:R0 := (Rd x Rr) << 1 Z,C 2 X
FMULS Rd, Rr Fractional Multiply Signed R1:R0 := (Rd x Rr) << 1 Z,C 2 X
FMULSU Rd, Rr Fractional Multiply Signed with Unsigned R1:R0 := (Rd x Rr) << 1 Z,C 2 X

BRANCH INSTRUCTIONS

Mnemonic Operands Description Operation Flags # Clocks Mega32
RJMP k Relative Jump PC:=PC+k+1 None 2
IJMP Indirect Jump to (Z) PC:= Z None 2
RCALL k Relative Subroutine Call PC:=PC+k+1 None 3
ICALL Indirect Call to (Z) PC:=Z None 3
CALL k Direct Subroutine Call PC := k None 4 X
RET Subroutine Return PC:=STACK None 4
RETI Interrupt Return PC:=STACK I 4
CPSE Rd, Rr Compare, Skip if Equal If(Rd=Rr) THEN PC:=PC+2 or 3 None 1/2/3
CP Rd, Rr Compare Rd-Rr Z,N,V,C,H,S 1
CPC Rd, Rr Compare with Carry Rd-Rr-C Z,N,V,C,H,S 1
CPI Rd, K Compare Working Register with Immediate * Rd-K Z,N,V,C,H,S 1
SBRC Rr, b Skip if Bit in Working Register is Cleared If(Rr(b)=0) THEN PC:=PC+2 or 3 None 1/2/3
SBRS Rr, b Skip if Bit in Working Register is Set If(Rr(b)=1) THEN PC:=PC+2 or 3 None 1/2/3
SBIC P, b Skip if Bit in I/O-Register is Cleared If(P(b)=0) THEN PC:=PC+2 or 3 None 1/2/3
SBIS P,b Skip if Bit in I/O-Register is Set If(P(b)=1) THEN PC:=PC+2 or 3 None 1/2/3
BRBS s, k Branch if Status Flag Set If(SREG(s)=1) THEN PC:=PC+k+1 None 1/2
BRBC s, k Branch if Status Flag Cleared If(SREG(s)=0) THEN PC:=PC+k+1 None 1/2
BREQ k Branch if Equal If (Z=1) THEN PC:=PC+k+1 None 1/2
BRNE k Branch if Not Equal If (Z=0) THEN PC:=PC+k+1 None 1/2
BRCS k Branch if Carry Set If (C=1) THEN PC:=PC+k+1 None 1/2
BRCC k Branch if Carry Cleared If (C=0) THEN PC:=PC+k+1 None 1/2
BRSH k Branch if Same or Higher If (C=0) THEN PC:=PC+k+1 None 1/2
BRLO k Branch if Lower If (C=1) THEN PC:=PC+k+1 None 1/2
BRMI k Branch if Minus If (N=1) THEN PC:=PC+k+1 None 1/2
BRPL k Branch if Plus If (N=0) THEN PC:=PC+k+1 None 1/2
BRGE k Branch if Greater or Equal, Signed If (N$V=0) THEN PC:=PC+k+1 None 1/2
BRLT k Branch if Less Than Zero, Signed If (N$V=1) THEN PC:=PC+k+1 None 1/2
BRHS k Branch if Half-Carry Flag Set If (H=1) THEN PC:=PC+k+1 None 1/2
BRHC k Branch if Half-Carry Flag Cleared If (H=0) THEN PC:=PC+k+1 None 1/2
BRTS k Branch if T-Flag Set If (T=1) THEN PC:=PC+k+1 None 1/2
BRTC k Branch if T-Flag Cleared If (T=0) THEN PC:=PC+k+1 None 1/2
BRVS k Branch if OverflowFlag is Set If (V=1) THEN PC:=PC+k+1 None 1/2
BRVC k Branch if Overflow Flag is Cleared If (V=0) THEN PC:=PC+k+1 None 1/2
BRIE k Branch if Interrupt Enabled If (I=1) THEN PC:=PC+k+1 None 1/2
BRID k Branch if Interrupt Disabled If (I=0) THEN PC:=PC+k+1 None 1/2

Wichtige Sprach-Elemente

Element Bedeutung Beispiel Erklärung zum Beispiel
; Einleiten eines Kommentars ; Kommentar bla bla  
.include Einbinden einer Datei .include "2313def.inc" Die 2313-Definitionen werden eingebunden
.equ Deklaration von Konstanten.
Wert ist nicht mehr änderbar im weiteren Quelltext
.equ papagei = 1 Der Bezeichner papagei hat nun den Wert 1
.equ fisch = -papagei * 2 Werte können auch durch Ausdrücke
(Expressions) berechnet werden
.set Deklaration / Definition einer Variablen.
Eine erneute Zuweisung eines Wertes ist möglich
.set cpuclock = 6000 Der Bezeichner cpuclock hat nun den Wert 6000
.set mothercycle = cpuclock*20/8 Werte können auch durch Ausdrücke
(Expressions) berechnet werden
.def Weist einem Register einen symbolischem Namen zu .def temp = R16 temp ist R16
label: Eine Einsprungmarke init: Die Marke (engl. label) init
Hinweise zu .equ, .set: Der Assembler kann mühselige Rechenarbeit übernehmen: Bestimmte Werte, die öfter im Programm gebraucht werden, z.B. die Frequenz mit der der Kontroller arbeitet können unter symbolischen Namen gespeichert werden. Die Werte lassen sich direkt oder durch einfache Ausdrücke beschreiben. Der Assembler errechnet die Werte und setzt diese an den entsprechenden Stellen ein.

Der Assembler versteht auch die Darstellung als ASCII Zeichen: 'a','A' usw.

Darstellung von Werten
Dezimal 255 10
Hexadezimal 0xFF $FF 0xA $0A
Binär 0b11111111 0b00001010

Umgang mit Ports (Datenrichtung, Ein- Ausgabe)

Der Mikrokontroller hat mehrere I/O Pins (Anschlüsse) die als 8Bit Ports gruppiert sind. Beim 90S2313 gibt es PORTB (PBn) und PORTD (PDn).

Port B Data Register – PORTB
Bit 7 6 5 4 3 2 1 0
$18 ($38) PORTB7 PORTB6 PORTB5 PORTB4 PORTB3 PORTB2 PORTB1 PORTB0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Port B Data Direction Register – DDRB
Bit 7 6 5 4 3 2 1 0
$17 ($37) DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Port B Input Pins Address – PINB
Bit 7 6 5 4 3 2 1 0
$16 ($36) PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0
Read/Write R R R R R R R R
Initial Value N/A N/A N/A N/A N/A N/A N/A N/A

Jedes Pin (z.B. PB0) kann als Ein- oder Ausgang geschaltet werden, die Richtung wird in dem Data Direction FlipFlop (z.B. DDB0) festgelegt.

Nach einem Reset sind alle Pins Eingänge weil die FlipFlops den Wert 0 (Inital Value) haben.

Um ein Pin als Ausgang zu schalten, muss in seinem DD-FlipFlop der Wert 1 gespeichert werden. Der Ausgangswert wird dann in dem PORT-FlipFlop (z.B. PORTB0) bestimmt.

Die Pins können zusätzliche Funktionen haben, siehe die Bezeichner in den Klammern bei der Zeichnung oben, z.B. serielle Schnittstelle.

Hier begnügen wir uns mit der normalen I/O-Funktion, dazu rechts ein Prinzip-Schaltbild eines Pins.

Die einzelnen FlipFlops (z.B. PORTBn) werden zu Registern (z.B. PORTB) zusammengefasst.

Durch das Einschreiben entsprechender Werte in die Port-Register kann nach dem Reset die Funktion festgelegt werden:

DDBn PORTBn I/O Pull-up Kommentar
0 0 Input No Tri-State (Hochohmig)
0 1 Input Yes Der Ausgang liefert einen Strom für z.B. Taster auf GND
1 0 Output No Push-pull Zero Output (Ausgang ist 0)
1 1 Output No Push-pull One Output (Ausgang ist 1)

Befehle, die mit Ports zu tun haben

Befehl Operand Beschreibung Beispiel Erklärung zum Beispiel
IN Rd,P Einlesen eines Port in Register in R16,PIND PortD einlesen in R16
OUT P, Rd Ausgeben eines Register in Port out PORTB,R16 R16 an PortB ausgeben
SBI P, b Setze Bit b in Port P sbi PORTB,2 Das Bit 2 an PortB setzen
CBI P, b Lösche Bit b in Port P cbi PORTB,2 Das Bit 2 an PortB löschen
SBIC P, b Überspringe, wenn Bit b in Port P gelöscht sbic PIND,4 wenn Bit gelöscht ist, wird der folgende Befehl übersprungen.
D.h. der folgende Befehl wird ausgeführt wenn Bit gesetzt..
SBIS p, b Überspringe, wenn Bit b in Port P gesetzt sbis PIND,4
rjmp testmode
Gehe in Tesmode wenn bei Power-On PGRM gedrückt,
d.h. gedrückt bedeutet Pin ist auf GND, Bit ist 0.

Atmel-RISC-8Bit Speicherkonzept am Beispiel des AT90S2313

Der Speicher ist gemäß der Harvard-Architektur in einen Programm- und einen Datenspeicher unterteilt. Der Programmspeicher ist wortweise (16 Bit) organisiert, d.h. Den 2 KiByte Flash-Speicher stehen nur 1 Ki Adressen $000..$3FF gegenüber. Der Datenspeicher ist byteweise organisiert:

  • $00 .. $1F sind die Register R0 bis R31
  • $20 .. $5F ist den I/O Komponenten (Ports, Timer, UART, usw.) zugeordnet
  • $60 .. $DF sind 128 Byte SRAM

Anmerkung: Das EEPROM (ohne Abbildung) wird über einen besonderen Mechanismus angesprochen, es gibt spezielle Befehle..

Wichtig: Zur Vereinfachung und zum Einsparen von Programmspeicher werden den Registern und I/O Adressen besondere Kurz-Zugriffe zugeordnet.

Beispiel: PORTB hat innerhalb des I/O Blocks die Adresse $18, bezogen auf den geammten Datenbereich die Adresse $38.
D.h. für manche Daten-Adressen gibt es zwei Zugriffsmöglichkeiten.

Praktisch werden die symbolischen Namen wie R16 oder PIND verwendet, somit muss man sich um die genauen Adressen keinen Kopf machen, sie sind in der jeweiligen *.inc Datei vordefiniert.

Direkte Adressierung

Register Direkt, einfach Register Direkt, mit zwei Registern
Beispiel: inc R16 ; erhöhe Register 16 um eins
Man beachte die Anzahl der Bits für die Kodierung des Operanden.
Beispiel: add R16, R17 ; R16 <- R16 + R17
Die Befehle sind meist genau 16 Bit lang.
I/O Direkt Daten Direkt
Beispiel: in R16, PIND ; Lade PIND in Register 16
6Bit -> 64 Port-Adressen!
Beispiel: lds R16, 0x60 ; Lade Inhalt des ersten SRAM-Bytes in R16
Dieser Befehl braucht zwei Wörter Platz wegen der 16 Bit SRAM Adresse
(es gibt auch grössere Controller)

Indirekte Daten-Adressierung

Daten Indirekt Mögliche Realisierung von char s[] = "ABI";
In das Register X alias R27 und R26 muss $61 geladen werden:
ldi R27,0
ldi R26, $61

Oder vornehmer:

ldi R27, high($61) ; ist 0
ldi R26, low($61) ; ist $61

Store Indirect via X:

ldi R16, 'A'
st X, R16
Daten Indirekt mit Post-Inkrement Daten Indirekt mit Prä-Dekrement
Store Indirect via X mit Increment von X:
ldi R16, 'A'
st X+, R16
ldi R16, 'B'
st X+, R16
usw...
Gibt es in allen 4 Variationen Prä-Post-Inkrement-Dekrement..
Daten Indirekt mit Displacement
Bei komplexeren Datenstrukturen z.B. Listen von Records bzw. Objekten wäre es praktisch zu
der Basisadresse des Objekts (Zeiger, Pointer auf Recotd bzw. Objekt) ein bestimmtes Feld bzw.
Attribut ansprechen zu können. Der Versatz der Feld- bzw. Attributadresse wird auch als
"Displacement" bezeichnet.
Beachte: Displacement hat nur 6Bit -> 0 .. 64

Beispiel für Array of Integer mit 16Bit:

int a,b[] = {1000,2000,3000}; // a zeigt auf $60, b zeigt auf $80
char i = 1; // i ist R20
a = b[i];

Die Adresse b[i] lässt sich mit Basisadresse b berechnen: b[i] = b + i*2, somit die Zuweisung a = b[i]:

ldi R29, high($80)
ldi R28, low($80)
lsl R20; nach links schieben ist i*2 nehmen
add R28, R20; b+ i*2 es gibt keinen Überlauf
ld R16, Y; hol das  low-Byte
sts $60, R16
ld R16, Y+1; hol das high-Byte
sts $61, R16
Programm-Speicher-Zugriff auf Konstanten und mit Post-Inkrement
Im Programm-Speicher können Konstanten abgelegt werden mit der Assembler-Direktive .db. Mit dem LPM-Befehl kann ein Byte aus dem Programmspeicher via Z-Register in ein Register kopiert werden. Da der Programmspeicher 16 Bit organisiert ist wird mit dem LSB des Z-Registers zwichen dem High- und Low-Byte einer Programm-Speicher-Adresse unterschieden.
ldi R31, high(kzeiger) ; High-Byte in Z
ldi R30, low(kzeiger) ; Low-Byte in Z
lpm R16, Z+ ; lade erste Konstante
; usw.
kzeiger: .db "ABI",0 ; die Konstante
Direkte Sprünge auf Programm-Adressen mit JMP und CALL Indirekte Sprünge auf Programm-Adressen mit IJMP und ICALL

Long Jump und Long Call, sind für grosse Sprünge sinnvoll 22-Bit Adressen.

Praktisch für Case-Anweisungen, bzw. Sprung-Tabellen.

Interrupts

Prog.-Adresse
90S2313
Interrupt-Quelle Interrupt-Definition
$000 Reset Power On-,/RST-Pin und Watchdog
$001 INT0 Externer Interrupt 0
$002 INT1 Externer Interrupt 1
$003 TIMER1 CAPT Timer/Counter 1 Capture
$004 TIMER1 COMPA Timer/Counter 1 Compare Match A
$005 TIMER1 OVF Timer/Counter 1 Overflow
$006 TIMER0 OVF Timer/Counter 0 Overflow
$007 UART, RX UART: Byte empfangen
$008 UART, UDRE UART: Datenregister leer
$009 UART, TX UART: Transfer beendet
$00A ANA_COMP Analog-Komparator
Je niedriger die Adresse, desto höher die Priorität des Interrupts.

 

© Oliver Mezger 04.04.2006 MezData.de Den Kontakt herstellen...