Pfad: Home => AVR-Überblick => Programmiertechniken => Ports

Programmiertechnik für Anfänger in AVR Assemblersprache

Was ist ein Port?

Ports sind eigentlich ein Sammelsurium verschiedener Speicher. In der Regel dienen sie der Kommunikation mit irgendeiner internen Gerätschaft wie z.B. den Timern oder der Seriellen Schnittstelle oder der Bedienung von äußeren Anschlüssen wie den Parallel-Schnittstellen des AVR. Der wichtigste Port wird weiter unten besprochen: das Status-Register, das an das wichtigste interne Gerät, nämlich den Akkumulator, angeschlossen ist.

Es gibt insgesamt 64 Ports, die aber nicht bei allen AVR-Typen auch tatsächlich physikalisch vorhanden sind. Je nach Größe und Ausstattung des Typs sind eine Reihe von Ports sinnvoll ansprechbar. Welche der Ports in welchem Typ tatsächlich vorhanden sind, ist letztlich aus den Datenblättern zu erfahren.

Ports haben eine feste Adresse, über die sie angesprochen werden können. Die Adresse gilt weitgehend unabhängig vom AVR-Typ. So befindet sich der Ausgabeport der Parallelschnittstelle B an der Portadresse 0x18 (0x für hexadezimal!). Die Adressen muss man sich aber nicht merken. In den Include-Dateien zu den einzelnen AVR-Typen, die der Hersteller zur Verfügung stellt, sind die jeweiligen verfügbaren Ports mit wohlklingenden Namen belegt. So ist in den Include-Dateien die Assemblerdirektive

.EQU PORTB, 0x18

angegeben und wir müssen uns fürderhin nur noch merken, dass der Port B PORTB heißt. Die Include-Datei 8515def.inc kommt mit folgender Direktive in die Quellcode-Datei:

.INCLUDE "C:\Irgendwo\8515def.inc"

und alle für diesen Typ bekannten Register sind jetzt mit ihrem Alias-Namen leichter ansprechbar.

Ports nehmen oft ganze Zahlen auf, sie können aber auch aus einer Reihe einzelner Steuerbits bestehen. Diese einzelnen Bits haben dann eigene Namen, so dass sie mit Befehlen zur Bitmanipulation angesteuert werden können. Diese Namen für Bitpositionen in einem Port sind auch in den Include-Dateien definiert, so dass man sich auch die konkrete Bitposition bestimmter Bits nicht mehr merken muss. Die Bitnamen sind in den Datenblättern und bei den hier detaillierter dargestellten Ports dargestellt.

So enthält z.B. das MCU General Control Register, genannt MCUCR, eine Reihe von Steuerbits, die das generelle Verhalten des Chips beeinflussen (siehe die Beschreibung des MCUCR im Detail). Ein vollgepackter Port, in dem jedes Bit noch mal einen eigenen Namen hat (ISC00, ISC01, ...). Wer den Port benötigt, um den AVR in den Tiefschlaf zu versetzen, muss sich im Typenblatt die Wirkung dieser Sleep-Bits heraussuchen und durch eine Befehlsfolge die entsprechende einschläfernde Wirkung programmieren, also z.B. so: ...

.DEF MeinLieblingsregister = R16
    LDI MeinLieblingsregister, 0b00100000
    OUT MCUCR, MeinLieblingsregister
    SLEEP


Der Out-Befehl bringt den Inhalt meines Lieblingsregisters, nämlich ein gesetztes Sleep-Enable-Bit SE, zum Port MCUCR und versetzt den AVR gleich und sofort in den Schlaf, wenn er im ausgeführten Code eine SLEEP-Instruktion findet. Da gleichzeitig alle anderen Bits mitgesetzt werden und mit Sleep-Mode SM=0 als Modus der Halbschlaf eingestellt wurde, geht der Chip nicht völlig auf Tauchstation. In diesem Zustand wird die Befehlsausführung eingestellt, die Timer und andere Quellen von Interrupts bleiben aber aktiv und können den Halbschlaf jederzeit unterbrechen, wenn sich was Wichtiges tut.

Umgekehrt lassen sich die Portinhalte mit dem IN-Befehl in beliebige Register einlesen und dort weiterverarbeiten. So lädt

.DEF MeinLieblingsregister = R16
    IN MeinLieblingsregister, MCUCR


den lesbaren Teil des Ports MCUCR in das Register R16. Den lesbaren Teil deswegen, weil es bei vielen Ports auch nicht belegte Bits gibt, die dann immer als Null eingelesen werden.

Noch öfter als ganze Ports einlesen muss man auf Änderungen bestimmter Bits der Ports prüfen. Dazu muss nicht der ganze Port gelesen und verarbeitet werden. Es gibt hierfür spezielle Sprungbefehle, die aber im Kapitel Springen vorgestellt werden. Umgekehrt kommt es oft vor, dass ein bestimmtes Portbit gesetzt oder rückgesetzt werden muss. Auch dazu braucht man nicht den ganzen Port lesen und nach der Änderung im Register dann den neuen Wert wieder zurückschreiben. Die beiden Befehle heissen SBI (Set Bit I/O-Register) und CBI (Clear Bit I/O-Register). Ihre Anwendung geht z.B. so:

.EQU Aktivbit=0 ; Das zu manipulierende Bit des Ports
    SBI PortB, Aktivbit ; Das Bit wird Eins
    CBI PortB, Aktivbit ; Das Bit wird Null

Die beiden Befehle haben einen gravierenden Nachteil: sie lassen sich nur auf Ports bis zur Adresse 0x1F anwenden, für Ports darüber sind sie leider unzulässig.

Für den Exotenprogrammierer gibt es wie bei den Registern auch hier die Möglichkeit, die Ports wie ein SRAM zu lesen und zu schreiben, also mit dem LD- bzw. dem ST-Befehl. Da die ersten 32 Adressen schon mit den Registern belegt sind, werden die Ports mit ihrer um 32 erhöhten Adresse angesprochen, wie z.B. bei

.DEF MeinLieblingsregister = R16
    LDI ZH,HIGH(PORTB+32)
    LDI ZL,LOW(PORTB+32)
    LD MeinLieblingsregister,ZL


Das macht nur im Ausnahmefall einen Sinn, geht aber halt auch. Es ist der Grund dafür, warum das SRAM erst ab Adresse 0x60 beginnt (0x20 f&uum;r die Register, 0x40 für die Ports reserviert).

Zum Seitenanfang

Details wichtiger Ports in den AVR

Die folgende Tabelle kann als Nachschlagewerk für die wichtigsten gebräuchlichsten Ports dienen. Sie enthält nicht alle möglichen Ports. Insbesondere die Ports der MEGA-Typen und der AT90S4434/8535 sind der Übersichtlichkeit halber nicht darin enthalten! Bei Zweifeln immer die Originaldokumentation befragen!  
GerätLinkRegisterLink
AkkumulatorSREG Status RegisterSREG
StackSPL/SPH StackpointerSPL/SPH
Ext.SRAM/
Ext.Interrupt
MCUCR MCU General Control RegisterMCUCR
Ext.Int.INT Interrupt Mask RegisterGIMSK
Flag RegisterGIFR
Timer InterruptsTimer Int. Timer Int Mask RegisterTIMSK
Timer Interrupt Flag RegisterTIFR
Timer 0Timer 0 Timer/Counter 0 Control RegisterTCCR0
Timer/Counter 0TCNT0
Timer 1Timer 1 Timer/Counter Control Register 1 ATCCR1A
Timer/Counter Control Register 1 BTCCR1B
Timer/Counter 1TCNT1
Output Compare Register 1 AOCR1A
Output Compare Register 1 BOCR1B
Input Capture RegisterICR1L/H
Watchdog TimerWDT Watchdog Timer Control RegisterWDTCR
EEPROMEEPROM EEPROM Adress RegisterEEAR
EEPROM Data RegisterEEDR
EEPROM Control RegisterEECR
SPISPI Serial Peripheral Control RegisterSPCR
Serial Peripheral Status RegisterSPSR
Serial Peripheral Data RegisterSPDR
UARTUART UART Data RegisterUDR
UART Status RegisterUSR
UART Control RegisterUCR
UART Baud Rate RegisterUBRR
Analog ComparatorANALOG Analog Comparator Control and Status RegisterACSR
I/O-PortsIO-Ports   


Zum Seitenanfang

Das Statusregister als wichtigster Port

Der am häufigste verwendete Port für den Assemblerprogrammierer ist das Statusregister mit den darin enthaltenen acht Bits. In der Regel wird auf diese Bits vom Programm aus nur lesend/auswertend zugegriffen, selten werden Bits explizit gesetzt (mit dem Assembler-Befehl SEx) oder zurückgesetzt (mit dem Befehl CLx). Die meisten Statusbits werden von Bit-Test, Vergleichs- und Rechenoperationen gesetzt oder rückgesetzt und anschliessend für Entscheidungen und Verzweigungen im Programm verwendet.

Die folgende Tabelle enthält eine Liste der Assembler-Befehle, die die jeweiligen Status-Bits beeinflussen.
BitRechnenLogikVergleichBitsSchieben Sonstige
ZADD, ADC, ADIW, DEC, INC, SUB, SUBI, SBC, SBCI, SBIW AND, ANDI, OR, ORI, EOR, COM, NEG, SBR, CBR CP, CPC, CPI BCLR Z, BSET Z, CLZ, SEZ, TST ASR, LSL, LSR, ROL, ROR CLR
CADD, ADC, ADIW, SUB, SUBI, SBC, SBCI, SBIW COM, NEG CP, CPC, CPI BCLR C, BSET C, CLC, SEC ASR, LSL, LSR, ROL, ROR -
NADD, ADC, ADIW, DEC, INC, SUB, SUBI, SBC, SBCI, SBIW AND, ANDI, OR, ORI, EOR, COM, NEG, SBR, CBR CP, CPC, CPI BCLR N, BSET N, CLN, SEN, TST ASR, LSL, LSR, ROL, ROR CLR
VADD, ADC, ADIW, DEC, INC, SUB, SUBI, SBC, SBCI, SBIW AND, ANDI, OR, ORI, EOR, COM, NEG, SBR, CBR CP, CPC, CPI BCLR V, BSET V, CLV, SEV, TST ASR, LSL, LSR, ROL, ROR CLR
SSBIW - - BCLR S, BSET S, CLS, SES - -
HADD, ADC, SUB, SUBI, SBC, SBCI NEG CP, CPC, CPI BCLR H, BSET H, CLH, SEH - -
T- - - BCLR T, BSET T, BST, CLT, SET - -
I- - - BCLR I, BSET I, CLI, SEI - RETI


Zum Seitenanfang

©2002 by http://www.avr-asm-tutorial.net