Assembler - Tips

From XennisWiki
Jump to: navigation, search

Tips zur Programmierung in Assembler.

Atmel AVR - ATmega 16

Tips zur Programmierung des Mikrocontrollers Atmel AVR - ATmega 16.

Stackpointer initialisieren

;Stackpointer initialisieren
ldi	R16,	high(RAMEND)
out	SPH,	R16
ldi	R16,	low(RAMEND)
out	SPL,	R16

I/O Register am Beispiel Port

; Port x (A, B, C oder D) initialisieren
ldi	R16,	0x05		; Alle Pins die als Ausgabe dienen auf "1" setzen, alle Pins die als Eingabe dienen auf "0" setzen
out	DDRx,	R16			; hier: 0x05 = 0000.0101 => Px0=1 udn Px2=1 als Ausgabe
ldi	R16,	0x04		; Low oder High an den enstprechenden Pins anlegen
out	PORTx,	R16			; hier: 0x04 = 0000.0100 => Px2=1 anlegen

; Port x einlesen
in	R16,	PINx		; Port x einlesen

; Nur ein bestimmtes Bit des Ports überprüfen (hier: Px2)
in	R16,	PINx		; Bsp: 0010.1100
andi	R16,	1<<Px2		;      0000.0100
; Z=1 => Px2=0 (d.h. springe bei "breq")
; Z=0 => Px2=1 (d.h. springe bei "brne")
; Einzelnes Bit auf Low legen (hier: Px2)
cbi	PORTx,	Px2

; Einzelnes Bit auf High legen (hier: Px2)
sbi	PORTx,	Px2
; Auf einzelnes Bit triggern (hier: Px2)
triggerRising:
	; Analog für normale Register: sbrs
	sbis	PINx,	PINx2	; Wenn PINx2=1 => überspringe die Folgende Zeile
	jrmp	triggerRising

triggerFalling:
	; Analog für normale Register: sbrc
	sbic	PINx,	PINx2	; Wenn PINx2=0 => überspringe die Folgende Zeile
	jrmp	triggerFalling


; Analog zu SBR (Set Bit in Register): CBR (Clear Bit in Register)
in	R16,	TIMSK
sbr	R16,	(1<<OCIE0)
out	TIMSK,	R16

Interrupt-Tabelle (im ROM)

Beispiel

.cseg
.org	$0000		jmp
	init
.org	INT0addr	jmp	; External Interrupt0 Vector Address
	isr_int0
.org	ADCCaddr	jmp	; ADC Conversation Complete Interrupt Vector Address
	isr_adc

.dseg	$0030
; [...] Programm

Daten im RAM speichern

.dseg
.org	$60
	Ein_Byte:	.byte	1
	Neun_Byte:	.byte	9

.cseg
	; Wert in Variable speichern
	ldi	R16,		42
	sts	Ein_Byte,	R16

	; Wert der Variable auslesen
	lds	R16,		Ein_Byte

Tabelle in ROM auslesen

; [...]
.cseg
; [...]
.org	$002A
; Tabelle "Tab" (.db: double byte)
Tab:	.db	0x08,   0x07,	0x06, \
		0x05,	0x04,	0x03

; [...]

; Tabelle auslesen
readTab:
	ldi	ZL,	low(Tab<<1)	; Z-Pointer auf die Adresse der Tabelle setzen
	ldi	ZH,	high(Tab<<1)
	lpm	R16,	Z+		; Erster Wert der Tabelle wird in R16 gespeichert (hier: 0x08)
	lpm	R17,	Z+		; Zweiten Wert in R17 speichern (hier: 0x07)
; Einen bestimmten Wert aus der Tabelle auslesen
readTabValue5:
	ldi	ZL,	low(Tab<<1)	; Z-Pointer auf die Adresse der Tabelle setzen
	ldi	ZH,	high(Tab<<1)
	adiw	Z,	4		; 5. Wert soll ausgelesen, d.h. 1 Wert + 4
	lpm	R16,	Z		; 5. Wert der Tabelle (hier: 0x04)
; Alle Werte der Tabelle in einer Schleife auslesen
.def	Count = R17
readTabInit:
	ldi	Count,	6		; Tabelle hat 6 Einträge
	ldi	ZL,	low(Tab<<1)	; Z-Pointer auf die Adresse der Tabelle setzen
	ldi	ZH,	high(Tab<<1)
readTabLoop:
	lpm	R16,	Z+		; Wert(i) der Tabelle wird in R16 gespeichert
	dec	Count
	brne	readTabLoop