Forum: Mikrocontroller und Digitale Elektronik ATmega48PA Analog Comparator mit interner Referenzspannung und Interrupt


von Lenwo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community,

ich habe ein Problem mit dem Komparator im ATmega48PA und würde euch 
gern um Rat bitten. Grundsätzlich möchte ich folgendes erreichen:

Der Komparator soll die an AIN1 anliegende Spannung mit der internen 
Referenzspannung vergleichen und bei steigender Flanke des 
Komparator-Outputs ein Interrupt auslösen. Zur Visualisierung des 
Ergebnisses wird dann ein Output Pin getoggled an dem eine LED hängt.

Dafür verwende ich momentan den folgenden Aufbau: ATmega48PA sitzt im 
Sockel auf einem AVR Dragon Board. Verdrahtet ist er über den ISP 
Header, ausgeführt wird der Code aber per DebugWIRE. Also IDE verwende 
ich AtmelStudio 7.

An dem PC0 Pin hängt die LED (ich habe die Funktionalität der LED in 
einem Testlauf schon überprüft). An dem Pin PD7 (AIN1) hängt für diese 
Testzwecke ein offenes Kabel, dass ich bei Bedarf mit VCC verbinde um 
den Komparator zu schalten.

Hier ist der C Code, den ich momentan verwende:
1
#define   F_CPU   1000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
8
void initAll() {
9
  //gpio port C pin 0 direction: output
10
  DDRC |= (1 << DDC0);
11
  PORTC &= ~(1 << PORTC0);
12
  
13
  //gpio port D pin 7 direction: output, no pull-up
14
  DDRD &= ~(1 << DDD7);
15
  PORTD &= ~(1 << PORTD7);
16
  
17
  //disable the digital input buffers
18
  DIDR1 |= (1<<AIN1D) | (1<<AIN0D);
19
  
20
  //ACBG: internal reference voltage
21
  //ACIE: interrupt enable
22
  //ACIS1/ACIS0: Rising output edge
23
  ACSR |= (1 << ACBG) | (1 << ACIE) | (1 << ACIS0) | (1 << ACIS1);
24
  //internal reference voltage stabiliization
25
  _delay_ms(2);
26
}
27
28
void ledInterrupt() {
29
  PINC |= (1 << PINC0);
30
}
31
32
ISR(ANALOG_COMP_vect)
33
{
34
  ledInterrupt();
35
}
36
37
int main(void)
38
{
39
  initAll();
40
  sei();
41
  
42
    /* Replace with your application code */
43
    while (1) 
44
    {
45
    
46
    }
47
}

Das Problem ist das Folgende: Hängt das Kabel in der Luft, wechselt der 
Komparator dauerhaft seinen Ausgang, die LED flackert also mit hoher 
Frequenz (aber langsam genug, dass man das Flackern sieht). Verbinde ich 
das Kabel mit VCC wird der momentane Zustand der LED beibehalten, aber 
es wird kein Interrupt ausgelöst. Ebenso wenn ich das Kabel vom AIN1 
vollständig entferne.

Ich habe ein Bild von der ganzen Verdrahtung mit angehängt - nicht damit 
ihr sie überprüft, sondern damit ihr wisst von was für einem offenen 
Kabel ich spreche. Nehme ich das offene Kabel weit genug weg von den 
Übrigen, schaltet der Komparator nicht mehr. Es scheint also als würde 
das Kabel als Antenne fungieren und Störsignale von den übrigen Kabel 
empfangen. Trotzdem dürfte die Spannung dabei doch nicht größer als 1.1V 
werden oder?

Mein Schluss aus dem ganzen ist, dass die interne Referenzspannung nicht 
korrekt mit dem Komparator verbunden ist. Aber vielleicht habt ihr ja 
noch eine andere Idee!

Vielen Dank für Eure Hilfe und Beste Grüße
Lenwo

von Kaltfuss (Gast)


Lesenswert?

Was willst du für den Dragon haben?

von Peter D. (peda)


Lesenswert?

Lenwo schrieb:
> Hängt das Kabel in der Luft, wechselt der
> Komparator dauerhaft seinen Ausgang

Das ist korrekt, "Luft" ist kein gültiger Logikpegel und auch kein 
definierter Analogpegel.
Floatende Pins fangen sich gerne 50Hz Netzbrumm ein.

von Thomas E. (thomase)


Lesenswert?

Lenwo schrieb:
> Trotzdem dürfte die Spannung dabei doch nicht größer als 1.1V
> werden oder?

Offenbar tut sie das aber doch. Sonst würde der Komparator ja nichts 
davon mitbekommen.

Lenwo schrieb:
> Mein Schluss aus dem ganzen ist, dass die interne Referenzspannung nicht
> korrekt mit dem Komparator verbunden ist

Quatsch. Deine Schaltung macht genau das, was sie soll. Das ist nur 
nicht das, was du willst.

Das ACO-Flag wird gesetzt, wenn AIN1 < AIN0.
Immer wenn das ACO gesetzt wird, wird ein Interrupt ausgelöst. Steigende 
Flanke, hast du so eingestellt. Steigende oder fallende Flanke bezieht 
sich auf das ACO-Flag. Nicht auf das, was an den Pins passiert.

Leg den AIN1 mit einem Widerstand auf GND und stell den Interrupt auf 
fallende Flanke. Wenn du den Draht dann an Vcc hältst, wird der 
Interrupt ausgelöst.

: Bearbeitet durch User
von Lenwo (Gast)


Lesenswert?

Hallo und vielen Dank für die so schnellen Antworten!

Peter D. schrieb:
> Das ist korrekt, "Luft" ist kein gültiger Logikpegel und auch kein
> definierter Analogpegel.
> Floatende Pins fangen sich gerne 50Hz Netzbrumm ein.

Thomas E. schrieb:
> Offenbar tut sie das aber doch. Sonst würde der Komparator ja nichts
> davon mitbekommen.

Thomas E. schrieb:
> Leg den AIN1 mit einem Widerstand auf GND und stell den Interrupt auf
> fallende Flanke. Wenn du den Draht dann an Vcc hältst, wird der
> Interrupt ausgelöst.

Funktioniert wunderbar! Unterm Strich habe ich also Stunden investiert, 
weil ich nicht glauben konnte, dass der Komparator korrekt arbeitet - 
ist dann wohl zumindest berechtigt ;-)

Vielen Dank für die Hilfe, war wirklich schnell und unkompliziert!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.