Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter fuer schwierige und grosse Gaerten im Test

(SPI mit dazu)
(Hardware)
 
(46 dazwischenliegende Versionen von 14 Benutzern werden nicht angezeigt)
Zeile 13: Zeile 13:
 
*AVR-Kern
 
*AVR-Kern
 
** Harvard-Architektur (getrennter Befehls- und Datenspeicher)  
 
** Harvard-Architektur (getrennter Befehls- und Datenspeicher)  
** 32 Register, kein Akkumulator, 3 Pointerregister
 
** EEPROM-Datenspeicher
 
** [[Watchdog]], [[Bootloader]]-Support, verschiedene Stromspar-Modi, Brownout-Erkennung, Interner Oszillator
 
** Lineares Speichermodell (keine Segmentierung)
 
 
** 8-Bit Architektur ist für Hochsprachen (C) optimiert  
 
** 8-Bit Architektur ist für Hochsprachen (C) optimiert  
 +
** 32 Register, davon 6 als 3 Pointerregister, kein Akkumulator
 +
** Lineares Speichermodell (keine Segmentierung bis 128 kBytes Programmspeicher)
 
* In-System programmierbar: die Controller können sehr einfach über ein  Programmierkabel (oft ISP-Kabel genannt), das mit dem PC verbunden wird, programmiert werden – auch dann, wenn sie sich nicht in einer Schaltung befindet.
 
* In-System programmierbar: die Controller können sehr einfach über ein  Programmierkabel (oft ISP-Kabel genannt), das mit dem PC verbunden wird, programmiert werden – auch dann, wenn sie sich nicht in einer Schaltung befindet.
 +
* integrierter Flash-Speicher für Programm
 
* umfangreiche Peripherie
 
* umfangreiche Peripherie
 +
** [[Watchdog]], [[Bootloader]]-Support, verschiedene [[Stromspar-Modi(AVR)|Stromspar-Modi]], Brownout-Erkennung, Interner Oszillator
 +
** EEPROM-Datenspeicher
 
** 8- und 16-Bit-Timer/Counter mit [[PWM]], Capture/Compare, externe Betaktung, asynchrone Operation
 
** 8- und 16-Bit-Timer/Counter mit [[PWM]], Capture/Compare, externe Betaktung, asynchrone Operation
 
** Kommunikation: [[UART|USART]], [[SPI]], [[I2C]] ([[TWI]])
 
** Kommunikation: [[UART|USART]], [[SPI]], [[I2C]] ([[TWI]])
 
** Analog-Comparator, Analog-Digital-Wandler  
 
** Analog-Comparator, Analog-Digital-Wandler  
 
** unterschiedlichste externe und interne Interrupt-Quellen (UART, SPI, Timer, A/D-Wandler, Analog-Comparator, ...)
 
** unterschiedlichste externe und interne Interrupt-Quellen (UART, SPI, Timer, A/D-Wandler, Analog-Comparator, ...)
** JTAG (Debugerinterface)
+
** JTAG (Debugerinterface) (Teilweise)
* AVR Typen (AT90 "Classic AVR", ATtiny, ATmega)  
+
* AVR Typen (AT90 "Classic AVR", ATtiny, ATmega), trotzdem sehr ähnlich, die neue XMega Serie ist vor allem bei der Peripherie etwas anders
 
* erhältlich in unterschiedlichen Gehäusen, idR Durchsteck und als [[SMD]]
 
* erhältlich in unterschiedlichen Gehäusen, idR Durchsteck und als [[SMD]]
 
* Viele Entwicklungsboards erhältlich, z.B. das Roboternetzboard [[RN-Control]]
 
* Viele Entwicklungsboards erhältlich, z.B. das Roboternetzboard [[RN-Control]]
Zeile 50: Zeile 51:
  
 
[[Bild:mega128pin.gif|center]]
 
[[Bild:mega128pin.gif|center]]
 
  
  
Zeile 65: Zeile 65:
 
|-
 
|-
 
  |'''[[VCC]]'''  
 
  |'''[[VCC]]'''  
  | Versorgungsspannung von 2,7 Volt bis 6 V bei den L-Varianten (low power), ansonsten 4,5V bis 6V. Die nächste AVR-Generation soll ab 1,8 Volt funktionieren.
+
  | Versorgungsspannung von 2,7 V bis 5,5 V bei den L-Varianten (low power), ansonsten 4,5V bis 5,5 V. Neuere AVR ab 2,7 V und ab 1,8 V in V-Variante.
 
|-
 
|-
 
  |'''[[GND]]'''  
 
  |'''[[GND]]'''  
Zeile 71: Zeile 71:
 
|-
 
|-
 
  |'''AREF'''  
 
  |'''AREF'''  
  |Referenzspannung für den Analog-Digital-Wandler (kann auf 5V gesetzt werden). Auch die interne Bandgap-Referenzspannung kann über diesen Pin entstört werden (dann KEINE externe Spannung an diesen Pin geben (Kurzschluss)!).  
+
  |Referenzspannung für den Analog-Digital-Wandler. Auch die interne Bandgap-Referenzspannung kann über diesen Pin entstört werden (dann KEINE externe Spannung an diesen Pin geben (Kurzschluss)!).  
 
|-
 
|-
 
  |'''AGND'''  
 
  |'''AGND'''  
  |Alternative Masse, etwa um ein Verbindungspunkt mit GND zu haben und bei empfindlichen Messungen  Masseschleifen zu vermeiden.
+
  |Analoge Masse für AD Wandler und dazugehörige Ports. Sollte in aller Regel mit GND verbunden werden.
 
|-
 
|-
 
  |'''AVCC'''  
 
  |'''AVCC'''  
 
  |  
 
  |  
Die Betriebsspannung für den Analog-Digital-Wandler (siehe Beschaltungsskizze). Die Pins AVCC, AGND und AREF sollten immer beschaltet werden, da es sonst passieren kann, dass Port A nicht richtig funktioniert, selbst wenn man den AD-Wandler nicht benutzt.  
+
Die Betriebsspannung für den Analog-Digital-Wandler (und einiges mehr) (siehe Beschaltungsskizze). Die Pins AVCC und AGND müssen immer beschaltet werden, selbst wenn man den AD-Wandler und Port A nicht benutzt.  
 
|-
 
|-
 
  |'''RESET'''  
 
  |'''RESET'''  
Zeile 133: Zeile 133:
 
|-
 
|-
 
  |'''T0'''  
 
  |'''T0'''  
  |Timer-Eingang. Timer kann gestartet, gestoppt oder getaktet werden
+
  |Timer 0: externer Takteingang.
 
|-
 
|-
 
  |'''T1'''  
 
  |'''T1'''  
  |Timer-Eingang. Timer kann gestartet, gestoppt oder getaktet werden
+
  |Timer 1: externer Takteingang.
 
|-
 
|-
 
  |'''OC0'''  
 
  |'''OC0'''  
Zeile 143: Zeile 143:
 
  |'''OC1A'''  
 
  |'''OC1A'''  
 
  |Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines  
 
  |Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines  
Der erste PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motogeschwindigkeit benutzt werden.  
+
Der erste PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.  
 
|-
 
|-
 
  |'''OC1B'''  
 
  |'''OC1B'''  
 
  |Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines  
 
  |Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines  
Der zweite PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motogeschwindigkeit benutzt werden.  
+
Der zweite PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.  
 
|-
 
|-
 
  |'''ICP1'''  
 
  |'''ICP1'''  
  |Eingang für die Capture-Funktion des integrierten Zeitgebers / Zählerbausteines  
+
  |Eingang für die [[Timer/Counter_(Avr)#Input_Capture|Capture-Funktion]] des integrierten Zeitgebers / Zählerbausteines  
 +
 
 
|-
 
|-
 
  |'''OC2'''  
 
  |'''OC2'''  
  |[[Pwm]] bzw. Output Compare Ausgang des Timers2. Er kann zum Regeln der Bot-Motogeschwindigkeit benutzt werden.  
+
  |[[Pwm]] bzw. Output Compare Ausgang des Timers2. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.  
 
|-
 
|-
 
  |'''TOSC1, TOSC2'''  
 
  |'''TOSC1, TOSC2'''  
  |TOSC1 und TOSC2 sind Eingänge für den asynchronen Modus von Timer2. Sie sind vorgesehen für den Anschluss eines externen Uhrenquarzes ( 32.768 kHz ). Damit lassen sich zum Beispiel sehr genaue Ein-Sekunden-Impulse für eine Uhr generien.  
+
  |TOSC1 und TOSC2 sind Eingänge für den asynchronen Modus von Timer2. Sie sind vorgesehen für den Anschluss eines externen Uhrenquarzes ( 32.768 kHz ). Damit lassen sich zum Beispiel genaue Ein-Sekunden-Impulse für eine Uhr generien, sogar wenn der normale Takt im Power-save Modus aus ist.
 
<!------------------------------------------------------------------------------------->
 
<!------------------------------------------------------------------------------------->
 
|- {{Hintergrund1}}
 
|- {{Hintergrund1}}
Zeile 181: Zeile 182:
 
|-
 
|-
 
  |'''XCK'''  
 
  |'''XCK'''  
  |Externe Takt für den USART. Wird nur in Sonderfällen für den Takt benötigt.
+
  |Taktsignal der USART im synchronen Mode (z.B. als SPI Master).  
USART ("Universal Synchronous/Asynchronous Receiver and Transmitter"). Das ist die serielle Schnittstelle, die zur Datenübertragung zwischen Mikrocontroller und PC genutzt wird. Zur bidirektionalen Übertragung werden zwei Pins am Controller benötigt: TXD und RXD. Über TXD ("Transmit Data") werden Daten gesendet, RXD ("Receive Data") dient zum Empfang.  
+
 
<!------------------------------------------------------------------------------------->
 
<!------------------------------------------------------------------------------------->
 
|- {{Hintergrund1}}
 
|- {{Hintergrund1}}
Zeile 188: Zeile 188:
 
|-
 
|-
 
  |'''SS'''  
 
  |'''SS'''  
  |SPI-Interface – wird beneötigt um den richtigen Slave am Bus zu wählen
+
  |SPI-Interface – wird benötigt, um den µC als aktiven Slave auszuwählen
 
|-
 
|-
 
  |'''MOSI'''  
 
  |'''MOSI'''  
Zeile 225: Zeile 225:
  
 
== Timer/Counter ==
 
== Timer/Counter ==
 
+
Für Infos zu Timer und Counter siehe Artikel [[Timer/Counter (Avr)]].
Die Mikrocontroller der AVR-Familie besitzen je nach Typ eine unterschiedliche Anzahl an programmierbaren [[Timer|Timern]]. Bei den aktuellen ATmegas sind das mindestens ein 8-Bit Timer und bei größeren Ausführungen der Serie auch 16-Bit Timer. Die Timer werden immer Timerx benannt, wobei x für die Timernummer steht (also 0, 1, 2, usw.).
+
Die Konfigurationsmöglichkeiten sind von Timer zu Timer unterschiedlich.
+
 
+
'''Hinweis:''' Die folgenden Code-Beispiele sind in C programmiert und wurden für einen [[ATMega32|ATmega32]] entwickelt. Sie lassen sich also ohne große Änderungen auch auf anderen Mikrocontrollern der AVR-Familie einsetzen.
+
 
+
=== Allgemeine Funktionsweise ===
+
Timer funktionieren nach dem allgemeinen Prinzip, dass sie eine Ganzzahl (im weiteren als Zähler bezeichnet) je nach Betriebsmodus auf- oder abwärtszählen, d.h. inkrementieren bzw. dekrementieren.
+
 
+
Angenommen, der Timer arbeitet im einfachsten Betriebsmodus, dem normalen Modus (siehe [[Avr#Normaler Modus (Normal Mode)|Normaler Modus (Normal Mode)]]). Die Zählrichtung des Timers ist aufsteigend gerichtet. Je nach Auflösung, also 8-Bit oder 16-Bit, erreicht der Zähler irgendwann einen bestimmten Zustand. Möglich wäre, dass er überläuft, wenn z.B. bei einem 8-Bit Timer der Wert 255 inkrementiert wird (siehe Grafik).
+
 
+
[[Bild:AbstrakterZaehlvorgang.png]]
+
 
+
=== Der Prescaler ===
+
Der Prescaler (eng. = Vorteiler) kann dazu genutzt werden, den Takt, der den Timern zugeführt wird, zu verkleinern. U.a. kann man damit die Timer so konfigurieren, damit diese in den unterschiedlichsten Frequenzen takten. Hier eine Grafik die den Prescaler veranschaulicht:
+
 
+
[[Bild:Prescaler.png]]
+
 
+
Das obere Diagramm zeigt den Betrieb ohne Prescaler, das untere mit Prescaler. Die gestrichelte Linie zeigt, wann ein Interrupt eintritt.
+
 
+
Im Teil [[Avr#Die Betriebsmodi|Die Betriebsmodi]] wird weiter auf die praktische Verwendung des Prescalers eingegangen.
+
 
+
=== Die Betriebsmodi ===
+
Die AVR-Timer können in unterschiedlichen Betriebsmodi betrieben werden. Diese sind:
+
* Normaler Modus
+
* CTC Modus
+
* PWM
+
 
+
==== Normaler Modus (Normal Mode) ====
+
Der einfachste Betriebsmodus ist der normale Modus. Er funktioniert wie im Abschnitt  "[[Avr#Allgemeine Funktionsweise|Allgemeine Funktionsweise]]" beschrieben. Die Zählrichtung des Timers ist immer aufsteigend, und irgendwann kommt es zu dem Interrupt Timer-Overflow (welcher in einer passend ISR aufgefangen werden kann). Im einfachsten Fall kann man diesen Modus in folgendem Diagramm darstellen:
+
 
+
[[Bild:NormalerModus_1.png]]
+
 
+
Der Zähler des Timers (im Diagramm oben, die aufsteigende und dann wieder zurückgesetzte Linie) ist in dem Register TCNTx gespeichert, wobei x für eine Zahl steht. Soll z.B. auf den Timer0 (siehe Datenblatt des jeweiligen Controllers) des Controllers zugegriffen werden, so ist an TCNT eine 0 anzuhängen, also TCNT0.
+
Wie lange es braucht, bis der Zähler einen Overflow auslöst, ist von der Taktfrequenz des Controllers, dem eingestellten Prescaler-Wert und von der Timerauflösung abhängig. Nun wäre es ja sehr unpraktisch, wenn wir den Zähler nicht anpassen könnten. Denn sonst müssten wir unsere Software die den Timer benutzt evtl. anpassen und viel rechnen um z.B. für 1000 ms zu schlafen. Deswegen kann auf den Zähler zugreifen und ihn vorladen bevor dieser wieder vom eigentlichen Timer hochgezählt wird. Dies veranschaulicht folgendes Diagramm:
+
 
+
[[Bild:NormalerModus_1_Vorladen.png]]
+
 
+
Dadurch kann man den Timer beeinflussen, und beeinflussen wie lange es dauert, bis ein Overflow auftritt. Um zu berechnen, welchen Wert wir vorladen müssen, kann man auch ein Java-Applet nutzen, siehe unter [[Avr#Weblinks|Weblinks Java Applet]].
+
 
+
Natürlich kann man das auch "von Hand" rechnen. Die Berechnung des Preloader- sowie Prescalerwerts bei Verwendung der Overflow-Interrupts, eines Prescalers von 64 (nicht alle Prescaler können verwendet werden) und eines Quarzes mit der Frequenz von 8 MHz sieht folgendermaßen aus (gesuchte Frequenz beträgt 1000 Hz unter der Verwendung des Timer0 eines ATmega32):
+
# <math>Prescale = Frequenz * 1000000 [Hz] = 8000000</math>
+
# Wir definieren den maximalen Zählerwert. Dieser ist bei einem 8-Bit Timer 256, bei einem 16-Bit Timer 65536. In unserem Fall ist der maximale Zählerwert 256, weil Timer0 verwendet wird.
+
# Nun wird die Variable ''Prescale'' (s.o.) durch den verwendeten Prescaler (64) geteilt (<math>8000000 Hz / 64 = 125000</math>).
+
# Als nächstes wird der im dritten Punkt errechnete Wert durch die gesuchte Frequenz geteilt <math>=125000 / 1000Hz = 125</math>.
+
# Nun wird mathematisch überprüft, ob der errechnete Wert aus dem vierten Punkt kleiner als der maximale Zählerwert ist. Trifft dies zu, so subtrahiert man den errechneten Wert vom maximalen Zählerwert (<math>= 256 - 125 = 131</math>).
+
 
+
Damit haben wir den Wert errechnet, der bei jedem Interrupt, den der Timer0 auslöst, in TCNTx (in diesem Fall TCNT0) nachgeladen werden muss, damit die Interrupts in dem gewünschten Zeitabstand von einer Millisekunde ausgelöst werden.
+
 
+
Allerdings bleibt zu bemerken, dass bei der Verwendung einer "ungeraden" Quarzfrequenz (z.B. 7,3728 MHz) der Timer mit einer bestimmten Ungenauigkeit arbeitet. Würden wir z.B. den Quarz oben mit einem Quarz mit 7,3728 MHz austauschen, so wäre die Fehlerrate 0,17%. Diese Ungeauigkeit varriert von verwendetem Prescaler zu Prescaler. D.h. wenn wir einen Prescaler von 1024 (und einer Quarzfrequenz von 8 MHz) verwendet hätten, so hätten wir eine inakzeptable Ungeauigkeit von 11,61%. Deswegen sollte sie eines der genannten Programme unter [[Avr#Weblinks]] verwenden, denn diese zeigen nur die bestmögliche Konfiguration an.
+
 
+
Die Fehlerrate kann natürlich auch ausgerechnet werden. Hier die Rechenschritte (sie sind erweiternd zu der oberen Berechnung):
+
# Als erstes wird mathematisch überprüft, ob der Preloaderwert (siehe fünften Schritt oben) größer als 1 ist.
+
# Trifft dies zu, so wird als nächstes die resultierende Frequenz errechnet. Die geschieht folgendermaßen: Der errechnete Preloaderwert aus der Rechnung oben wird vom maximalen Zählerwert subtrahiert, anschließend mit dem Prescaler multipliziert und dann das Ganze durch die Variable Prescale geteilt
+
<math>(256 - 131) \cdot 64 / 8\,000\,000 \mathrm{Hz} \cdot 1\,000\,000 = 1000</math>.
+
# Nun wird die gesuchte Frequenz vom errechneten Wert aus dem dritten Punkt subtrahiert und dann wiederum durch diese geteilt <math>(1000-1000) / 1000 = 0</math>. Damit läuft dieser Timer genau mit einer Fehlerrate von 0 %.
+
 
+
Betreibt man den Timer im Overflow-Modus, so muss man, wie bereits erwähnt, nach/bei jedem Overflow-Interrupt den Timer nachladen. Der Interrupt heißt in diesem Fall SIG_OVERFLOWx (x steht für die Nummer des Timers). Dieser muss in einer ISR abgefangen werden.
+
 
+
Zusammenfassend ein Beispielprogramm:
+
 
+
<pre>
+
/* Es wird der Timer2 (8-Bit) eines ATmega32 verwendet, der mit einem Quarz mit 7,3728 MHz
+
betrieben wird. Im Abstand von 0,001 ms erzeugt der Timer einen Interrupt, also eine
+
Frequenz von 1000000 Hz (oder 100 kHz). Der Timer wird auf einen Prescaler von 1 und
+
einem Preloader von  183 konfiguriert.*/
+
 
+
volatile uint8_t countTimer2; // Speichert den aktuellen Zählerwert
+
 
+
// ISR zum auffangen der Interrupts:
+
SIGNAL(SIG_SIG_OVERFLOW2)
+
{
+
countTimer2++;
+
TCNT2 = 183; // Nachladen
+
}
+
 
+
// Initialisierung:
+
TCCR2 = (1<<CS22); // Prescaler von 1
+
TCNT2  = 183; // Vorladen
+
TIMSK |= (1<<TOIE2); // Interrupts aktivieren und damit Timer starten
+
sei();
+
 
+
// Funktionen zum benutzen der Timer:
+
/** Diese Funktion nicht aufrufen. Wird von sleep_millisec aufgerufen.
+
Bei t=100 schläft die Funktion 1 ms. */
+
inline void sleep (uint8_t t)
+
{
+
// countTimer2 wird in der ISR oben inkrementiert
+
countTimer2 = 0;
+
while (countTimer2 < t);
+
}
+
 
+
/** Schläft x-Millisekunden. */
+
inline void sleep_millisec(uint16_t msec)
+
{
+
uint16_t i;
+
for(i=0; i<msec; i++) {
+
sleep(100);
+
}
+
}
+
</pre>
+
Allerdings wird auf diese leicht veraltete Technik nun nicht weiter eingegangen. Der Artikel wendet sich nun dem neueren "Compare Output"-Betriebsmodus zu.
+
 
+
Beim "Compare Output"-Betriebsmodus wird genauso ein Zähler hochgezählt. Allerdings wird der Zählerwert nach jeder Inkrementierung mit einem vom Benutzer festgelegten Wert verglichen. Entspricht der Zählerwert dem gespeicherten Wert, so kommt es zu einem Interrupt. Dieser Wert wird in das Register OCRx (x steht wieder für die Timernummer) gespeichert. Je nach Auflösung des Timers ist dieses Register 8-Bit oder 16-Bit breit.
+
 
+
Hinweis: Siehe CTC Modus unten. Dieser wird benötigt um den Timer entsprechend im "Compare Output"-Betriebsmodus vernünftig zu betreiben.
+
 
+
Hier ein typisches Diagramm dieses Betriebsmodus (Hinweis: Das Diagramm wurde unter Verwendung des CTC Modus erstellt. Für Begriffserklärung siehe CTC Modus):
+
 
+
[[Bild:NormalerModus_CompareMatch.png]]
+
 
+
Das Ausrechnen des Werts, der in OCRx geschrieben werden muss, damit Frequenz x entsteht, ist nicht sonderlich schwer. Man geht wie bei der Berechnung des Werts für den Overflow-Modus vor (s.o.) nur daß man das resultierende Ergebnis vom maximalen Zählerwert (bei 8-Bit Auflösung ist dieser 256, bei 16-Bit Auflösung 65536) subtrahiert. Das Ergebnis wird dann einmalig in das Register OCRx geschrieben. Mann muss also nicht wie beim Overflow-Modus den Timer nach jedem Interrupt nachladen. Der enstehende Interrupt heißt in diesem Fall SIG_OUTPUT_COMPAREx (x steht für die Nummer des Timers). Dieser muss in einer ISR abgefangen werden.
+
 
+
Wiederum zusammenfassend ein Beispielprogramm:
+
 
+
<pre>
+
/* Es wird der Timer2 (8-Bit) eines ATmega32 verwendet, der mit einem Quarz mit 7,3728 MHz
+
betrieben wird. Im Abstand von 0,001 ms erzeugt der Timer einen Interrupt, also eine Frequenz
+
von 1000000 Hz (oder 100 kHz). Der Timer wird auf einen Prescaler von 1 und einem OCR2-Wert
+
von 73 konfiguriert.*/
+
 
+
volatile uint8_t countTimer2; // Speichert den aktuellen Zählerwert
+
 
+
// ISR zum auffangen der Interrupts:
+
SIGNAL(SIG_OUTPUT_COMPARE2)
+
{
+
  countTimer2++;
+
}
+
 
+
// Initialisierung:
+
TCCR2 = (1<<CS22) | (1<<WGM21); // Prescaler von 1 | CTC-Modus (siehe unten für Beschreibung)
+
OCR2  = 73; // Vergleichswert
+
TIMSK |= (1<<OCIE2); // Interrupts aktivieren und damit Timer starten
+
sei();
+
 
+
// Funktionen zum benutzen der Timer:
+
/** Diese Funktion nicht aufrufen. Wird von sleep_millisec aufgerufen.
+
Bei t=100 schläft die Funktion 1 ms. */
+
inline void sleep(uint8_t t)
+
{
+
// countTimer2 wird in der ISR oben inkrementiert
+
countTimer2 = 0;
+
while (countTimer2 < t);
+
}
+
 
+
/** Schläft x-Millisekunden. */
+
inline void sleep_millisec(uint16_t msec)
+
{
+
uint16_t i;
+
for(i=0; i<msec; i++) {
+
sleep(100);
+
}
+
}
+
</pre>
+
 
+
==== CTC Modus (Clear Timer on Compare Match mode) ====
+
Der CTC Modus ist eine Erweiterung des "Compare Output"-Betriebsmodus. Der CTC Modus wird z.B. für das obere Beispielprogramm benötigt. Wird der Timer nämlich im normalen Betriebsmodus betrieben, so ist seine Zählergrenze je nach Auflösung 255 oder entsprechend für die 16-Bit Timer. Erst wenn diese Grenze erreicht wurde, wird der Timer zurückgesetzt (also auf 0). Durch den CTC Modus wird der Timer augenblicklich automatisch nachdem ein "Compare Output"-Interrupt auftrat zurückgesetzt. Man kann also die maximalen Zählergrenze selber definieren.
+
Dieses Diagramm veranschaulicht den CTC Modus. Nach dem Interrupt wird der Timer sofort wieder zurückgesetzt.
+
 
+
[[Bild:NormalerModus_CompareMatch.png]]
+
 
+
==== PWM ====
+
Für PWM siehe [[Pwm]].
+
 
+
=== Registerübersicht ===
+
''Hinweis: Diese Registertabellen wurden für den aktuellen [[Atmel Controller Mega16 und Mega32]] erstellt. Wenn Sie ein anderes Modell verwenden kann es sein, dass ein oder mehrere Register nicht existieren, oder sie eine andere Bezeichnung haben.''
+
 
+
{| {{Blaueschmaltabelle}} width=100%
+
|'''TIMSK'''
+
|-
+
|Mit diesem Register, der von allen Timern verwendet wird, lässt sich die Interruptausführung und Art des jeweiligen Timers bestimmen.<br/><br/>
+
 
+
{{Registertabelle8Bit|OCIE2|TOIE2|TICIE1|OCIE1A|OCIE1B|TOIE1|OCIE0|TOIE0}}
+
 
+
|-
+
|
+
*'''OCIE2 (Timer/Counter2 Output Compare Match Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter2 Compare Match Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''TOIE2 (Timer/Counter2 Overflow Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter2 Overflow Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''TICIE1 (Timer/Counter1, Input Capture Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter1 Input Capture Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''OCIE1A (Timer/Counter1 Output Compare A Match Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter1 Output Compare A Match Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''OCIE1B (Timer/Counter1 Output Compare B Match Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter1 Output Compare B Match Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''TOIE1 (Timer/Counter1 Overflow Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, wird der Timer/Counter1 Overflow Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''OCIE0 (Timer/Counter0 Output Compare Match Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, so wird der Timer/Counter0 Compare Match Interrupt aktiviert (vorrausgesetzt die Interrupts sind global aktiviert).
+
*'''TOIE0 (Timer/Counter0 Overflow Interrupt Enable)'''<br/>Wenn dieses Bit gesetzt wird, so wird der Timer/Counter0 Overflow Interrupt aktiviert  (vorrausgesetzt die Interrupts sind global aktiviert).
+
|}
+
  
 
== Analog-Digital-Wandler ==
 
== Analog-Digital-Wandler ==
''Für allgemeine Informationen zu dem Analog-Digital-Wandler siehe Artikel [[ADC]].''<br><br>
+
Für Infos zu Analog-Digital-Wandler siehe Artikel [[ADC (Avr)]].
Mit einem Analog-Digital-Wandler ([[ADC]], für Analog Digital Converter) ist es mit den AVRs möglich, auf einfache Art und Weise analoge Größe in digitale Werte umzuwandeln. Dies bietet sich z.B. an, wenn man die Batteriespannung eines Roboters bestimmen möchte.
+
 
+
=== Kanäle ===
+
Ein AVR hat normalerweise nur einen [[ADC]] integriert. Öfters muss man aber mehrere analoge Größen von verschiedenen Quellen wandeln, deswegen besitzen die AVRs Kanäle (ein ATmega32 z.B. besitzt acht Kanäle auf Port A). Diese Kanäle werden dann mithilfe eines Multiplexer auf den [[ADC]] geschalten werden, der dann die anliegenden analoge Spannung in einen digitalten Wert wandelt.
+
 
+
=== Betriebsmodi ===
+
Der [[ADC]] bietet verschiedene Betriebsmodi. Diese wären:
+
* Single Conversation: Der [[ADC]] wandelt eine analoge Größe um und gibt diese zurück.
+
* Free Running: Der [[ADC]] wandelt wie in einer Endlosschleife ständig die anliegenden analogen Größen in digitale Werte um und gibt diese zurück.
+
 
+
=== Teilungsfaktor ===
+
Zum Wandeln benötigt der [[ADC]] einen eigenen Takt, der auf der Taktfrequenz des Mikrocontrollers basiert. Allerdings ist die Taktfrequenz des Mikrocontrollers zu schnell und deswegen wird diese durch den Vorteiler verkleinert. Der resultierende Takt muss zwischen 50kHz und 200kHz liegen. Folgende Teilungsfaktoren sind verfügbar:<br>
+
{| {{Blauetabelle}}
+
|'''Teilungsfaktoren'''
+
|2
+
|4
+
|8
+
|16
+
|32
+
|64
+
|128
+
|}
+
<br>
+
Um zu bestimmen welcher Teilungsfaktor geeignet ist, kann man folgende Formel verwenden.<br>
+
<math>Tacktfrequenz = 8 MHz</math><br>
+
<math>Teilungsfaktor_{min} = {Tacktfrequenz \over {200 kHz}} = {{8000000 Hz} \over {200000 Hz}} = 40</math><br>
+
<math>Teilungsfaktor_{max} = {Tacktfrequenz \over {50 kHz}} = {{8000000 Hz} \over {50000 Hz}} = 160</math><br>
+
Deswegen kann man nun zwischen einem der folgenden Teilungsfaktor wählen: 64 und 128. Im Interesse der Geschwindigkeit sollte 64 gewählt werden.<br>
+
Siehe bitte die Registerübersicht weiter unten. Dort wird gezeigt, welches Register entsprechend eingestellt werden muss, damit man einen der oben aufgelisteten Teilungsfaktoren auswählen kann.
+
 
+
=== Referenzspannung ===
+
Das Ergebnis der Wandlung des [[ADC]] bezieht sich auf eine bestimmt Referenzspannung. Diese Referenzspannung lässt sich bestimmen. Je nach gewählter Referenzspannung darf man nur eine zu messende Spannung an den Port anlegen, die nicht höher liegt als die Referenzspannung. Sonst würde dieser zerstört werden. Die Referenzspannung ist also gleich der maximal zu messenden Spannung. Um einzustellen welche Referenzspannung verwendet werden soll, gibt es den Register ADMUX. Folgende Quellen sind als Referenzspannung möglich:<br>
+
{| {{Blauetabelle}}
+
|'''Referenzspannungsquelle'''
+
|AREF, internes Vref deaktiviert
+
|AVCC mit externen Kondensator am AREF Pin
+
|Keine Funktion, reserviert
+
|Interne 2,56V Spannungsreferenz mit externen Kondensator am AREF Pin
+
|}
+
Siehe bitte die Registerübersicht. Dort steht genauer wie man den Register einzustellen hat.
+
<br>
+
Man benötigt die Referenzspannung auch (oder besserer deren analoge Größe) um den Wert den der ADC zurückgibt in V umzurechnen. Um den zurückgegebenen Wert des ADC umzuwandel geht man so vor:<br>
+
# Bestimmen der Auflösung des ADC. Bei den ATMegas normalerweiße 10 Bit. 10 Bit entsprechen einer Stufung von 1024.
+
# Ermitteln des digitalen Werts der analogen Größe. In der Beispielrechnung verwende ich den Wert 592.
+
# Größe der Referenzspannung. In der Beispielrechnung wird 5V verwendet.
+
Mit diesen Werten kann folgende Berechnung ausführen.<br>
+
<math>V = 592 * 5V</math><br>
+
<math>V = 2960 / 2 ^{Bit} = 2960 / 2 ^{10} = \underline {\underline { 2{,}9V }}</math>
+
 
+
=== Programmbeispiele ===
+
'''C/C++'''<br>
+
Dieses Beispiel ist für die [[Atmel Controller Mega16 und Mega32]] gedacht, die mit einer Taktfrequenz von 8 MHz laufen. Es ist unbedingt darauf zu achten nicht die Referenzspannung von 2,56V zu überschreiten! Sonst stirbt der Port. Je nach Einsatzart muss man das Beispielprogramm entsprechend abändern (also diese Zeile mit ADMUX |= (1<<REFS1) | (1<<REFS0);).
+
<pre>
+
#include <avr/io.h>
+
#include <inttypes.h>
+
 
+
uint16_t readADC(uint8_t channel) {
+
uint8_t i;
+
uint16_t result = 0;
+
+
// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
+
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
+
 
+
// Kanal des Multiplexers waehlen
+
ADMUX = channel;
+
// Interne Referenzspannung verwenden (also 2,56 V)
+
ADMUX |= (1<<REFS1) | (1<<REFS0);
+
+
// Den ADC initialisieren und einen sog. Dummyreadout machen
+
ADCSRA |= (1<<ADSC);
+
while(ADCSRA & (1<<ADSC));
+
+
// Jetzt 3x die analoge Spannung and Kanal channel auslesen
+
// und dann Durchschnittswert ausrechnen.
+
for(i=0; i<3; i++) {
+
// Eine Wandlung
+
ADCSRA |= (1<<ADSC);
+
// Auf Ergebnis warten...
+
while(ADCSRA & (1<<ADSC));
+
+
result += ADCW;
+
}
+
+
// ADC wieder deaktivieren
+
ADCSRA &= ~(1<<ADEN);
+
+
result /= 3;
+
+
return result;
+
}
+
 
+
int main(void) {
+
uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
+
// also ADC0. In result steht das Ergebnis.
+
return 0;
+
}
+
</pre>
+
 
+
'''Bascom'''<br>
+
Dieses Programmbeispiel ist für den Atmel Controller Mega32 gedacht. Es gibt nacheinander die Spannungen der einzelnen Kanäle (ADC0..7) aus. Dazwischen macht es immer 800 ms pause.
+
<pre>
+
' Die gemessene Spannung wird in der Variablen W gespeichert.
+
' Channel ist der Pin, an dem die Spannung gemessen werden soll.
+
 
+
$baud = 9600
+
$crystal = 1000000
+
$regfile "m32def.dat"
+
Config Adc = Single , Prescaler = Auto
+
Start Adc
+
Dim W As Word , Channel As Byte
+
Channel = 0
+
Do
+
  W = Getadc(channel)
+
  Print "ADC-Pin " ; Channel ; ": Wert " ; W
+
  Incr Channel
+
  If Channel > 7 Then Channel = 0
+
  Waitms 800
+
Loop
+
End
+
</pre>
+
 
+
=== Registerübersicht ===
+
''Hinweis: Diese Registertabellen wurden für den aktuellen [[Atmel Controller Mega16 und Mega32]] erstellt. Wenn Sie ein anderes Modell verwenden kann es sein, dass ein oder mehrere Register nicht existieren, oder sie eine andere Bezeichnung haben.''
+
 
+
{| {{Blaueschmaltabelle}} width=100%
+
|'''ADCSRA (ADC Control and Status Register A)'''
+
|-
+
|Dieser Register dient dazu den ADC zu kontrollieren.<br/><br/>
+
 
+
{{Registertabelle8Bit|ADEN|ADSC|ADATE|ADIF|ADIE|ADPS2|ADPS1|ADPS0}}
+
 
+
|-
+
|
+
*'''ADEN (ADC Enable)'''<br/>Wird dieses Bit gesetzt (also 1), dann wird der ADC aktiviert. Schreibt man eine 0 wird der ADC deaktiert. Wird der ADC während einer Wandlung deaktiviert, wird die Wandlung abgebrochen.
+
*'''ADSC (ADC Start Conversion)'''<br/>Dieses Bit startet den Messvorgang, je nachdem in welchem Betriebsmodi der ADC läuft. Wird dieses Bit nach der Aktivierung des ADC über '''ADEN''' zum ersten Mal gesetzt, wird der ADC erst eine Initialisierungswandlung durchführen und danach erst die eigentliche Wandlung. Das Schreiben einer 0 auf das Bit hat keinen Effekt.
+
*'''ADATE (ADC Auto Trigger Enable)'''<br/>Wird dieses Bit gesetzt, wird das Auto Triggering des ADC aktiviert.
+
*'''ADIF (ADC Interrupt Flag)'''<br/>Dieses Bit wird auf 1 gesetzt, wenn eine Wandlung erfolgte und das Ergebnis nun verfügbar ist. Der ADC Complete Interrupt wird ausgelöst, wenn das '''ADIE'''-Bit gesetzt ist und die Interrupts global aktiviert sind. Das Bit wird gelöscht, wenn die entsprechende [[ISR]] abgearbeitet wird. Alternativ kann man es löschen, indem man eine 1 auf das Bit schreibt.
+
*'''ADIE (ADC Interrupt Enable)'''<br/>Wird dieses Bit gesetzt und die globalen Interrupts sind aktiviert, wird der ADC Complete Interrupt aktiviert, auf den man dann in der entsprechenden [[ISR]] reagieren kann.
+
*'''ADPS2 (ADC Prescaler Select Bit 2)'''<br/>Diese Bits bestimmen den Teilungsfaktor zwischen der XTAL-Frequenz (also der Taktfrequenz) und dem Eingangstakt des [[ADC]]. Zum Wandeln benötigt der [[ADC]] einen eigenen Takt, der auf der Taktfrequenz des Mikrocontrollers basiert. Allerdings ist die Taktfrequenz zu schnell und deswegen wird diese durch den Vorteiler verkleinert. Der resultierende Takt muss zwischen 50kHz und 200kHz liegen. Siehe [[Avr#Teilungsfaktor]]. Folgende Teilungsfaktoren sind verfügbar:<br>
+
{| {{Blauetabelle}}
+
|'''ADPS2'''
+
|'''ADPS1'''
+
|'''ADPS0'''
+
|'''Teilungsfaktor'''
+
|-
+
|0
+
|0
+
|0
+
|2
+
|-
+
|0
+
|0
+
|1
+
|2
+
|-
+
|0
+
|1
+
|0
+
|4
+
|-
+
|0
+
|1
+
|1
+
|8
+
|-
+
|1
+
|0
+
|0
+
|16
+
|-
+
|1
+
|0
+
|1
+
|32
+
|-
+
|1
+
|1
+
|0
+
|64
+
|-
+
|1
+
|1
+
|1
+
|128
+
|}
+
*'''ADPS1 (ADC Prescaler Select Bit 1)'''<br/>Siehe '''ADPS2''' für eine Beschreibung.
+
*'''ADPS0 (ADC Prescaler Select Bit 0)'''<br/>Siehe '''ADPS2''' für eine Beschreibung.
+
|}
+
 
+
{| {{Blaueschmaltabelle}} width=100%
+
|'''ADMUX (ADC Multiplexer Selection Register)'''
+
|-
+
|Mit diesem Register wird u.a. der Multiplexer gesteuert.<br/><br/>
+
 
+
{{Registertabelle8Bit|REFS1|REFS0|ADLAR|MUX4|MUX3|MUX2|MUX1|MUX0}}
+
|-
+
|
+
*'''REFS1 (Reference Selection Bit 1)'''<br/>Mit diesem Bit kann steuern, welche Referenzspannung der ADC verwenden soll. Die möglichen Quellen sind unten aufgelistet. Wird während einer Wandlung die Quelle für die Referenzspannung geändert, wird die aktuelle Wandlung mit der "alten" Quellen zuerste beendet, bevor die neue Einstellung übernommen wird.<br>
+
{| {{Blauetabelle}}
+
|'''REFS1'''
+
|'''REFS0'''
+
|'''Referenzspannungsquelle'''
+
|-
+
|0
+
|0
+
|AREF, internes Vref deaktiviert
+
|-
+
|0
+
|1
+
|AVCC mit externen Kondensator am AREF Pin
+
|-
+
|1
+
|0
+
|Keine Funktion, reserviert
+
|-
+
|1
+
|1
+
|Interne 2,56V Spannungsreferenz mit externen Kondensator am AREF Pin
+
|}
+
*'''REFS0 (ADC Start Conversion)'''<br/>Siehe '''REFS1'''.
+
*'''ADLAR (ADC Left Adjust Result)'''<br/>Dieses Bit beeinflusst, wie der ermittelte Messwert im ADC Data Register abgelegt wird.
+
*'''MUX4 (Analog Channel and Gain Selection Bit 4)'''<br/>Dieses Bit wird auf 1 gesetzt, wenn eine Wandlung erfolgte und das Ergebnis nun verfügbar ist. Der ADC Complete Interrupt wird ausgelöst, wenn das '''ADIE'''-Bit gesetzt ist und die Interrupts global aktiviert sind. Das Bit wird gelöscht, wenn die entsprechende ISR abgearbeitet wird. Alternativ kann man es löschen, indem man eine 1 auf das Bit schreibt.
+
*'''MUX3 (Analog Channel and Gain Selection Bit 3)'''<br/>Mit diesen Bits ('''MUX3''' bis '''MUX0''') wird der Kanal des Multiplexers eingestellt, der mit dem ADC verbunden ist.<br>
+
{| {{Blauetabelle}}
+
|'''MUX4..0'''
+
|'''Pin'''
+
|-
+
|00000
+
|ADC0
+
|-
+
|00001
+
|ADC1
+
|-
+
|00010
+
|ADC2
+
|-
+
|00011
+
|ADC3
+
|-
+
|00100
+
|ADC4
+
|-
+
|00101
+
|ADC5
+
|-
+
|00110
+
|ADC6
+
|-
+
|00111
+
|ADC7
+
|}
+
Es reicht also einfach die Pinnummer in ADMUX zu schreiben.
+
*'''MUX2 (Analog Channel and Gain Selection Bit 2)'''<br/>Siehe '''MUX3''' für eine Beschreibung.
+
*'''MUX1 (Analog Channel and Gain Selection Bit 1)'''<br/>Siehe '''MUX3''' für eine Beschreibung.
+
*'''MUX0 (Analog Channel and Gain Selection Bit 0)'''<br/>Siehe '''MUX3''' für eine Beschreibung.
+
|}
+
 
+
Des Weiteren gibt es noch den Register '''ADCL/ADCH''' in dem das Ergebnis einer Wandlung steht. Man liest den Wert folgendermaßen aus:<br>
+
<pre>
+
uint16_t x = ADCL;
+
x += (ADCH<<8);
+
// oder
+
x = ADCW;
+
</pre>
+
  
 
== Analog-Komparator ==
 
== Analog-Komparator ==
Für eine allgemeine Beschreibung des Komparators siehe Artikel [[Analog-Komparator]].<br><br>
+
Für Infos zu Analog-Komparator siehe Artikel [[Analog Komparator (Avr)]].
 
+
Die meisten AVRs haben einen Komparator integriert. Dieser Komparator besitzt zwei Eingänge – einen normalen und einen invertierten. Wie in [[Analog Komparator]] beschrieben vergleicht der Komparator zwei Spannungen und gibt dann aus welche größer ist. Der Komparator der AVRs lässt sich weiter konfigurieren, siehe dazu die Registerübersicht.
+
 
+
=== Funktionsweise ===
+
Der Analoge-Komparator vergleicht die Eingangsspannungen der Pins AIN0 (+, Eingang für nicht invertierte Spannung) und AIN1 (-, Eingang für invertierte Spannung). Ist die Spannung an AIN0 höher ist als an AIN1 wird ACO gesetzt. Dieses Verhalten lässt sich natürlich verändern, so dass ACO z.B. auch gesetzt wird, wenn AIN1 höher als AIN0 ist. Siehe dazu die Registerübersicht
+
 
+
=== Kanäle ===
+
Muss man mehrere Größen „gleichzeitig“ (ich schreibe das in Anführungszeichen, weil ein Controller Aufgaben nicht parallel verarbeiten kann wohl aber sehr schnell hintereinander) vergleichen, gibt es (wie beim [[Analog-Digital-Wandler]], kurz [[ADC]]) einen Multiplexer mit dessen Hilfe man die Kanäle des Multiplexers auf den Komparator schalten kann. Man kann (natürlich abhängig vom Modell, ich orientiere mich an einem ATmega32) die Pins ADC0..7 über dem Multiplexer mit dem Komparator verbinden und zwar mit dem invertierten Eingang des Komparators. Verwendet man den Multiplexer, muss der [[ADC]] allerdings deaktiviert sein.
+
Folgende Pins sind als Eingänge wählbar.<br>
+
{| {{Blauetabelle}}
+
|'''ACME'''
+
|'''ADEN'''
+
|'''MUX2..0'''
+
|'''Pin des invertierten Eingangs'''
+
|-
+
|0
+
|x
+
|xxx
+
|AIN1
+
|-
+
|1
+
|1
+
|xxx
+
|AIN1
+
|-
+
|1
+
|0
+
|000
+
|ADC0
+
|-
+
|1
+
|0
+
|001
+
|ADC1
+
|-
+
|1
+
|0
+
|010
+
|ADC2
+
|-
+
|1
+
|0
+
|011
+
|ADC3
+
|-
+
|1
+
|0
+
|100
+
|ADC4
+
|-
+
|1
+
|0
+
|101
+
|ADC5
+
|-
+
|1
+
|0
+
|110
+
|ADC6
+
|-
+
|1
+
|0
+
|111
+
|ADC7
+
|}
+
 
+
 
+
=== Registerübersicht ===
+
''Hinweis: Diese Registertabellen wurden für den aktuellen [[Atmel Controller Mega16 und Mega32]] erstellt. Wenn Sie ein anderes Modell verwenden kann es sein, dass ein oder mehrere Register nicht existieren, oder sie eine andere Bezeichnung haben.''
+
 
+
{| {{Blaueschmaltabelle}} width=100%
+
|'''ACSR (Analog Comparator Control And Status Register)'''
+
|-
+
|Mit diesem Register wird der Komparator des AVR gesteuert.<br/><br/>
+
 
+
{{Registertabelle8Bit|ACD|ACBG|ACO|ACI|ACIE|ACIC|ACIS1|ACIS0}}
+
 
+
|-
+
|
+
*'''ACD (Analog Comparator Disable)'''<br/>Wird dieses Bit gesetzt, wird der Komparator deaktiviert um Strom zu sparen (der Komparator ist standardgemäß deaktiviert). Will man den Komparator mit '''ACD''' deaktivieren, muss man davor den '''ACIE''' (Analog Comparator Interrupt) deaktiveren.
+
*'''ACBG (Analog Comparator Bandgap Select)'''<br/>Wird dieses Bit gesetzt, erstetzt eine feste Bandlückenreferenzspannung den positiven Eingang zum Analog-Komparator. Wird dieses Bit auf 0 gesetzt, so wird der Pin AIN0 mit dem positiven Eingang des Komparators verbunden.
+
*'''ACO (Analog Comparator Output)'''<br/>Auf diesem Bit wird das Ergebnis des Komparators ausgegeben (mit einer leichten Verzögerung von eins bis zwei Taktzyklen).
+
*'''ACI (Analog Comparator Interrupt Flag)'''<br/>Dieses Bit wird automatisch gesetzt, wenn der Komparator einen Interrupt auslöst (definiert über die Bits '''ACIS1''' und '''ACIS0''') und die entsprechende [[ISR]] ausführt. Das Bit wird wieder gelöscht, wenn die entsprechende [[ISR]] abgearbeitet wurde. Alternativ kann man das Bit auch löschen, indem man eine 1 auf das Bit schreibt.
+
*'''ACIE (Analog Comparator Interrupt Enable)'''<br/>Wird dieses Bit gesetzt, wird der Analog-Komparator Interrupt aktiviert (vorausgesetzt die Interrupts sind global aktiviert). Wird das Bit gelöscht, werden die Interrupts deaktiviert.
+
*'''ACIC (Analog Comparator Input Capture Enable)'''<br/>Noch keine Beschreibung verfügbar. <!-- Vielleicht kann das ja jemand hier beschreiben. -->
+
*'''ACIS1 (Analog Comparator Interrupt Mode Select)'''<br/>Diese Bits bestimmen welches Ereignis den Analog-Komparator Interrupt aktiviert. Es sind folgenden Einstellungen vorhanden:<br>
+
{| {{Blauetabelle}}
+
|'''ACIS1'''
+
|'''ACIS0'''
+
|'''Interruptmodus'''
+
|-
+
|0
+
|0
+
|Interrupt bei Ausgangumschaltung. <!-- Vielleicht kann das ja jemand besser übersetzen... -->
+
|-
+
|0
+
|1
+
|Reserviert (keine Funktion).
+
|-
+
|1
+
|0
+
|Interrupt bei fallender Flanke
+
|-
+
|1
+
|1
+
|Interrupt bei ansteigender Flanke.
+
|}
+
*'''ACIS0 (Analog Comparator Interrupt Mode Select)'''<br/>Siehe ACIS1 für eine Beschreibung.
+
|}
+
 
+
{| {{Blaueschmaltabelle}} width=100%
+
|'''SFIOR (Special Function IO Register)'''
+
|-
+
|Mit diesem Register lässt sich u.a. der Multiplexer des Komparators aktivieren bzw. deaktivieren.<br/><br/>
+
 
+
{{Registertabelle8Bit|-|-|-|-|ACME|-|-|-}}
+
|-
+
|
+
*'''ACME (Analog Comparator Multiplexer Enable)'''<br/>Wird dieses Bit gesetzt und der [[ADC]] ist deaktiviert (d.h. ADEN aus dem Register ADCSRA ist nicht gesetzt) wählt der Multiplexer den invertierten Eingang zum Analog-Komparator. Wird auf dieses Bit dagegen eine 0 geschrieben, so wird AIN1 mit dem invertierten Eingang des Komparators verbunden.  
+
|}
+
  
 
== TWI/I2C ==
 
== TWI/I2C ==
Zeile 811: Zeile 243:
  
 
Näheres zu SPI beim AVR siehe [[SPI (AVR)]].
 
Näheres zu SPI beim AVR siehe [[SPI (AVR)]].
 +
 +
== USI - Universal Serial Interface ==
 +
Für Infos zu USI (Universal Serial Interface) siehe Artikel [[USI (Avr)]].
 +
 +
== IO-PORTs ==
 +
Die IO-Port dienen dazu direkt digitale Werte auszugeben oder einzulesen. Zu jedem Port (im folgenden X für A,B,C,D,...) gehören 3 Register. Zum einem Port gehören bis zu 8 Pins (PX0,...,PX7).
 +
* DDRX : Datenrichtungsregister (1 = Ausgang, 0 = Eingang)
 +
* PORTX bzw. Portx bei BASCOM : Ausgaberegister. Für Ausgänge wird hier der Ausgabewert bestimmt. Für Eingänge wird hier der Pullup-Widerstand eingeschaltet (1) oder ausgeschaltet (0).
 +
* PINX bzw. Pinx bei BASCOM : Eingangsregister. Lesen gibt den Zustand am Pin (1 = high, 0 = low). Das gilt auch wenn der IO Pin als Ausgang funktioniert. Die Wirkung beim Schreiben in dieses Register hängt vom Typ ab (siehe Datenblatt). Bei älteren Typen passiert beim schreiben nichts. Bei einigen neueren Typen wird beim schreiben einer 1 das entsprechende Bit im Register PORTX umgedreht.
 +
 +
Von außen gesehen kann der IO Pin also 4 Zustände haben:  niederohmig an VCC (high), niederohmig an GND (low), Pullup an VCC und hochohmiger Eingang. Für die Ausgabe nutzt man in der Regel PORTX, für Eingänge immer PINX.
  
 
== Die Fusebits ==
 
== Die Fusebits ==
Fusebits nennt man bestimmte Bits zur Konfigurierung eines AVR-Controllers. Bei der Auslieferung neuer AVR Controller sind die Fusebits bereits vorkonfiguriert. In vielen Fällen kann man die Konfiguration unverändert belassen, je nach Controllertyp. Bei den Typen Mega xxx bestimmen einige Fusebits beispielsweise, dass der interne Taktgeber aktiviert ist. Möchte man dagegen einen externen Quarz anschließen oder die Taktfrequenz ändern, so müssen auch die Fusebits geändert werden. Auch das Deaktivieren des "[[On Chip Debugging]]" Modus ist oft notwendig, wenn man alle Ports ausnutzen möchte.  
+
Zur Konfigurierung eines AVR-Controllers werden Fusebits benutzt. Bei der Auslieferung neuer AVR Controller sind die Fusebits bereits vorkonfiguriert, in der Regel auf den internen RC Oszillator und etwa 1 MHz Frequenz. In vielen Fällen kann die Konfiguration unverändert bleiben. Bei den Typen Mega xxx bestimmen einige Fusebits beispielsweise, dass der interne Taktgeber aktiviert ist. Soll z.B. dagegen ein externer Quarz anschlossen oder die Taktfrequenz geändert werden, so müssen auch die Fusebits geändert werden. Auch das Deaktivieren des "[[On Chip Debugging]]" Modus ist oft notwendig, wenn alle Ports genutzt werden sollen.  
  
 
Die Fusebits werden in der Regel über die Software eingestellt, welche auch für das Übertragen des Programmcodes zuständig ist. Besonders einfach geht dies beispielsweise mit der Entwicklungsumgebung [[Bascom]]. Aber auch andere Programme wie [[PonyProg]] können für die Umstellung der Fusebits genutzt werden. Einmal eingestellte Fusebits bleiben bis zur erneuten Fusebit-Änderung erhalten. Der normale Programmiermodus verändert die Fusebits nicht.  
 
Die Fusebits werden in der Regel über die Software eingestellt, welche auch für das Übertragen des Programmcodes zuständig ist. Besonders einfach geht dies beispielsweise mit der Entwicklungsumgebung [[Bascom]]. Aber auch andere Programme wie [[PonyProg]] können für die Umstellung der Fusebits genutzt werden. Einmal eingestellte Fusebits bleiben bis zur erneuten Fusebit-Änderung erhalten. Der normale Programmiermodus verändert die Fusebits nicht.  
  
Je nach AVR Controllertyp sind unterschiedliche Fusebits (Einstellungen) vorhanden. Die genaue Beschreibung findet man im jeweiligen Datenblatt. Da aber falsch gesetzte Fusebit-Einstellungen zu den häufigsten Problemen gehören, liste ich hier die Funktion der üblichen Fusebits nochmals genauer auf:
+
Je nach AVR Controllertyp sind unterschiedliche Fusebits (Einstellungen) vorhanden. Die genaue Beschreibung findet man im jeweiligen Datenblatt. Da aber falsch gesetzte Fusebit-Einstellungen zu den häufigsten Problemen gehören (siehe auch unter dieser Tabelle), liste ich hier die Funktion der üblichen Fusebits nochmals genauer auf:
  
 
{| {{Blauetabelle}}
 
{| {{Blauetabelle}}
Zeile 824: Zeile 267:
 
|-
 
|-
 
  |'''JTAGEN'''
 
  |'''JTAGEN'''
  |Hiermit wird die "[[On Chip Debugging]]" Schnittstelle aktiviert bzw. deaktiviert. Das sind die Bits mit den Bezeichnungen TDI, TDO, TMS und TCK. Möchte man diese Pins als normalen Port nutzen, so muss diese Schnittstelle immer deaktiviert werden.  
+
  |Hiermit wird die "[[On Chip Debugging]]" Schnittstelle aktiviert bzw. deaktiviert. Das sind die Bits mit den Bezeichnungen TDI, TDO, TMS und TCK. Möchte man diese Pins als normalen Port nutzen, so muss diese Schnittstelle immer deaktiviert werden. Alternativ kann man das JTAG aber auch per Software deaktivieren.
 
|-
 
|-
 
  |'''SUT0, SUT1'''
 
  |'''SUT0, SUT1'''
Zeile 833: Zeile 276:
 
|-
 
|-
 
  |'''BODEN'''
 
  |'''BODEN'''
  |Über dieses Bit wird der '''Brown-out Detector''' aktiviert bzw. deaktiviert. Dies ist eine Überwachung der Betriebsspannung. Diese Überwachung soll dafür sorgen, dass bei Spannungseinbrüchen ein ordentlicher RESET durchgeführt wird. Dadurch wird verhindert, dass ein Controller in einen undefinierten Zustand gerät (hängen bleibt).
+
  |Über dieses Bit wird der '''Brown-out Detector''' aktiviert bzw. deaktiviert. Dies ist eine Überwachung der Betriebsspannung, die dafür sorgt, dass bei zu geringer Spannung der Controller angehalten wird und dann ein ordentlicher RESET durchgeführt wird, wenn die Spannung wieder ausreicht. Dadurch wird verhindert, dass der Controller in einen undefinierten Zustand gerät (hängen bleibt), sich verrechnet oder versehentlich das EEPROM / Flash verändert. In der Regel sollte man daher den Brown-out Detector aktivieren.
 
|-
 
|-
  |'''BOOTLEVEL'''
+
  |'''BODLEVEL'''
  |Über dieses Bit kann die Spannung festgelegt werden, ab welcher der '''Brown-out Detector''' den Controller neu startet (also RESET ausführt).  
+
  |Über dieses Bit (ggf. auch mehrere) wird festgelegt, ab welcher Spannung der Brown-out Detector anspricht.  
 
|-
 
|-
 
  |'''BOOTRST'''
 
  |'''BOOTRST'''
Zeile 849: Zeile 292:
 
  |'''CKOPT'''
 
  |'''CKOPT'''
 
  |Abhängig von den Einstellungen von CKSEL kann hier dir Oszillator-Verstärkung eingestellt werden. Genaueres im Datenblatt des jeweiligen Controllers.
 
  |Abhängig von den Einstellungen von CKSEL kann hier dir Oszillator-Verstärkung eingestellt werden. Genaueres im Datenblatt des jeweiligen Controllers.
 +
|-
 +
|'''CKDIV8'''
 +
|Bei neueren µCs (aber etwa Mega88) stellt dieses Bit den Teiler für den Takt ein. Default ist dieses Bit aktiv, so dass der Takt des internen Oszillators von 8 MHz auf 1 MHz geteilt wird.
 
|-
 
|-
 
  |'''WDTON'''
 
  |'''WDTON'''
Zeile 868: Zeile 314:
 
Wie man die Fusebits mit [[Bascom]] einstellt, wird im Beitrag [[Bascom - Erstes Programm in den AVR Controller übertragen]] erläutert.
 
Wie man die Fusebits mit [[Bascom]] einstellt, wird im Beitrag [[Bascom - Erstes Programm in den AVR Controller übertragen]] erläutert.
  
''Autoren des Artikels: Frank, Luma''  
+
''Autoren des Artikels: Frank, Luma''
  
 +
Fusebits verstellt auf Externer Oszillator gehört zu den sehr häufigen Fehlern insbesondere bei Anfängern. Eine Möglichkeit, diesen Fehler mit einem Minimum an Hardware (minimalistisch gehts mit nur 1 Widerstand an einer EIA232-Schnittstelle) zu reparieren, ist hier vorgestellt: [http://www.roboternetz.de/phpBB2/viewtopic.php?t=51685 Fuse irrtümlich auf extern Takt?].
  
 
== Siehe auch ==
 
== Siehe auch ==
* [[Atmel]]
 
* [[On Chip Debugging]]
 
* [[Bootloader]]
 
* [[Avr-gcc|avr-gcc]] - Leistungsfähiger AVR-Port des freien Compilers GCC
 
* [[Bascom]] - Sehr gutes Basic-Entwicklungssystem
 
* [[WinAVR]] - Ein freies Werkzeugpaket auf Basis avr-gcc für die Windows-Platform, integriert unter anderem das [[Programmer's Notepad]]
 
 
* [[AVR-Einstieg leicht gemacht]]
 
* [[AVR-Einstieg leicht gemacht]]
 +
===Entwicklungsumgebungen===
 +
* [[Microsoft_Visual_Studio_2008_als_AVR_Entwicklungsumgebung| Microsoft Visual Studio]] - Die kostenlose "Express Edition" setzt auf WinAVR und auf den GCC auf, compiliert über custom-build und generiert ein Script für Ponyprog
 +
 +
* [[Bascom]] - Basic-Entwicklungssystem
 
* [[Bascom - Erstes Programm in den AVR Controller übertragen]]
 
* [[Bascom - Erstes Programm in den AVR Controller übertragen]]
 +
* [[Avr-gcc|avr-gcc]] - Leistungsfähiger AVR-Port des freien Compilers GCC
 +
* [[WinAVR]] - Freies, kostenloses Werkzeugpaket mit avr-gcc, binutils, tools ([[make]], [[Programmer's Notepad]], [[avrdude]], etc.) für MS-Windows.
 +
* [[Linuxdistribution_Avr-live-cd]]
 
* [[AVR_Assembler_Einf%C3%BChrung|AVR Assembler Einführung (AvrStudio)]]
 
* [[AVR_Assembler_Einf%C3%BChrung|AVR Assembler Einführung (AvrStudio)]]
 +
* [http://www.mikroe.com/en/compilers/mikropascal/avr/ MikroPascal for AVR] Sehr gute kommerzielle Pascal Entwicklungsumgebung. Der Compiler ist auch für PIC und andere Controller verfügbar.
 +
 +
=== Hardware ===
 
* [[AVR-ISP Programmierkabel]] - Bauanleitung für die AVR Controller Programmierkabel
 
* [[AVR-ISP Programmierkabel]] - Bauanleitung für die AVR Controller Programmierkabel
 
* [[RN-Control]] - Eines der beliebtestet AVR-Boards im Roboternetz
 
* [[RN-Control]] - Eines der beliebtestet AVR-Boards im Roboternetz
 
* [[RNBFRA-Board]] - Größeres Board mit zwei Atmel Controllern
 
* [[RNBFRA-Board]] - Größeres Board mit zwei Atmel Controllern
 +
 +
===Sonstiges===
 +
* [[Atmel]]
 +
* [[HEX Beispiel-Dateien für AVR]]
 +
* [[Bootloader]]
 +
* [[On Chip Debugging]]
  
 
== Weblinks ==
 
== Weblinks ==
 
* [http://www.atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC Aktuelle AVR Vergleichstabelle]
 
* [http://www.atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC Aktuelle AVR Vergleichstabelle]
 
* [http://www.atmel.com/dyn/products/devices.asp?family_id=607 Die Datenblätter zu Atmel Controllern]
 
* [http://www.atmel.com/dyn/products/devices.asp?family_id=607 Die Datenblätter zu Atmel Controllern]
* [https://mpg.dnsalias.com/~magerlu/rn-wiki/avrtimer_applet Java Applet Timer Berechnung]
+
* [https://mpg.dnsalias.com/~magerlu/rn-wiki/avrtimer_applet Java Applet Timer Berechnung]  
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=169 AvrTimer Windows Berechnungstool]
+
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=169 AvrTimer Windows Berechnungstool (für Bascom, nur nach Anmeldung)]
 
* [http://people.freenet.de/gjl/helferlein/avr-uart-rechner.html AVR-Baudraten-Rechner (JavaScript)]
 
* [http://people.freenet.de/gjl/helferlein/avr-uart-rechner.html AVR-Baudraten-Rechner (JavaScript)]
 +
* [http://www.engbedded.com/fusecalc/ Berechnung der Fusebits (englisch)]
  
 
[[Kategorie:Microcontroller]]
 
[[Kategorie:Microcontroller]]

Aktuelle Version vom 21. September 2014, 16:43 Uhr

Beispiel eines AVR Controllers

AVR ist eine 8-Bit Microcontroller-Familie mit RISC-Architektur. Im Gegensatz zu vielen anderen Microcontroller-Architekturen hat die AVR-Architektur keine Vorgänger. Sie ist ein komplettes Neudesign, das Anfang der 90-Jahre an der Universität von Trondheim/Norwegen entwickelt und vom (bis heute einzigen) Hersteller Atmel aufgekauft wurde. Es gibt eine ganze Serie von AVR-Controllern. Sie alle werden ähnlich programmiert, haben vergleichbaren Befehlssatz und physikalische Eigenschaften, bieten jedoch unterschiedliche Features und Peripherie.

Es gibt zahlreiche und kostenlose Entwicklungssysteme in den Sprachen Basic, C/C++, Pascal und Assembler für diese Controller-Familie.

Wofür steht AVR?

"AVR" steht angeblich für Advanced Virtual RISC (in einem Paper der Entwickler des AVR-Kerns Alf Egin Bogen und Vegard Wollan). Laut Atmel bedeutet es nichts.

Hardware

AVR-Controller besitzen eine zweistufige Pipeline (fetch and execute), die es ermöglicht, die meisten Befehle innerhalb eines einzigen Prozessortaktes auszuführen. Dadurch ist ein AVR wesentlich schneller als etwa 8051-Controller, bei denen der Prozessortakt intern noch durch 12 geteilt wird.

  • AVR-Kern
    • Harvard-Architektur (getrennter Befehls- und Datenspeicher)
    • 8-Bit Architektur ist für Hochsprachen (C) optimiert
    • 32 Register, davon 6 als 3 Pointerregister, kein Akkumulator
    • Lineares Speichermodell (keine Segmentierung bis 128 kBytes Programmspeicher)
  • In-System programmierbar: die Controller können sehr einfach über ein Programmierkabel (oft ISP-Kabel genannt), das mit dem PC verbunden wird, programmiert werden – auch dann, wenn sie sich nicht in einer Schaltung befindet.
  • integrierter Flash-Speicher für Programm
  • umfangreiche Peripherie
    • Watchdog, Bootloader-Support, verschiedene Stromspar-Modi, Brownout-Erkennung, Interner Oszillator
    • EEPROM-Datenspeicher
    • 8- und 16-Bit-Timer/Counter mit PWM, Capture/Compare, externe Betaktung, asynchrone Operation
    • Kommunikation: USART, SPI, I2C (TWI)
    • Analog-Comparator, Analog-Digital-Wandler
    • unterschiedlichste externe und interne Interrupt-Quellen (UART, SPI, Timer, A/D-Wandler, Analog-Comparator, ...)
    • JTAG (Debugerinterface) (Teilweise)
  • AVR Typen (AT90 "Classic AVR", ATtiny, ATmega), trotzdem sehr ähnlich, die neue XMega Serie ist vor allem bei der Peripherie etwas anders
  • erhältlich in unterschiedlichen Gehäusen, idR Durchsteck und als SMD
  • Viele Entwicklungsboards erhältlich, z.B. das Roboternetzboard RN-Control

Einige Pinbelegungen der populärsten AVR-Controller

(in etwa nach Leistungsfähigkeit sortiert)

At90s2313tiny.png


Mega8kompatibel.png
Mega1632.gif


Mega128pin.gif



Die AVR-Pin-Bezeichnungen und deren Funktion

Die meisten Ports sind doppelt belegt und besitzen neben der normalen Port-Funktion noch eine Sonderfunktion. Die verschiedenen Pinbezeichnungen und Sonderfunktionen werden hier beschrieben:

Tabelle: Die AVR-Pin-Bezeichnungen und deren Funktion
Versorgungs- und Referenzpins, Reset
VCC Versorgungsspannung von 2,7 V bis 5,5 V bei den L-Varianten (low power), ansonsten 4,5V bis 5,5 V. Neuere AVR ab 2,7 V und ab 1,8 V in V-Variante.
GND Masse
AREF Referenzspannung für den Analog-Digital-Wandler. Auch die interne Bandgap-Referenzspannung kann über diesen Pin entstört werden (dann KEINE externe Spannung an diesen Pin geben (Kurzschluss)!).
AGND Analoge Masse für AD Wandler und dazugehörige Ports. Sollte in aller Regel mit GND verbunden werden.
AVCC

Die Betriebsspannung für den Analog-Digital-Wandler (und einiges mehr) (siehe Beschaltungsskizze). Die Pins AVCC und AGND müssen immer beschaltet werden, selbst wenn man den AD-Wandler und Port A nicht benutzt.

RESET Rücksetz-Eingang, intern über einen Pullup mit VCC verbunden. Ein LOW–Pegel an diesem Pin für die Dauer von mindestens zwei Zyklen des Systemtaktes bei aktivem Oszillator setzt den Controller zurück. Rücksetzen der Ports erfolgt unabhängig von einem evtl. anliegenden Systemtakt.
PEN Programming Enable - Diesen Pin gibt es nur beim Mega128/64 u.ä. Wird dieser Pin beim Power-On Reset nach Masse gezogen, geht der Controller in den ISP Programmiermodus. Man kann ihn also alternativ zu Reset verwenden. In der Regel verwendet man aber die Reset-Leitung und PEN sollte man direkt mit VCC verbinden.
System-Takt
XTAL1 Eingang des internen Oszillators zur Erzeugung des Systemtaktes bzw. Eingang für ein externes Taktsignal, wenn der interne Oszillator nicht verwendet werden soll bzw. Anschluss von Quarz/Keramik-Resonator/RC-Glied.
XTAL2 Anschluss von Quarz oder Keramik-Resonator oder Ausgang des integrierten Oszillators zur Nutzung als Systemtakt (Je nach Fuse-Einstellungen).
Digitale bidirektionale I/O-Ports
Jeder Pin der Ports kann individuell als Eingang oder Ausgang konfiguriert werden. Die I/O-Ports sind maximal 8 Bit breit und verfügen ja nach AVR-Typ über eine unterschiedliche Anzahl von Pins. An jedem als Eingang (Input) geschalteten Pin gibt es zuschaltbare Pullup-Widerstände, die teilweise auch bei aktivierter Sonderfunkton verfügbar sind.

Bei eingeschalteten Sonderfunktionen wie UART, SPI, ADC, etc. sind die entsprechenden Pins nicht als "normale" digitale I/O verwendbar, sondern dienen der Sonderfunktion. Die Anzahl der als I/O verwendbaren Pins ist auch abhängig von den Fuse-Einstellungen (Vorsicht beim Umstellen, Handbuch GENAU lesen!).

PA 0 – 7 Port A
PB 0 – 7 Port B
PC 0 – 7 Port C
PD 0 – 7 Port D
PE 0 – 7 Port E
PF 0 – 7 Port F
PG 0 – 7 Port G
Externe Interrupts
Die PCINT-Interrupts gibt es nur für neuere AVRs wie den ATmega88. Falls die Anzahl an externen Interrupts nicht ausreicht, kann evtl. auch andere Hardware dafür eingesetzt werden, etwa der Analog-Comparator mit interner Bandgap-Referenz, falls er anderwärtig nicht gebraucht wird.
INT0 Externer Interrupt 0
INT1 Externer Interrupt 1
INT2 Externer Interrupt 2
PCINTx Pin-Change Interrupt
Timer und PWM
T0 Timer 0: externer Takteingang.
T1 Timer 1: externer Takteingang.
OC0 PWM bzw. Output Compare Ausgang des Timers 0
OC1A Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines

Der erste PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.

OC1B Ausgang für die Compare-Funktion des integrierten Zeitgeber- / Zählerbausteines

Der zweite PWM-Ausgang des Timers1. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.

ICP1 Eingang für die Capture-Funktion des integrierten Zeitgebers / Zählerbausteines
OC2 Pwm bzw. Output Compare Ausgang des Timers2. Er kann zum Regeln der Bot-Motorgeschwindigkeit benutzt werden.
TOSC1, TOSC2 TOSC1 und TOSC2 sind Eingänge für den asynchronen Modus von Timer2. Sie sind vorgesehen für den Anschluss eines externen Uhrenquarzes ( 32.768 kHz ). Damit lassen sich zum Beispiel genaue Ein-Sekunden-Impulse für eine Uhr generien, sogar wenn der normale Takt im Power-save Modus aus ist.
Analog-Digital-Wandler
ADC0 bis ADC7 Eingänge des AD-Wandlers. Spannungen können hier gemessen werden oder an den Analog-Komparator weiter geleitet werden.
Analog-Komparator
AIN0, AIN1 Die beiden externen Eingänge des Analog-Komparators.

Mit AIN0(+) und AIN1(-) kann man zwei Spannungen miteinander vergleichen. Wenn die Spannung an AIN0 höher als bei AIN1 ist, liefert der Komparator "High", ansonsten ein "Low". Als interne Eingänge des Komparators können die Interne Bandgap-Referenzspannung oder Ausgänge des ADC-Multiplexers dienen.

Serielle Schnittstelle (USART)
RXD Eingang der Seriellen Schnittstelle (Receive Data), TTL-Pegel
TXD Ausgang Serielle Schnittstelle (Transmit Data), TTL-Pegel
XCK Taktsignal der USART im synchronen Mode (z.B. als SPI Master).
SPI-Schnittstelle
SS SPI-Interface – wird benötigt, um den µC als aktiven Slave auszuwählen
MOSI SPI-Interface – Datenausgang (als Master) oder Dateneingang (als Slave), verwendet bei ISP (In-System-Programmierung)
MISO SPI-Interface – Dateneingang (als Master) oder Datenausgang (als Slave), verwendet bei ISP (In-System-Programmierung)
SCK SPI-Interface – Bustakt vom Master, verwendet bei ISP (In-System-Programmierung)
I2C-Schnittstelle (TWI)
SDA I2C-Schnittstelle (Bus aus 2 Leitungen) Datenleitung
SCL I2C-Schnittstelle (Bus aus 2 Leitungen) Clockleitung
JTAG-Interface
TDI JTAG-Debug Interface - Über dieses Interface kann man den AVR programmieren und debuggen. Die Schnittstelle ist ähnlich wie die SPI Schnittstelle und hat getrennte Dateneingangs- und Datenausgangsleitungen sowie eine Taktleitung. TDI ist die Dateneingangsleitung
TDO JTAG-Debug Interface - TDO ist die Datenausgangsleitung des JTAG Interface
TMS JTAG-Debug Interface
TCK JTAG-Debug Interface

Timer/Counter

Für Infos zu Timer und Counter siehe Artikel Timer/Counter (Avr).

Analog-Digital-Wandler

Für Infos zu Analog-Digital-Wandler siehe Artikel ADC (Avr).

Analog-Komparator

Für Infos zu Analog-Komparator siehe Artikel Analog Komparator (Avr).

TWI/I2C

Für Details über das Two-wire Serial Interface (kurz TWI) siehe Artikel TWI.

UART/USART

Für Details über den UART/USART siehe Artikel UART.

SPI - Serial Peripheral Interface

Für Details über SPI siehe Artikel SPI.

Näheres zu SPI beim AVR siehe SPI (AVR).

USI - Universal Serial Interface

Für Infos zu USI (Universal Serial Interface) siehe Artikel USI (Avr).

IO-PORTs

Die IO-Port dienen dazu direkt digitale Werte auszugeben oder einzulesen. Zu jedem Port (im folgenden X für A,B,C,D,...) gehören 3 Register. Zum einem Port gehören bis zu 8 Pins (PX0,...,PX7).

  • DDRX : Datenrichtungsregister (1 = Ausgang, 0 = Eingang)
  • PORTX bzw. Portx bei BASCOM : Ausgaberegister. Für Ausgänge wird hier der Ausgabewert bestimmt. Für Eingänge wird hier der Pullup-Widerstand eingeschaltet (1) oder ausgeschaltet (0).
  • PINX bzw. Pinx bei BASCOM : Eingangsregister. Lesen gibt den Zustand am Pin (1 = high, 0 = low). Das gilt auch wenn der IO Pin als Ausgang funktioniert. Die Wirkung beim Schreiben in dieses Register hängt vom Typ ab (siehe Datenblatt). Bei älteren Typen passiert beim schreiben nichts. Bei einigen neueren Typen wird beim schreiben einer 1 das entsprechende Bit im Register PORTX umgedreht.

Von außen gesehen kann der IO Pin also 4 Zustände haben: niederohmig an VCC (high), niederohmig an GND (low), Pullup an VCC und hochohmiger Eingang. Für die Ausgabe nutzt man in der Regel PORTX, für Eingänge immer PINX.

Die Fusebits

Zur Konfigurierung eines AVR-Controllers werden Fusebits benutzt. Bei der Auslieferung neuer AVR Controller sind die Fusebits bereits vorkonfiguriert, in der Regel auf den internen RC Oszillator und etwa 1 MHz Frequenz. In vielen Fällen kann die Konfiguration unverändert bleiben. Bei den Typen Mega xxx bestimmen einige Fusebits beispielsweise, dass der interne Taktgeber aktiviert ist. Soll z.B. dagegen ein externer Quarz anschlossen oder die Taktfrequenz geändert werden, so müssen auch die Fusebits geändert werden. Auch das Deaktivieren des "On Chip Debugging" Modus ist oft notwendig, wenn alle Ports genutzt werden sollen.

Die Fusebits werden in der Regel über die Software eingestellt, welche auch für das Übertragen des Programmcodes zuständig ist. Besonders einfach geht dies beispielsweise mit der Entwicklungsumgebung Bascom. Aber auch andere Programme wie PonyProg können für die Umstellung der Fusebits genutzt werden. Einmal eingestellte Fusebits bleiben bis zur erneuten Fusebit-Änderung erhalten. Der normale Programmiermodus verändert die Fusebits nicht.

Je nach AVR Controllertyp sind unterschiedliche Fusebits (Einstellungen) vorhanden. Die genaue Beschreibung findet man im jeweiligen Datenblatt. Da aber falsch gesetzte Fusebit-Einstellungen zu den häufigsten Problemen gehören (siehe auch unter dieser Tabelle), liste ich hier die Funktion der üblichen Fusebits nochmals genauer auf:

CKSEL0, CKSEL1, CKSEL2, CKSEL3 Die Kombination dieser 4 Fusebits bestimmt die Taktquelle des Controllers. Das kann eine interner Taktgenerator, ein Quarz, Quarzoszillator, RC-Glied und ähnliches sein.
JTAGEN Hiermit wird die "On Chip Debugging" Schnittstelle aktiviert bzw. deaktiviert. Das sind die Bits mit den Bezeichnungen TDI, TDO, TMS und TCK. Möchte man diese Pins als normalen Port nutzen, so muss diese Schnittstelle immer deaktiviert werden. Alternativ kann man das JTAG aber auch per Software deaktivieren.
SUT0, SUT1 Die sogenannte StartUp-Zeit (PowerOn delay). Diese Einstellung muss abhängig von der Art des Taktgenerators eingestellt werden, genaueres im jeweiligen Datenblatt.
SPIEN Hiermit kann die serielle ISP-Programmierung, welche die meisten Programmierkabel nutzen, deaktiviert werden. Dies sollte man lieber vermeiden, denn wenn dieser Programmiermodus deaktiviert wurde, kann nur noch der Parallel-Programmiermodus genutzt werden. Der Parallel-Programmiermodus benötigt jedoch ein spezielles Programmiergerät, das die wenigsten Bastler besitzen. Also Vorsicht!
BODEN Über dieses Bit wird der Brown-out Detector aktiviert bzw. deaktiviert. Dies ist eine Überwachung der Betriebsspannung, die dafür sorgt, dass bei zu geringer Spannung der Controller angehalten wird und dann ein ordentlicher RESET durchgeführt wird, wenn die Spannung wieder ausreicht. Dadurch wird verhindert, dass der Controller in einen undefinierten Zustand gerät (hängen bleibt), sich verrechnet oder versehentlich das EEPROM / Flash verändert. In der Regel sollte man daher den Brown-out Detector aktivieren.
BODLEVEL Über dieses Bit (ggf. auch mehrere) wird festgelegt, ab welcher Spannung der Brown-out Detector anspricht.
BOOTRST Gewöhnlich startet ein Programm im Controller nach einem RESET ab Adresse 0. Durch dieses Fusebit kann der Controller jedoch veranlasst werden, nach einem Reset einen sogenannten Bootloader-Bereich auszuführen. Ein Bootloader kann genutzt werden, um Controller über andere Schnittstellen (z.B. RS232) zu programmieren.
BOOTSZ0, BOOTSZ1 Der zuvor genannte Bootloaderbereich kann bei AVR-Controllern verschieden groß sein. Über diese beiden Bits können vier verschiedene Größen eingestellt werden. Siehe unter Bootloader.
EESAVE Dieses Bit legt fest, ob beim Programmieren des Controllers (man nennt es auch brennen) immer das EEPROM gelöscht werden soll.
CKOPT Abhängig von den Einstellungen von CKSEL kann hier dir Oszillator-Verstärkung eingestellt werden. Genaueres im Datenblatt des jeweiligen Controllers.
CKDIV8 Bei neueren µCs (aber etwa Mega88) stellt dieses Bit den Teiler für den Takt ein. Default ist dieses Bit aktiv, so dass der Takt des internen Oszillators von 8 MHz auf 1 MHz geteilt wird.
WDTON Schaltet den WatchDog-Timer beim Booten ein/aus. Dies ist auch per Software möglich
RSTDISBL Durch dieses Bit kann man den RESET-Pin deaktivieren und dann als normalen I/O-Port nutzen. Aber Vorsicht! Da die RESET-Leitung beim Programmieren (Brennen) des Chips genutzt wird, kann man nach dessen Deaktivierung den Controller mit den üblichen ISP-Adaptern nicht mehr programmieren. In diesem Fall könnte man zwar den Controlle noch mit speziellen Programmiergeräten im Parallelmodus programmieren, aber in der Praxis verfügen nur wenige Bastler über ein Programmiergerät, das dies leistet.
LB1, LB2 Das sind die sogenannten Lockbits, mit denen sich das Auslesen des Flash- als auch EEPROM-Speichers verhindern läßt. Zwar können andere Anwender immer noch Daten lesen, allerdings handelt es sich dabei nicht mehr um den wirklichen Inhalt sondern lediglich um wirre Datenbytefolgen. Programmierer, die den erarbeiteten Code vor Raubkopierern schützen wollen, nutzen diese Lockbits. Das Programmieren ist auch bei gesetzen Lockbits noch möglich. Der Bootloader-Bereich wird nicht durch die Lockbits geschützt.
BLB01, BLB02 Durch diese Bits kann der Code sogar vor dem Zugriff durch den Bootloader geschützt werden
BLB11, BLB12 Diese Bits schützen den Bootloaderbereich selbst

Wie man die Fusebits mit Bascom einstellt, wird im Beitrag Bascom - Erstes Programm in den AVR Controller übertragen erläutert.

Autoren des Artikels: Frank, Luma

Fusebits verstellt auf Externer Oszillator gehört zu den sehr häufigen Fehlern insbesondere bei Anfängern. Eine Möglichkeit, diesen Fehler mit einem Minimum an Hardware (minimalistisch gehts mit nur 1 Widerstand an einer EIA232-Schnittstelle) zu reparieren, ist hier vorgestellt: Fuse irrtümlich auf extern Takt?.

Siehe auch

Entwicklungsumgebungen

  • Microsoft Visual Studio - Die kostenlose "Express Edition" setzt auf WinAVR und auf den GCC auf, compiliert über custom-build und generiert ein Script für Ponyprog

Hardware

Sonstiges

Weblinks


LiFePO4 Speicher Test