Pfad:
Home =>
AVR-Übersicht => AVR-Architektur
(This page in English:
)
Überblick über die Architektur von AVRs
Das Folgende gibt einen Überblick über AVRs für
Anfänger. Es beschreibt
allgemeine Eigenschaften aller AVR-Typen
und die in den AVRs intern verfügbare Hardware
für den praktischen Einsatz. In Auswahl
wird ein Tool beschrieben, mit dem der optimale AVR-Typ
anhand der erforderlichen Hardware ausgewählt werden
kann.
Die AVR sind eine Serie von 8-Bit-Mikroprozessoren, genannt
ATtiny, ATmega und ATxmega. Ältere Typen hießen
AT89 und AT90S. Alle diese Typen sind durch die folgenden
Eigenschaften charakterisiert:
- Sie arbeiten mit einer Betriebsspannung in einem weiten Bereich
von 1,7 bis 5,5 V, mit Taktraten von weniger als 10 kHz
bis maximal 20 MHz, und benötigen sehr geringe
Betriebsströme (abhängig vom Typ, der Taktrate,
der Betriebsspannung, dem Betriebsmodus und den
auszuführenden Instruktionen), generell weniger als
5 mA. Einige Untertypen sind speziell für den
Batteriebetrieb ausgelegt.
- Sie alle verwenden den gleichen 16-Bit-Befehlssatz und
die gleiche Kernprozessor-Architektur. Etwa 130 verschiedene
Befehle bieten eine große Vielfalt arithmetischer und
logischer Operationen. Unbedingte und bedingte Verzweigungen
und eine Vielzahl verschiedener Schreib- und Lesebefehle mit
16-Bit-Zeigern.
Einige der zulässigen Instruktionen in AVR-Assembler
sind Mogelpackungen:
- So gibt es eine Instruktion namens TST r, die
dasselbe tut wie OR r,r oder AND r,r und
denselben Maschinencode produziert wie das AND,
- SBR r,k tut dasselbe wie ORI r,k,
- CBR r,k tut dasselbe wie ANDI r,255-k,
- SER r tut dasselbe wie LDI r,255,
- SEI bis SEC tun dasselbe wie BSET I
bis BSET C
- CLI bis CLC tun dasselbe wie BCLR I
bis BCLR C
Solche Mogelpackungen sind in der folgenden Tabelle nicht mit
einem "X" als exklusiv gekennzeichnet.
Aus den 130 Instruktionen wird so eine etwas niedrigere Anzahl
von 78, aber immer noch ganz schön viele. Jedenfalls mehr
als doppelt so viele wie bei PICs zuhause.
Und einige davon sind sehr, sehr mächtig. So gibt es
Schreib- und Lesebefehle für das SRAM mit vier
verschiedenen Adressierungsarten:
- Mit Angabe der festen Adresse in der Instruktion (STS,
LDS),
- ST und LD mit der Adresse in den Doppelregistern X
(R27:R26), Y (R29:R28), oder Z (R31:R30),
- ST und LD mit X, Y oder Z mit vorherigem Vermindern
(ST -Z,R) oder nachträglichem Erhöhen (ST Z+,R)
der Adresse,
- STD und LDD mit der Basisadresse in Y oder Z unter
zeitweiligem Addieren einer Ablage N (STD Z+N,R)
zur Adresse.
So können auch komplexe Datenstrukturen im SRAM optimal
angesteuert werden.
- Die Instruktionen sind meistens ein Wort (16 Bit) lang und
werden schon während der Bearbeitung des vorhergehenden
Befehls aus dem Programmspeicher gelesen und dekodiert (falls
die vorausgehende Instruktion kein Sprungbefehl war). Dieses
pre-fetch verdoppelt nahezu die Ausführungsgeschwindigkeit.
Die meisten Instruktionen benötigen für die
Ausfürung einen einzigen Takt.
- Die Dauer, die Befehle benötigen, sind exakt vorhersehbar.
Alle Verzögerungen, die sich aus länger zu bearbeitenden
Operationen ergeben, wie z.B. EEPROM-Leseoperationen oder
Interruptaufrufe, sind exakt spezifiziert und können
berücksichtigt werden.
- Instruktionen und Konstanten sind in einem elektrisch
lösch- und programmierbaren Flashspeicher gespeichert.
Der Speicher kann daher fast beliebig oft gelöscht und
erneut mit einem geänderten Inhalt programmiert werden.
Er kann ferner durch Setzen von Hardware-Fuse-Bits gegen
Auslesen geschützt werden (Lock-Bits).
- In 32 8-Bit-Registern, von denen acht als 16 Bit breite
Zähler und sechs als 16-Bit-Zeiger eingesetzt werden
können, können schnell zugängliche Werte
gespeichert und mit direkten Einzelbefehlen manipuliert
werden, wie z.B. ADDieren oder SUBtrahieren.
- Das 8 Bit breite Statusregister SREG speichert alle
Flaggen, die die CPU bei der Bearbeitung der Instruktionen
ermittelt, wie z.B. die Nullflagge Z (zero) oder die
Überlaufflagge C (carry). Alle Flaggen können
mit Einzelinstruktionen auf Null (clear) oder Eins (set)
gesetzt werden. Ein Bit im SREG, das T-Bit, wird von
der Befehlsbearbeitung nicht beeinflusst und kann für
eigene Zwecke verwendet werden (z. B. als
Zwischenspeicher für ein einzelnes Bit oder zum
Kopieren eines Bits in ein anderes Register) oder auch als
Ein-Bit-Flagge.
- Im Controller eingebaute Hardware, wie z.B. Treiber von
Ein- und Ausgabepins, Timer, AD-Wandler, assynchrone und
synchrone serielle Kommunikation, Analogvergleicher,
kann von der CPU durch Schreiben mit OUT-Instruktionen in
64 8-Bit-Ports konfiguriert und mit IN auch wieder ausgelesen
werden. Die untere Hälfte der 64 Ports kann ferner mit
Lesen/Ändern/Schreiben-Instruktionen Bit für Bit
mit CBI (Clear Bit I/o) und SBI (Set Bit I/o) gelöscht
oder gesetzt werden.
Ein- und Ausgabesignale der internen Hardware, wie z. B.
die Vergleicher in Timern, können externen Pins
zugeordnet werden, womit die Signale extern verfügbar
werden. Das Setzen, Löschen oder Torkeln solcher Pins
erfolgt dann automatisch und bedarf keiner
Extra-Instruktionen.
In kleineren Typen mit wenigen Pins kann jeder einzelne Pin
mit vielen unterschiedlichen Signalen belegt werden, wie hier
für die DIP-Versionen von zwei ATtiny-Typen gezeigt
(bis zu sieben unterschiedliche Signale pro Pin):
Die 32 Register und alle Ports sind adressmäßig
gespiegelt: die Register tragen Adressen von 0 bis 31,
die Ports von 32 aufwärts und können auf diese
Weise mit direkter oder indirekter Adressierung angesprochen
werden. In neueren Typen mit sehr viel interner Hardware
können daher mehr als 64 Ports vorhanden sein
und mit Schreib- und Leseoperationen angesprochen werden.
- Alle AVRs (außer der uralte Typ AT90S1200) haben
eingebauten statischen RAM-Speicher an Bord. Die
verfügbaren Speicherstellen zu je 8 Bit können
mit drei verschiedenen Addressierungsmodi beschrieben und
gelesen werden:
- direkte Adressierung (Adresse als zweites Wort des
Befehlsworts),
- indirekte Adressierung mit drei verschiedenen
16-Bit-Zeigern, die zusätzlich nach dem
Lesen/Schreiben automatisch erhöht oder zuvor
vermindert werden können,
- indirekte Adressierung mit zeitweiligem Versatz,
wofür zwei 16-Bit-Zeiger verfügbar sind.
- Der obere Teil des statischen RAM-Speichers kann als
automatisch arbeitender Stapelspeicher verwendet werden.
Registerinhalte können mit PUSH auf dem Stapel
abgelegt und mit POP dem Stapel wieder entnommen werden
(Last-In-First-Out, LIFO). Bei Unterprogrammaufrufen
(RCALL oder CALL) und bei Interrupts wird die
Aufrufadresse automatisch auf dem Stapel abgelegt und
bei der Rückkehr (RET, bei Interrupts RETI) diesem
wieder entnommen. Diese automatische Manipulation des
Stapelzeigers vereinfacht die Stapelkontrolle.
- Alle internen Hardwarekomponenten können die CPU
unterbrechen (Interrupt), wenn diese durch Setzen
entsprechender Bits in den Porteinstellungen eingeschaltet
wurden. Beim Interrupt verzweigt die CPU an festgelegte
Programmadressen (Vektoren) im Programmspeicher. Die Reaktion
auf Interruptanforderungen ist priorisiert, höherrangige
Interrupts stehen in der Vektorenliste weiter oben (bei
niedrigeren Adressen), wie z.B. der externe Interrupt oder
Timerinterrupts.
- Um Daten so zu speichern, dass sie auch den Verlust der
Versorgungsspannung überstehen und verfügbar bleiben,
verfügen alle AVR über einen EEPROM-Speicher.
EEPROM-Speicher kann elektrisch gelöscht, wieder
beschrieben und ausgelesen werden. Lesen erfolgt sehr
schnell, Schreiben benötigt wenige Millisekunden.
Das Schreiben kann interruptgesteuert erfolgen.
- Alle AVRs haben einen Watchdog-Timer (Wachhund). Dieser
startet den Controller neu, wenn er nicht regelmäßig
zurückgesetzt wird. Das ermöglicht auch in
ungeplanten Situationen einen sicheren Betrieb.
- Interne Hardware-Eigenschaften, wie z.B. der Brown-Out-Detector
(erkennt einen kurzzeitigen Einbruch der Versorgungsspannung),
die Einstellung von internen oder externen Taktquellen wie
Quarzen oder Quarzoszillatoren, der Leseschutz des
Programmspeichers, etc., können mittels Auswahl von
entsprechenden Fuses verstellt werden.
- Der Zugang zu den Fuses, Schreib- und Lesezugriffe auf den
Programm- und EEPROM-Speicher können im seriellen Modus
oder, bei größeren Typen, im Parallelmodus
erfolgen. Das Lesen/Schreiben im seriellen Modus erfordert eine
Taktleitung (SCK), eine Lese- (MOSI) und eine Schreibleitung
(MISO). Die Polarität dieser drei Pins wird geändert,
wenn der RESET-Eingang durch das Programmiergerät extern
auf niedriges Potential gezogen wird. Das Programmieren im
seriellen Modus kann in der Schaltung selbst mit der (niedrigen)
Versorgungsspannung des Zielsystems erfolgen
(In-System-Programming, ISP). Parallelprogrammierung und
Programmierung bei erhöhter Spannung (+12 V am RESET-Pin)
ermöglichen die Programmierung auch von solchen Prozessoren,
bei denen der RESET-Pin durch Setzen der Disable-Fuse
umkonfiguriert wurde.
Das folgende Bild gibt einen vereinfachten Überblick über
alle verfügbaren Speicher in den AVRs. Die 32 Register und die 64
Ports können zusätzlich auch mit den 16-Bit-Zeigern gelesen
und beschrieben werden (direkte Adressierung mit LDS oder STS,
indirekte Adressierung mit LD oder ST). Daher beginnt das SRAM bei
höheren Adressen (0x0060 oder höher).
Die Benennungen von Ports und deren Adressen, der Start und das Ende
des SRAMs und alle anderen typ-spezifischen Parameter sind in Dateien
mit den Namen "devicedef.inc" angegeben, bei denen
"device" z.B. mit "tn13" oder "m8A"
angegeben wird. Alle typspezifische Hardware, alle Modi dieser
Hardware und deren Konfiguration und die elektrischen Eigenschaften
der verschiedenen AVR sind in den Datenbüchern (Devive Data Book)
beschrieben und können bei
Microchip
als PDF-Dateien abgeholt werden.
2.1 Ein- und Ausgabepins
Alle externen Pins des Controllers, außer den Stromversorgungspins
VCC und GND sowie (normalerweise) der RESET-Eingang, können
als Ein- und Ausgabepins konfiguriert werden. Das kann für
jeden Pin in drei verschiedenen Modi erfolgen (x = Port A, B, C, ...;
n = Portpin 0, 1, ...):
- als Ausgabepin: wird das Richtungsbit (direction bit) im
DDRxn-Port auf Eins gesetzt, wird der Ausgangstreiber eingeschaltet.
Das Bit PORTxn bestimmt dann darüber, ob der Pin Eins
(nahe Plus der Betriebsspannung) oder Null (nahe Minus der
Betriebsspannung) wird. Der Pin kann im Eins-Zustand bis zu
50 mA treiben, im Null-Zustand bis zu 70 mA.
- als hochohmiger Eingabepin: ist das Richtungsbit im DDxn-Port
Null, wird der Ausgangstreiber abgeschaltet. Der Zustand des
Pins kann im Port PINxn gelesen werden. Eingabepins haben einen
extrem hohen Eingangswiderstand und eine kleine
Schmitt-Trigger-Spannung (der Pin geht erst bei einer etwas
höheren Spannung auf Eins und bei einer etwas niedrigeren
auf Null, auch Schaltschwelle oder Hysterese genannt).
- als Eingabepin mit einem Pull-Up-Widerstand: bei gelöschtem
Richtungsbit DDRxn und gesetztem PORTxn-Bit wird ein Widerstand
von etwa 50 kΩ vom Eingabepin zur positiven
Betriebsspannung geschaltet. Das reduziert den Eingangswiderstand.
Sofern der Pin nicht extern auf niediges Potenzial gezogen wird,
liefert er beim Lesen Eins.
Das folgende Bild zeigt den Ausgangstreiber, die Eingangsstufe und den
Pull-Up-Widerstand eines einzelnen Portpins im Detail, in diesem Fall
PB0.
Alle Einstellungen an Portpins können jederzeit von der Software
geändert werden, so dass z.B. Operationen in beiden Richtungen
(bi-directional) möglich sind.
Externe Pegelwechsel an bestimmten Eingabepins können einen
externen Interrupt auslösen. Kleinere Typen haben dafür
den INT0-Eingang, größere zusätzlich INT1 oder gar
INT2. Diese Pins können so konfiguriert werden, dass sie bei
Pegelwechseln von Null auf Eins, von Eins auf Null oder bei beiden
Pegelwechseln einen Interrupt auslösen. In einem weiteren Fall
wird der Interrupt so lange ausgelöst wie der Eingang auf Null
bleibt.
Zusätzlich können in vielen AVR-Typen aber auch alle
anderen Pins als Interrupt-Auslöser konfiguriert werden. Dieser
Interrupt wird als PCINTn bezeichnet. Nur diejenigen
PCINT-Eingänge lösen einen Interrupt aus, deren Bit in
einer Maske Eins gesetzt ist. Sind mehr als ein Bit gesetzt, muss
per Software festgestellt werden, welcher von den Pins den Interrupt
ausgelöst hat. Alle Pegelwechsel lösen PCINT aus.
Die meisten Portpins können auch für ausgewählte
andere Zwecke eingesetzt werden. Daher sollte die Beschreibung
der Ports konsultiert werden.
2.2 Timer/Counter
Die eingebauten Timer/Counter können für etliche Aufgaben
eingesetzt werden:
- um die Zeit zu bestimmen die zwischen zwei Ereignissen
vergangen ist, wie z.B. zwischen zwei Tastendrücken,
zwischen jedem Pegelwechsel eines externen Signals oder
Wechseln des Ergebnisses des Analogvergleichers,
- um eine Reaktion des Controllers auf ein Ereignis um
eine festgelegte Dauer zu verzögern, z.B. 10
Minuten nach dem Einschalten der Betriebsspannung,
8 µs nachdem ein Schalter betätigt wurde,
- um automatisch einen externen Pin aus- und anzuschalten,
z.B. um ein Audiosignal mit 440 Hz zu erzeugen oder
um eine LED im 2-Hz-Rhytmus blinken zu lassen,
- um einen externen Pin für eine bestimmte Zeit lang
ein- und wieder auszuschalten, um damit die Drehzahl eines
Motors oder die Helligkeit einer LED zu regeln,
- um die Anzahl Signale an einem Pin in einem bestimmten
Zeitraum zu zählen, z.B. für einen
Frequenzzähler,
- um in regelmäßigen Zeitabständen eine
AD-Wandlung anzustoßen, deren Ergebnis dann per
AD-Conversion-Complete-Interrupt abgeholt werden kann.
Timer/Counter können im Timer-Modus vom Prozessortakt oder
aus einem Vorteiler mit einer Teilerrate von 1, 8, 64, 256 oder
1024 getaktet werden. Im Zählermodus kann ein externes
Signal den Takt angeben, entweder bei steigendem oder fallendem
Signalpegel.
Timer/Counter können entweder 8 oder 16 Bit haben. Alle
AVR-Timer haben mindestens einen oder meist zwei Vergleicher
an Bord. Diese können dazu verwendet werden, um den
Zählerstand bei ganz bestimmten Werten zu erkennen und
z.B. einen Interrupt auszulösen.
Zusätzlich können die Vergleicher dazu benutzt werden,
um bestimmte Ausgänge auf Eins oder Null zu setzen oder
ihre Polarität umzukehren (toggle). Diese Pins heißen
OCnA oder OCnB, wobei n die Timer/Counter-Nummer ist (0, 1, 2 ...).
Timer/Counter können einen Interrupt auslösen
- wenn sie überlaufen (im normalen Modus bei 8 Bit:
255 auf 0; 16 bit: 65535 auf 0), der Interrupt heißt
TCnOVF,
- wenn der Vergleicher (A und/oder B) Gleichheit festgestellt
hat, genannt TCn_COMPA oder TCn_COMPB.
Zahlreiche unterschiedliche Timer/Counter modi sind wählbar:
- Normaler Modus: der Timer zählt aufwärts. Wenn er
255/65535 erreicht, beginnt er bei Null von vorne.
- CTC Modus (Clear timer on compare): Der Timer zählt
aufwärts. Wenn er den Top-Wert im Vergleichsregister
COMP-A oder im Port ICR erreicht, setzt der Timer mit dem
nächsten Impuls auf Null zurück. Dieser Modus
kann verwendet werden, um digitale Signale einer bestimmten
Frequenz zu erzeugen.
- Schneller PWM-Modus (Fast PWM): der Timer zählt
aufwärts. Wenn er den Vergleicherwert erreicht, kehrt
er die Polarität eines Pins um. Erreicht der Timer
den höchsten Wert (in COMP-A oder ICR) wird der externe
Pin auf Null oder Eins gesetzt. Das entstehende Signal wird
als pulsweiten-moduliert bezeichnet.
- Phasen-korrekter PWM-Modus (phase correct PWM): der
Timer zählt aufwärts, wenn er den Top-Wert erreicht
zählt er abwärts. Jedes Mal, wenn der Timerstand
aufwärtszählend den Vergleichswert erreicht, wird
der Signalausgang gesetzt oder gelöscht, beim
Abwärtszählen umgekehrt. Das erzeugt ein
phasenkorrektes Ausgangssignal.
Handelt es sich beim Timer/Counter um ein 16 Bit Exemplar muss
eine bestimmte Prozedur eingahalten werden, damit die oberen
8 Bits und die unteren 8 Bits gleichzeitig in den Port geschrieben
werden. Dazu wird ein einzelnes Byte nicht direkt geschrieben,
sondern zeitweise in einem Puffer aufbewahrt und erst mit dem
zweiten Byte zusammen in das Zielregister geschrieben oder aus
diesem gelesen werden. Das garantiert, dass alle 16 Bits
zusammengehörig geschrieben und gelesen werden.
Bei den PWM-Modi werden die Vergleichsregister nicht sofort
geschrieben. Das Schreiben erfolgt erst dann, wenn der jeweilige
Zyklus von Neuem beginnt. Das ermöglicht es, den neuen
Vergleichswert jederzeit schreiben zu können ohne den
laufenden Ablaufzyklus zu stören.
Der Timer/Counter Betriebsmodus, die Vorteilerauswahl, die
Pinwechselmodi und die Interruptauswahl werden in drei Ports
kontrolliert.
2.3 AD-Wandler
Die meisten AVR haben einen 10-Bit-AD-Wandler an Bord. Dieser
wandelt analoge Spannungen an den AINn-Pins in einen Digitalwert
um. Als Referenz dabei dient entweder die Betriebsspannung, eine
eingebaute Konstantspannungsquelle von 1,1 V oder (in
wenigen Fällen) eine extern zugeführte Referenzspannung.
Der als Analogeingang ausgewählte Portpin und die
Referenzspannung werden in dem Port ADMUX eingestellt.
Das Einleiten einer Wandlung wird durch das Setzen des ADSC-Bits
im AD-Kontrollport ADCSRA gestartet. Alternativ kann auch ein
externes Ereignis (Pegelwechsel an einem Pin) oder ein
Timer-Ereignis (Überlauf, Vergleich) zum Starten veranlassen
(Setzen des Bits ADATE im Kontrollport).
Die Umwandlung wird mit der Methode der sukzessiven Approximation
ausgeführt. Dazu wird in einer schrittweisen Näherung
jeweils die halbe Referenzspannung verglichen. Ist die
Eingangsspannung kleiner, ist das oberste Bit Null. Im nächsten
Schritt wird ein Viertel der Referenzspannung zum Wert dazu addiert
und erneut verglichen. Usw. usf. bis alle 10 Bits ermittelt sind.
Die Taktung dieses Annäherungsprozesses erfolgt aus dem
Prozessortakt durch Teilen mit 2, 4, 8 oder einer höheren
Teilerrate bis 128. Eine Wandlung benötigt 13 AD-Wandlertakte,
wenn der AD-Wandler vor dem Start der Wandlung eingeschaltet war.
Der erfolgte Abschluss der Wandlung kann am Bit ADSC im
AD-Kontrollwort ermittelt werden. Mit dem ADEN-Bit in diesem Port
kann bei Abschluss der Wandlung der ADC_RDY-Interrupt ausgelöst
werden.
Normalerweise dient nur ein mit ADMUX auswählbarer AINn-Pin
zur Messung. In einigen neueren Typen ist es aber möglich,
zwei Pins zu verwenden und die Differenz der Spannung an den beiden
Pins zu messen. Es ist zusätzlich möglich, diese Differenz
um das 20-fache oder bis zum 100-fachen zu verstärken (gain).
Die beiden Pins und die Verstärkung werden im ADMUX-Port
eingestellt. Ist die Differenz an den beiden Eingangspins negativ,
kann die Ausgabe negativer Werte eingestellt werden, wobei das
höchste Bit des Ergebnisses zum Vorzeichen wird.
Einige wenige AVR-Typen haben einen Temperatursensor an Bord,
der in ADMUX ebenfalls als Eingangswert eingestellt werden kann.
Die gemessenen Temperaturwerte haben eine Genauigkeit von 1°
und müssen justiert werden.
2.4 Analogvergleicher
Alle AVR-Typen haben einen Analogvergleicher an Bord. Dieser
vergleicht Analogspannungen an zwei Pins AIN0 und AIN1. Das
Vergleichsergebnis kann vom Port ACSR gelesen werden.
Wechsel im Ergebnis können einen ANA_COMP-Interrupt
auslösen, wenn das Enable-Bit im Kontrollport ACSR gesetzt
ist.
2.5 EEPROM
Alle AVR-Typen haben EEPROM-Speicher an Bord. Sein Inhalt bleibt
über sehr lange Zeiten erhalten, die maximale Anzahl an
Schreiboperationen ist spezifiziert.
Der Standard-Inhalt des EEPROMs, wenn ein neues Exemplar
ausgeliefert wird oder nachdem eine Löschoperation
ausgeführt wurde, ist 255dezimal oder
FFhex.
EEPROM-Speicherstellen können gelesen werden durch
- Schreiben der gewünschten Adresse in den
EEPROM-Adress-Port,
- das Setzen des Read-Enable-Bits im EEPROM-Kontrollport,
- Einlesen des Ergebnisses aus dem EEPROM-Daten-Port.
Das Schreiben von Daten in das EEPROM erfolgt durch folgenden
Algorithmus:
- Schreiben der gewünschten Adresse in den
EEPROM-Adress-Port,
- Schreiben des Datenbytes in den EEPROM-Daten-Port,
- Setzen der Schreibmodus-Bits (nur Programmieren, nur
Löschen, Löschen und Programmieren) im
EEPROM-Kontrollport,
- Setzen des EEPROM-Write-Enable-Bits in diesem Port,
- Setzen des EEPROM-Write-Bits in diesem Port.
Der Schreibfortschritt kann durch Lesen des Write-Bits
erfolgen. Der Abschluss des Schreibvorgangs kann einen
EE_RDY-Interrupt auslösen, wenn das Enable-Bit im
EEPROM-Kontrollregister dafür gesetzt ist.
2.6 Asynchrone Empfangs-/Sendeeinrichtung, USARTs
Größere AVR-Typen haben ein Universal-Interface
für die serielle Kommunikation an Bord. Das Interface
liest serielle Signale am RXD-Eingang und sendet sie am
TXD-Ausgang, entweder im asynchronen oder im synchronen
Modus. Die Signale an RXD und TXD können extern in
das RS232-Format oder in andere serielle Übertragungsformate
umgewandelt werden.
Datenpakete (Frames) können bestehen aus
- einem Startbit,
- 5, 6, 7, 8 oder 9 Datenbits,
- keinem, geradem oder ungeradem Paritätsbit,
- einem oder zwei Stopbits.
AVR-Typen mit USART(s) an Bord haben zusätzlich einen
Baudratengenerator an Bord, der die serielle Taktrate für
den Empfänger und den Sender vorgibt. Der Generator teilt
den Prozessortakt maximal durch 16*4096 = 65.536. Er kann im
UBRR-Port eingestellt werden. Einige Typen haben einen
zusätzlichen Takteingang XCK dafür, der extern
mit einem Taktsignal bespeist werden kann.
Das UART kann als Interruptquelle für folgende Fälle
konfiguriert werden:
- USART_RXC wird ausgelöst, wenn ein Zeichen
empfangen wurde, Framefehler, Datenüberläufe und
Paritätsfehler können im Kontrollport erkannt
werden,
- USART_UDRE wird ausgelöst, wenn der Sendepuffer
leer ist und das nächste zu sendende Zeichen in den
Puffer geschrieben werden kann,
- USART_TXC wird ausgelöst, wenn der Sendepuffer leer
ist und das letzte zu sendende Zeichen vollständig
gesendet wurde.
2.7 Synchrone serielle Kommunikation
Bei der synchronen seriellen Kommunikation wird ein Taktsignal
eingesetzt, um die seriell am Dateneingang anliegenden Bits
in ein Schieberegister des Empfängers zu transferieren.
Umgekehrt werden beim Senden die Datenbits am Sendeausgang
nacheinander bereitgestellt und mit einem Taktsignal gesendet.
Die meisten AVR-Typen haben die Hardware für
synchrone serielle Kommunikation an Bord. Diese kann
entweder für den Zwei- oder den Dreileitungs-Modus
konfiguriert werden (Two-Wire, Three-Wire).
Im Three-Wire-Modus sind die Pins DO, DI und USCK aktiv.
USCK erzeugt das Taktsignal, wenn der AVR im Mastermode
ist und den Takt vorgibt, die Datenbits werden in DO
herausgeschoben und am DI hineingeschoben.
Im Two-Wire-Modus verwendet der AVR die Pins SDA/DI und
SCL/USCK, die beide bidirektional arbeiten und einen
offenen Kollektorausgang haben. Wenn das Interface als
Empfänger konfiguriert ist kommen Takt- und Datensignale
von der externen Quelle. Wenn als Sender konfiguriert,
werden beide Signale vom AVR angetrieben.
Interrupts können für das Erkennen der
Startbedingung (USI_STR) und für die Erkennung von
Überläufen (USI_OVF) beim Empfang eines kompletten
Datenbytes gesetzt werden.
2.8 Taktvorteiler
Taktsignalquellen für den Prozessor sind entweder
- ein interner RC-Oszillator (mit z.B. 8 MHz),
- ein interner zweiter RC-Oszillator mit niedriger Frequenz
(z.B. 128 kHz),
- ein extern angeschlossenes Taktsignal, oder
- ein extern angeschlossener Quarz oder Schwinger, der mit
einem internen Oszillator arbeitet.
Die Auswahl dieser Taktoptionen erfolgt mittels Setzen von
Fuses.
Die meisten AVR-Typen haben zusätzlich einen Taktvorteiler
an Bord. Dieser teilt die Frequenz der Taktquelle durch
Faktoren zwischen 1 und 256. Die werksseitige Voreinstellung
ist 8. Durch Löschen der CLKDIV8-Fuse läuft der
Prozessor ohne diesen Vorteiler, z.B. mit der Geschwindigkeit
des internen RC-Oszillators (meistens 8 MHz).
Um den Taktvorteiler zu aktivieren und unabhängig von den
Fuses per Software einzustellen, ist Folgendes erforderlich:
- das Enable-Bit im Port CLKPR wird gesetzt, und
- innerhalb von vier Taktzyklen wird der gewünschte
Teilerfaktor in den CLKPR-Port geschrieben.
Der Teiler wird danach sofort aktiv.
Wenn ein Projekt beginnt, stellt sich sofort die Frage, mit
welchem AVR-Typ man das Projekt am Besten ausführt.
Nachträglicher Typwechsel von einem kleineren auf einen
größeren Typ sind zwar nicht sehr aufwändig
(im Gegensatz zu dem was Nichtkenner von Hard- und Software
so alles in diversen Foren behaupten), aber so richtig optimal
wird Software erst, wenn sie die Features, die der Typ bietet,
optimal ausnutzt (freiwillige Feature-Kastration ist auch eine
häufig genutzte Methode, um Kompatibilität zu
erreichen - der kleinste gemeinsame Nenner als
selbstgewählte Performance-Bremse).
C-Programmierer brauchen den Rest dieses Kapitels gar nicht zu
lesen und zu verstehen. Sie brauchen so viel Programmspeicher,
dass es den ganzen Rest der Hardware ganz umsonst schon dazu gibt.
Sie können jetzt direkt in das Speicherkapitel
wechseln.
Für die, die in Assembler programmieren, bleibt die Welt
farbenfroh. Die Auswahl an Typen, Packungsarten und -größen,
interne Hardware, Pin-Zuordnung, etc., macht etwas Aufwand.
3.1 Auswahlkriterien
Die folgenden Kriterien spielen bei der Auswahl des optimalen
AVR-Typs eine Rolle:
- Packungsart und -größe: bei einigen Anwendungen
muss diese so klein wie möglich sein, z.B. bei kleinen
Flug- oder Schiffsmodellen oder in intelligenten
Kartencontrollern. Da kann man keine 96-poligen Ungeheuer
verwenden.
- Stromverbrauch: spielt beim Betrieb aus Kleinbatterien oder
Akkus eine zentrale Rolle. Je mehr unnötige Hardware ein
AVR mit sich herumschleppt, desto aufwändiger wird es,
das entweder abzuschalten (wenn es geht) oder alle
Möglichkeiten zur Verbrauchsreduzierung zu nutzen
(Taktverringerung, Interruptprogrammierung, Schlafmodus,
Abschalten von Pin-Treibern und AD-Wandlern, etc.).
- Nötige Hardwarefunktionen: wenn man einen 4- oder
8-Bit-Bus für eine LCD, einen oder mehrere
AD-Wandler-Eingänge, drei oder mehr externe
Interrupt-Quellen etc. benötigt, reduziert sich die
Anzahl geeigneter Typen entsprechend. Auch die
Mehrfach-Belegung externer Pins spielt dann eine Rolle, also
die Platzierung der nötigen Funktionen.
- Taktrate: wenn bestimmte Funktionen in einem engen Zeitfenster
auszuführen sind (z.B. ein IR-Sendesignal mit 40 kHz)
kann die nötige Taktrate ein Auswahlkriterium sein.
Allerdings um den Preis höheren Strombedarfs.
- Speicherbedarf: das ist das einfachste Kriterium. Wenn der
Platz nicht mehr reicht (war nach meinen bisherigen gefühlten
50 Softwareprojekten nur ein einziges Mal der Fall), dann kann
eine Optimierung des Codes wahre Wunder bewirken
(Software-Optimierung steigert oft auch die Qualität, die
Geschwindigkeit, die Nachvollziehbarkeit, usw.). Wozu es
manchmal besser ist, den alten Code in den Mülleimer zu
werfen, da er optimaleren Lösungen nur im Weg herumsteht.
Wenn Optimierung nichts hilft, kann man immer noch auf den
Typ mit der nächsthöheren Speicherausstattung
wechseln (z.B. von einem ATtiny24 zu einem 44 oder 84).
3.2 Auswahl nötiger Funktionen
Das folgende Werkzeug bietet Hilfe bei der Auswahl von AVR-Typen
nach Hardwarefunktionen. Es ist in Lazarus-Pascal geschrieben und
ist für Linux und Windows verfügbar. Die Software gibt es
in zwei Versionen.
3.2.1 Normalversion
Die folgenden Bilder sind mit der Windows-Version gemacht, die
Linux-Version sieht ein klein wenig anders aus (macht aber dasselbe).
Die linke Seite des Programmfensters dient der Auswahl der
nötigen Hardwarekomponenten.
Alle nötigen Komponenten sind anzuklicken. Bei den drei
Einstellfeldern für die Anzahl an PCINT, AD-Wandlerkanälen
und von I/O-Einzelpins kann die benötigte Anzahl vorgewählt
werden.
Jede Änderung bei der Komponentenauswahl listet alle Typengruppen
im Devices-Feld auf, die über die nötigen Funktionen
verfügen. Wenn das Anzeigekriterium "All devices"
aktiviert ist, zeigt das auch die nicht geeigneten Typen an, mit
einem Stern davor, und diejenigen Anforderungen, die nicht erfüllt
sind.
Wenn in dem Devices-Feld ein bestimmter Typ angeklickt wird, zeigt
das Fenster "Device" die Anschlussfolge dieses Typs (in
der PDIP/SOIC-Version) an. Wenn die Auswahl "Original pinout"
eingeschaltet ist, stellt diese das Original dar. Wenn nicht dann
signalisieren die Pinfunktionen in Kleinbuchstaben, welche Pins
den gewählten Hardwarefunktionen zugeordnet wurden (alternative
Pinfunktionen werden ausgeblendet).
In diesem Beispiel sind fünf PCINT, ein Quarz als Taktgeber
sowie ein separater Timer-Oszillator, die beiden OC-Signalausgänge
von Timer 1, drei AD-Wandler-Eingänge mit interner
Spannungsreferenz, der Analogvergleicher, ein 4-Bit-Bus und drei
einzelne I/O-Portbits zugeordnet. Die meisten AVR-Typen erfüllen
diese Anforderungen nicht gleichzeitig.
Das ist das Ergebnis für den ATmega644. Pins in Kleinbuchstaben
sind fest zugeordnet, in Großbuchstaben nicht. Die Pins 3 und 4
sind für den Analogvergleicher reserviert, der 4-Bit-Bus ist
den Pins 5 bis 8 (PB4 bis PB7), die fünf PCINTs an Pin 37 (PCINT3)
und Pin 36 (PCINT4), Pin 22 (PCINT16) und Pin 23 (PCINT17) sowie
Pin 20 (PCINT30) zugeordnet. ADC-Kanäle werden, wenn möglich,
in einer Reihe angeordnet, was die Adressierung vereinfacht. Hier sind
das ADC0 bis ADC2 an den Pins 40 bis 38.
Die folgenden Checkboxen formatieren die Anzeige um:
- Original: Die Original-Pinbelegung wird angezeigt,
- Frame: Die Pinbelegung wird als Draufsicht auf den Chip angezeigt,
- asm: Der Text wird so umformiert, dass er in eine
Assembler-Quellcode-Datei übernommen werden kann.
So sieht die Frame-Ansicht in asm-Formatierung aus.
Der Knopf "Save" speichert die angewendeten Kriterien und
das Pinout in einer Textdatei. Die sieht folgendermaßen aus:
Design criteria for Devices = ATmega164/324/644/1284:
External ints: INT0 INT1 5 PCINTs
Clock sources: Oscillator with external xtal or resonator
TC1: OC1A OC1B
UART0: RXD0 TXD0 External_clock
Analog channels: 3, Internal reference enabled, analog comparator enabled
I/O-Pins: 4-bit-bus 3 single bits
Pin layout:
; ___________________________
; 1/ |40
; o--|xck0 adc0|--o
; 2| |39
; o--|pb1 adc1|--o
; 3| |38
; o--|ain0 adc2|--o
; 4| |37
; o--|ain1 pcint3|--o
; 5| |36
; o--|pb4 pcint4|--o
; 6| |35
; o--|pb5 PA5 ADC5 PCINT5|--o
; 7| |34
; o--|pb6 PA6 ADC6 PCINT6|--o
; 8| |33
; o--|pb7 PA7 ADC7 PCINT7|--o
; 9| |32
; o--|reset aref|--o
; 10| |31
; o--|vcc gnd|--o
; 11| |30
; o--|gnd avcc|--o
; 12| |29
; o--|xtal2 pc7|--o
; 13| |28
; o--|xtal1 pc6|--o
; 14| |27
; o--|rxd0 PC5 TDI PCINT21|--o
; 15| |26
; o--|txd0 PC4 TDO PCINT20|--o
; 16| |25
; o--|int0 PC3 TMS PCINT19|--o
; 17| |24
; o--|int1 PC2 TCK PCINT18|--o
; 18| |23
; o--|oc1b pcint17|--o
; 19| |22
; o--|oc1a pcint16|--o
; 20| |21
; o--|pcint30 PD7 OC2A PCINT31|--o
; |___________________________|
Die Software gibt es hier:
Die Software ist kostenlos für nicht-kommerzielle Verwendung.
Fehlermeldungen, Anfragen zu weiteren Features, positive oder
negative Rückmeldungen bitte per Email an info bei avr-asm-tutorial.net.
Bei der fortgeschrittenen Version sind zwei zusätzliche Funktionen
verfügbar:
- die Auswahl nach Speichergröße,
- die Verlinkung mit zwei Anbietern von AVRs.
Die Auswahl nach Speichergröße erfolgt mit drei
Dropdown-Selektoren.
Die angebotenen Größen sind typische Werte bei allen AVR.
Ausgewählt werden damit die AVR-Typen, die mindestens den
gewählten Wert aufweisen.
Das zweite Feature prüft, ob Varianten des betreffenden Typs in
den beiden Shops
- Microchip Direct, und
- Reichelt Elektronik
verfügbar sind und bietet dann zwei entsprechende Schaltflächen
an.
Beim Anklicken der beiden Schaltflächen öffnet sich ein zusätzliches
Fenster, das in den Shops verfügbare Untertypen auflistet.
Klickt man einen der aufgelisteten Typen an, dann öffnet sich im
Internetbrowser ein Fenster, der direkt zur entsprechenden Produktseite
führt. Bei Microchip sind auf dieser Seite auch die entsprechenden
Datenbücher für den gewählten Typ verlinkt.
Die Software gibt es hier:
Wenn Du an die Speichergrenzen stößt, verwende einfach
einen größeren Typ. Bitte unbedingt beachten: das Befüllen
des Speichers mit unnützem, weil nie verwendetem Schrott, ist
kein guter Grund, um zu einem größeren Typ umzusteigen.
In diesem Fall ist es eine bessere Idee den Code zu optimieren.
Eine Liste der Speichergrößen ist hier verfügbar.
©2017 by http://www.avr-asm-tutorial.net
Verwendung, Kopieren und Weitergabe dieser Seiten ist zulässig solange
die Copyright-Angaben erhalten bleiben.