Bascom-AVR

Kleiner Bascom AVR Kurs -
Analog-Comparator

Hallo!

Im letzten Beitrag habe ich den Analog/Digital-Converter angesprochen. Das heutige Thema hat zwar auch mit dem Stichwort "Analog" zu tun, aber nicht mit der Messung einer Spannung, sondern mit dem Vergleich zweier Spannungen. Der Analog-Comparator (AC) vergleicht zwei Spannungen miteinander. Ist die Spannung am Pin AIN0 (PD6) höher als die Spannung am Pin AIN1 (PD7), dann gibt der Analog-Comparator HIGH zurück. Ist die Spannung am Pin AIN0 kleiner als die Spannung am Pin AIN1, dann gibt der Analog-Comparator LOW zurück.

Das kann man nutzten, um z.B. Pegelstände über ein Potentiometer einzustellen, welche beim Über- oder Unterschreiten angezeigt werden sollen. Oder um einen Pegel immer unter einem anderen Pegel zu halten. Z.B. zur Ansteuerung einer Wasserpumpe, die nur dann Wasser in einen Auffangbehälter pumpt, wenn noch genug Platz im Auffangbehälter ist.

An welchem Pin (AIN0 oder AIN1) die Referenzspannung angelegt wird ist egal. Die Spannung darf aber, wie üblich, nicht höher als VCC sein. Statt einer externen Referenzspannung kann eine interne 1,30 Volt (min: 1,15 V; max: 1,40 V) Bandgap-Referenzspannung verwendet werden. Diese interne Referenzspannung wird intern an AIN0 angelegt. Der Pin PD6 wird dadurch für andere Anwendungen frei.

Analog Comparator Block Diagram (ATmega8 Datenblatt; Kapitel "Analog Comparator")

atmega8_analog_comparator.gif

STOP AC/START AC

Der AC ist ständig eingeschaltet (aktiv) und muss nicht explizit gestartet werden. Man kann ihn mit STOP AC ausschalten und mit START AC wieder einschalten.

Die Hilfe zu START AC findest du hier: http://avrhelp.mcselec.com/index.html?start.htm
Die Hilfe zu STOP AC findest du hier: http://avrhelp.mcselec.com/index.html?stop.htm

ACSR.ACO

Das ist kein Befehl, sondern die Abkürzung für Analog Comparator Control and Status Register - Analog Comparator Output. Dieses Bit zeigt den Zustand des AC an und kann jederzeit abgefragt werden.

Die Hilfe zu diesem Bit findest du im ATmega8-Datenblatt im Kapitel "Analog Comparator".

Beispiel:

$regfile = "m8def.dat"

Led1 Alias Portb.0
Config Led1 = Output

Do
   Led1 = ACSR.ACO
Loop

End

Dieses Minimalbeispiel setzt voraus, dass an PB0 eine LED angeschlossen ist. Bei meinem Test sind an den Pins AIN1 und AIN0 jeweils ein 25k Poti als Spannungsteiler (zwischen VCC und GND) angeschlossen. Liegt an AIN0 eine höhere Spannung als an AIN1, dann leuchtet die LED. Wie man sieht, muss der AC nicht gestartet werden. Der AC ist ständig aktiv -- außer man schaltet ihn explizit aus (mit STOP AC).

Interrupt

Der AC kann auch einen Interrupt auslösen. Der AC-Interrupt (ACI) kann bei LOW-HIGH-Flanke (RISING), bei HIGH-LOW-Flanke (FALLING) und bei Zustandsänderung (TOGGLE) ausgelöst werden. Dieses Verhalten kann man mit dem Befehl CONFIG ACI einstellen.

Die Hilfe zu diesem Befehl findest du hier: http://avrhelp.mcselec.com/index.html?config_aci.htm

Beispiel:

$regfile = "m8def.dat"


Led1 Alias Portb.0
Config Led1 = Output

Led2 Alias Portb.1
Config Led2 = Output


Config Aci = On , Trigger = Toggle
On Aci On_aci
Enable Aci


Enable Interrupts


Do
   Led1 = ACSR.ACO
Loop

End


On_aci:
   Led2 = Not ACSR.ACO
Return

Dieses Beispiel setzt zusätzlich zum vorherigen Beispiel noch eine LED an PB1 voraus. Wenn man sich mit dem Testaufbau ein wenig spielt, dann fällt auf, dass die erste LED nach dem Start des Programms sofort entweder ein oder aus ist (je nach Poti-Einstellung). Die zweite LED wird erst dann ein- oder ausgeschaltet, wenn der Schwellwert durch Drehen an einem der Potis über- oder unterschritten wird. Der Interrupt wird also nur beim "Toggeln" ausgelöst.

Interne Spannungsreferenz

Setzt man das Bit ACSR.ACBG Analog Comparator Bandgap Select, dann wird intern an AIN0 eine 1,30 Volt (min: 1,15 V; max: 1,40 V) Bandgap-Referenzspannung angelegt. Der Pin PD6 wird damit frei.

Beispiel:

$regfile = "m8def.dat"


Led1 Alias Portb.0
Config Led1 = Output

ACSR.ACBG = 1 ' Interne Bandgap-Referenzspannung verwenden


Do
   Led1 = ACSR.ACO
Loop

End

Multiplexer

Der AC kann nicht nur mit den Pins AIN0 und AIN1 arbeiten. Statt AIN1 kann man den vom Analog/Digital-Converter (ADC) bekannten Multiplexer verwenden. Natürlich nur, wenn dieser nicht bereits vom ADC verwendet wird. Damit hat man für den Analog-Comparator die Pins ADC0 bis ADC5 (bei SMD-Bausteinen auch ADC6 und ADC7) zur Verfügung. Da es (laut Roland Walter) nach dem Umschalten des Multiplexers bis zu 750 ns dauern kann, bis der AC mit der Messung fertig ist, muss man diese 750 ns warten bevor man das Bit ACSR.ACO auswertet. Wenn der ATmega8 mit 8 Mhz läuft, dann dauert ein Tick 125 ns (1 sec / 8000000 Ticks = 0,000000125). Um den µC 750 ns warten zu lassen braucht es sechs Ticks. Diese kann man am Einfachsten mit !NOP verbraten. Im Datenblatt finde ich nur den Hinweis auf 1 bis 2 Ticks, aber lieber ein paar Ticks zu viel als zu wenig warten. ;-)

Ich verwende im Beispiel das erste Mal den MACRO-Befehl. Damit kann man sich Schreibarbeit sparen und öfter wiederkehrende Befehle zusammenfassen. Bascom ersetzt beim Kompilieren des Programms den Makro-Aufruf durch den Inhalt des Makros. Ein Makro ist schneller als GOTO oder GOSUB und braucht weniger Laufzeitressourcen, aber es wird kein Flash-Speicherplatz gespart.

Beispiel:

$regfile = "m8def.dat"
$crystal = 8000000


Led1 Alias Portb.0
Config Led1 = Output

Led2 Alias Portb.1
Config Led2 = Output

ACSR.ACBG = 1      'Bandgap-Referenzspannung einschalten
SFIOR.ACME = 1     'Multiplexer einschalten


'Makro, welches bei 8 Mhz 750 ns wartet
Macro Wait750ns
   !NOP   '125 ns
   !NOP   '125 ns
   !NOP   '125 ns
   !NOP   '125 ns
   !NOP   '125 ns
   !NOP   '125 ns
End Macro


Do
   ADMUX = 0       'nach ADC0 umschalten
   Wait750ns       'warten
   Led1 = ACSR.ACO

   ADMUX = 1       'nach ADC1 umschalten
   Wait750ns       'warten
   Led2 = ACSR.ACO
Loop

End

In diesem Beispiel wird je eine LED an PB0 und PB1 erwartet. Die in den vorherigen Beispielen angesprochenen Potis befinden sich für dieses Beispiel an den Pins ADC0 (PC0) und ADC1 (PC1).

Viel Spaß beim Ausprobieren. :-)


lg Gerold :-)



Den zugehörigen Original-Beitrag findest du im Loetstelle-Forum.