K (Tackt mitr CK tut weh ! *rüge*) |
Pidi (Diskussion | Beiträge) |
||
Zeile 3: | Zeile 3: | ||
== Kanäle == | == 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 | + | 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, der dann die anliegenden analoge Spannung in einen digitalten Wert wandelt. |
== Betriebsmodi == | == Betriebsmodi == |
Version vom 5. Dezember 2006, 14:49 Uhr
Für allgemeine Informationen zum Analog-Digital-Wandler siehe Artikel ADC.
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.
Inhaltsverzeichnis
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, 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:
Teilungsfaktoren | 2 | 4 | 8 | 16 | 32 | 64 | 128 |
Um zu bestimmen welcher Teilungsfaktor geeignet ist, kann man folgende Formel verwenden.
[math]Taktfrequenz = 8 MHz[/math]
[math]Teilungsfaktor_{min} = {Taktfrequenz \over {200 kHz}} = {{8000000 Hz} \over {200000 Hz}} = 40[/math]
[math]Teilungsfaktor_{max} = {Taktfrequenz \over {50 kHz}} = {{8000000 Hz} \over {50000 Hz}} = 160[/math]
Deswegen kann man nun zwischen einem der folgenden Teilungsfaktor wählen: 64 und 128. Im Interesse der Geschwindigkeit sollte 64 gewählt werden.
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:
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.
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:
- 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.
[math]V = 592 * 5V[/math]
[math]V = 2960 / 2 ^{Bit} = 2960 / 2 ^{10} = \underline {\underline { 2{,}9V }}[/math]
Programmbeispiele
C/C++
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);).
#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; }
Bascom
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.
' 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
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.
ADCSRA (ADC Control and Status Register A) | ||||||||||||||||||||||||||||||||||||
Dieser Register dient dazu den ADC zu kontrollieren.
| ||||||||||||||||||||||||||||||||||||
|
ADMUX (ADC Multiplexer Selection Register) | |||||||||||||||||||||||||||||||||
Mit diesem Register wird u.a. der Multiplexer gesteuert.
| |||||||||||||||||||||||||||||||||
Es reicht also einfach die Pinnummer in ADMUX zu schreiben.
|
Des Weiteren gibt es noch den Register ADCL/ADCH in dem das Ergebnis einer Wandlung steht. Man liest den Wert folgendermaßen aus:
uint16_t x = ADCL; x += (ADCH<<8); // oder x = ADCW;
Siehe auch