Hallo!
Langsam ist es an der Zeit mein Versprechen einzulösen, dass ich nach dem LCD-Thema das Thema Analog/Digital-Converter (ADC) aufgreife. Ein ADC ist so etwas wie ein Spannungsmesser. Mit einem ADC kann eine Spannung zwischen 0 Volt und der Analog-Versorgungsspannung AVCC (normalerweise 5 Volt) gemessen werden. Wenn man eine höhere Spannung messen will, dann muss man diese zuerst so weit niederbrechen, dass niemals mehr als AVCC bzw. die angelegte Referenzspannung am zu messenden Pin anliegen kann. Zum Beispiel mit einem Spannungsteiler aus zwei Widerständen und einer Z-Diode zum Schutz vor Überspannungen. Die Impedanz dieses Spannungsteilers sollte 10 kOhm nicht überschreiten.
Der ATmega8 hat so einen ADC mit an Board. Es ist zwar nur ein ADC eingebaut, aber dieser kann von sechs Pins (bei DIP-Gehäuse) oder acht Pins (bei SMD-Gehäusen) angesteuert werden. Dafür hat der ATmega8 einen so genannten Multiplexer eingebaut. Ein Multiplexer ist nichts anderes als ein Schalter, der das Signal eines Pins zum ACD umleitet.
Man muss also zuerst den Multiplexer einstellen -- also den Pin auswählen von dem das Signal zum ADC umgeleitet werden soll. Dann kann man die Messung mit dem ADC beginnen.
Bascom bietet dafür den Highlevel-Befehl GETADC
an. GETADC stellt zuerst den abzufragenden Pin über den Multiplexer ein und misst danach die dort angelegte Spannung mit dem ADC. Du musst dich selber um nichts mehr kümmern.
Du solltest aber auch wissen, dass GETADC kein Wundermittel ist. Wie andere Highlevel-Befehle auch, hat GETADC auch Nachteile. Einer der Nachteile ist, dass das Programm so lange still steht (grob geschätzt, bis zu 300 µs), bis die Messung vorbei ist. Der Befehl GETADC stellt zuerst den Multiplexer ein. -- Danach wird erst gemessen. Es könnte also passieren, dass ein Interrupt das Programm genau zwischen dem Umstellen des Multiplexers und der Messung unterbricht. Das alleine ist noch kein Problem. Es wird nur dann zu einem Problem, wenn im Interrupt-Handler der Multiplexer auf einen anderen Pin umgeschaltet wird. Falls du also den Multiplexer innerhalb eines Interrupt-Handlers umstellst (warum auch immer), solltest du vor dem Verwenden von GETADC die Interrupts global ausschalten und danach wieder einschalten (mit den Befehlen DISABLE INTERRUPTS
und ENABLE INTERRUPTS
). Man kann den ADC auch so einstellen, dass Messungen ohne Unterbrechung des Programmes vorgenommen werden. Das ist kein Problem, aber das funktioniert nicht mit dem Highlevel-Befehl GETACD. Dafür muss man die Einstellungen direkt in den AVR-Registern setzen (ohne Highlevel-Befehl).
Mit CONFIG ADC wählt man in erster Linie die Referenzspannung aus. Man kann damit auch auswählen, wie schnell die Messungen durchgeführt werden sollen. Je schneller, desto ungenauer. Je langsamer, desto genauer. Aber da das mit dem Parameter PRESCALER = AUTO
automatisch passiert, werde ich nicht weiter darauf eingehen.
Zur Verwendung des ADC mit dem Highlevel-Befehl GETADC, muss man den ADC auf SINGLE stellen. Da diese Einstellung bei Verwendung von GETADC immer gleich aussieht, werde ich hierauf auch nicht näher eingehen.
Anders sieht es mit der Auswahl der Referenzspannung aus. Der REFERENCE-Parameter kann beim ATmega8 auf AREF
, AVCC
oder INTERNAL
eingestellt werden.
Wird AREF als Referenzspannung ausgewählt, dann wird diese direkt vom AREF-Pin genommen. Diese Referenzspannung muss mit einem 100n Keramikkondensator gegen GND entstört werden.
Wird AVCC als Referenzspannung ausgewählt, dann wird diese intern an AREF angelegt. Diese Spannung kann, zusätzlich zur obligatorischen Entstörung des AVCC-Pins, mit einem 100n Keramikkondensator von AREF (nicht AVCC) nach GND entstört werden.
Wird INTERNAL als Referenzspannung ausgewählt, dann wird eine interne 2,56 Volt Referenzspannung an AREF angelegt. Diese Spannung muss mit einem Keramikkondensator gegen GND entstört werden.
Beispiel:
CONFIG ADC = SINGLE, PRESCALER = AUTO, REFERENCE = AVCC
Die Hilfe zu CONFIG ADC findest du hier: http://avrhelp.mcselec.com/index.html?config_adc.htm
Bevor man den ADC verwenden kann, muss man den ADC aktivieren. Und genau das passiert mit dem Befehl START ADC
. Beispiel siehe: GETADC
Die Hilfe zu START ADC findest du hier: http://avrhelp.mcselec.com/index.html?start.htm
GETADC
erwartet als Parameter die ID des zu messenden ADC-Pins. Der ATmega8 stellt sechs, oder bei SMD-Gehäusen acht, ADC-Eingänge zur Verfügung. Diese sind beim Atmega8 im DIP-Gehäuse die Pins PC0 bis PC5. Bei SMD-Gehäusen kommen noch die zwei Pins ADC6 und ADC7 dazu. Diese zwei Pins können nur als ADC-Eingänge verwendet werden. Ansonsten haben diese Pins keine zusätzliche Funktion.
Beispiel:
CONFIG ADC = SINGLE, PRESCALER = AUTO, REFERENCE = AVCC
START ADC
DIM messergebnis AS WORD
messergebnis = GETADC(0)
...
messergebnis = GETADC(7)
Zusätzlich zu den oben genannten Pins (0-7), kann noch eine interne 1,3 Volt Bandgap-Spannungsreferenz über die Zahl 14 und GND über die Zahl 15 gemessen werden.
Beispiel:
CONFIG ADC = SINGLE, PRESCALER = AUTO, REFERENCE = AVCC
START ADC
DIM messergebnis AS WORD
messergebnis = GETADC(14) '1,3 Volt Bandgap
messergebnis = GETADC(15) '0 Volt GND
Die Hilfe zu GETADC findest du hier: http://avrhelp.mcselec.com/index.html?getadc.htm
Die Messauflösung des ADC ist 10 Bit. Das bedeutet, dass maximal 1024 unterschiedliche Spannungen gemessen werden können. Bei einer Referenzspannung von 5 Volt ist jeder Messschritt 0,0048 Volt groß. Kleinere Spannungsunterschiede können nicht gemessen werden. Die Genauigkeit schwankt zwischen +-2 Messschritten. Bei 5 Volt Referenzspannung ist die Genauigkeit also +-0,0097 Volt. Wenn man das grob schätzt, dann kann man sagen, dass der ADC bei 5 Volt Referenzspannung eine angelegte Spannung auf zwei Kommastellen genau misst.
Ich habe bis jetzt nur von 5 Volt Referenzspannung geschrieben. Aber man kann jede beliebige Spannung zwischen 2 Volt und AVCC als Referenz verwenden. Diese Spannung kann man an den Pin AREF anlegen. Am Einfachsten ist es, wenn man die Spannung vom Pin AVCC, also der Spannungsversorgung des analogen Teils des Mikrocontrollers, als Referenzspannung verwendet. AVCC als Referenzspannung kann man intern einstellen. Man muss diese also nicht extra an den Pin AREF anlegen. Um kleinere Spannungen messen zu können, ohne eine Referenzspannung an AREF anlegen zu müssen, kann man auch eine interne 2,56 Volt Referensspannung auswählen. Mit dem Befehl CONFIG ADC
wählt man die Referenzspannung aus.
Da der Mikrocontroller nicht wissen kann, welche Spannung als Referenz anliegt, gibt der ADC immer nur eine Zahl zwischen 0 und 1024 zurück. 0 bedeutet 0 Volt und 1024 bedeutet Referenzspannung. Diese Zahl in eine Spannung umzuwandeln liegt an dir.
Die Formel dafür lautet: Vin = Vref / 1024 * ADC
Wenn du eine 5 Volt Referenzspannung verwendest, dann kannst du dir "5.0 / 1024.0" in einer Konstante speichern. So ersparst du dir diesen Rechenschritt im Programm. Z.B. so:
CONST ADC_MULTI = 0.0048828125 ' = 5.0 / 1024.0
Beispiel:
CONST ADC_MULTI = 0.0048828125 ' = 5.0 / 1024.0
CONFIG ADC = SINGLE, PRESCALER = AUTO, REFERENCE = AVCC
START ADC
DIM messergebnis AS WORD
DIM volt AS SINGLE
messergebnis = GETADC(0)
volt = messergebnis * ADC_MULTI
Für analoge Messungen muss der Pin AVCC gut entstört werden. Das geschieht zuerst mal mit einem 100 nF Keramikkondensator gegen GND. Und zusätzlich sollte man den Strom über eine 10 µH Spule von VCC beziehen.
Ob nun die interne 2,56 Volt Spannungsreferenz, VCC oder direkt AREF als Spannungsreferenz herangezogen wird, ein 100 nF Keramikkondensator vom Pin AREF nach GND kann nicht schaden.
Weiters sollte man darauf achten, dass während einer Messung kein Pin des Analogteiles umgeschaltet wird. Jede Zustandsänderung an einem der Analog-Pins kann das Ergebnis verfälschen. Das ist auch der Grund dafür, dass ich die Analog-Pins nur dann für digitale Operationen verwende, wenn ansonsten keine anderen Pins mehr zur Verfügung stehen.
Die Pins PC4 (ADC4/SDA) und PC5 (ADC5/SCL) sind Sonderfälle. Da diese Pins auch für I²C-Verbindungen zuständig sind, werden diese Pins nicht von AVCC sondern von VCC versorgt. Diese beiden Pins werden also mit der Stromversorgung für den digitalen Bereich des Mikrocontrollers versorgt. Und nicht wie die restlichen ADC-Pins mit AVCC. Dadurch sind Messungen an diesen Pins nie so genau, wie an den anderen ADC-Pins. Das sollte man beim Zeichnen eines Schaltplanes beachten.
Die genauen Daten findest du im Datenblatt im Kapitel "ADC Characteristics".
lg Gerold :-)
Den zugehörigen Original-Beitrag findest du im Loetstelle-Forum.
Ich programmiere Progressive Web Applications, Mobile Apps, Desktop-Programme und noch vieles mehr. Falls es dich interessiert, findest du mehr Informationen darüber auf meiner Business-Website.