AVR Assembler Makros: Unterschied zwischen den Versionen
(→I/O) |
(→I/O) |
||
Zeile 46: | Zeile 46: | ||
==I/O== | ==I/O== | ||
Bei grösseren und neueren AVRs sind etliche I/O- | Bei grösseren und neueren AVRs sind etliche I/O-Register nicht mit IN/OUT-Befehlen ansprechbar. LDS/STS erreicht zwar alle, ist aber bei kleineren oder älteren ineffizient. | ||
=== Port lesen === | === Port lesen === |
Version vom 3. Dezember 2006, 21:33 Uhr
Hier entsteht eine Sammlung von verschiedenen nützlichen Makros für den AVR Assembler.
16 Bit Konstante in Z-Pointer laden
<avrasm> .MACRO SetZPtr ;(Adresse)
ldi ZL, LOW(@0) ldi ZH, HIGH(@0)
.ENDMACRO </avrasm>
Natürlich auch möglich mit X- und Y-Pointer.
Speicher
2 Register ohne Zwischenspeicher vertauschen
<avrasm> .MACRO SWAP ;(a, b)
eor @0, @1 eor @1, @0 eor @0, @1
.ENDMACRO </avrasm>
Arithmetik
Konstante addieren
<avrasm> .MACRO ADDI ;(a, k)
subi @0, -(@1)
.ENDMACRO </avrasm>
Konstante addieren (16 Bit)
<avrasm> .MACRO ADDIW ;(RdL:RdH, k)
subi @0L, LOW(-@1) sbci @0H, HIGH(-@1)
.ENDMACRO </avrasm>
I/O
Bei grösseren und neueren AVRs sind etliche I/O-Register nicht mit IN/OUT-Befehlen ansprechbar. LDS/STS erreicht zwar alle, ist aber bei kleineren oder älteren ineffizient.
Port lesen
<avrasm> .macro input
.if @1 < 0x40
in @0, @1
.else lds @0, @1 .endif
.endm </avrasm>
Port schreiben
<avrasm> .macro output
.if @0 < 0x40
out @0, @1
.else sts @0, @1 .endif
.endm </avrasm>
Portbit abfragen
Abfrage eines Bits eines I/O-Ports und Sprung wenn 1/0. Überschreibt u.U. ZL.
Branch if Bit in I/O-Register is Set <avrasm> .macro bbis ;port,bit,target
.if @0 < 0x20 sbic @0, @1
rjmp @2
.elif @0 < 0x40
in zl, @0 sbrc zl, @1 rjmp @2
.else
lds zl, @0 sbrc zl, @1 rjmp @2
.endif
.endm </avrasm>
Branch if Bit in I/O-Register is Cleared <avrasm> .macro bbic ;port,bit,target
.if @0 < 0x20 sbis @0, @1
rjmp @2
.elif @0 < 0x40
in zl, @0 sbrs zl, @1 rjmp @2
.else
lds zl, @0 sbrs zl, @1 rjmp @2
.endif
.endm </avrasm>