analog comparator erkennt keine veränderte flanke

#1094733
Lesenswert?

Hi,

Ich hab an meinem ATMega168 an ADC1 3,2 V angelegt und ADC0 auf masse 
gelegt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
ISR(ANALOG_COMP_vect)
4
{
5
  PORTB = 0x00;
6
}
7

8

9
int main(void)
10
{
11
  DDRB = 0xff;
12
  PORTB = 0xff;
13
  ACSR |= (1<<ACIE) | (1<<ACIS1);
14
  sei();
15
  for(;;);
16
  return 0;
17
}
verbinde ich jetzt ADC0 mit 5V bleibt PORTB an. Soweit wär ja auch noch 
alles in ordnung. Lege ich ADC0 jetzt aber wieder auf Masse(fallende 
Flanke) bleibt PORTB immer noch an.

Weiß jemand was ich falsch gemacht hab?

Danke,

Moritz
#1094861
Lesenswert?

Hi,

Von welchem Datenblatt reden wir?
In meinem ist das nämlich eine andere Tabelle: "Table 21-2.
Status codes for Master Transmitter Mode".
Ansonsten wird doch die Richtungserkennung umgeschalten.
ACSR |= (1<<ACIE) | (1<<ACIS1);
Das ACIS1-Bit sorgt dafür, dass ein Interrupt bei fallender Flanke 
ausgelöst wird.
EDit:
Ah bei mir ist Tabelle 22-2 wohl die richtige:
1
Table 22-2.
2
ACIS1
3
0
4
0
5
1
6
1
7
ACIS0
8
0
9
1
10
0
11
1
12
Interrupt Mode
13
Comparator Interrupt on Output Toggle.
14
Reserved
15
Comparator Interrupt on Falling Output Edge.
16
Comparator Interrupt on Rising Output Edge.
naja das dann halt als Tabelle denken.
Und ich hab ACIS0=0 ACIS1=1 bedeutet Comparator Interrupt on Falling 
Output Edge.
Persönliche Seite #1094892
Lesenswert?

Moritz Sch schrob:
> Muss DDRD eigentlich irgendwie gesetzt sein?

Ich würd es auf IN ohne Pullups setzen, also default nach Reset.

Versuch mal

Das ISQ-Flag nach Setzen von ACSR zu löschen, also:
1
   ASCR = (1 << ACIE) | (1 << ACIS1);
2
   ASCR = (1 << ACIE) | (1 << ACIS1) | (1 << ACI);

Ausserdem kannst du versuchen
-- Auf Toggle der Flanke zu regieren: ACIS[1..0] = 00
-- Mehr Informationen an Port B auszugeben, zB ACO, etc.
#1094906
Lesenswert?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
ISR(ANALOG_COMP_vect)
4
{
5
  PORTB = 0x00;
6
}
7

8

9
int main(void)
10
{
11
  DDRB = 0xff;
12
  PORTB = 0xff;
13
  ACSR = (1 << ACIE);
14
  ACSR = (1 << ACIE) | (1 << ACIS1) | (1 << ACI);
15
  sei();
16

17
  /* neverending loop */
18
  for(;;);
19
  return 0;
20
}
Soweit mein momentaner Code: Bringt nichts, PORTB bleibt an.
Persönliche Seite #1094919
Lesenswert?

Beim Initialisieren entweder
1
   ASCR = (1 << ACIE) | (1 << ACIS1);
2
   ASCR = (1 << ACIE) | (1 << ACIS1) | (1 << ACI);

oder
1
   ASCR = (1 << ACIE);
2
   ASCR = (1 << ACIE) | (1 << ACI);

Wobei ich erst mal Version 2 versuchen würde. Wenn's damit nicht klappt 
ist das Problem woanders: µC kaputt oder Fehler im Makefile, so daß du 
immer das gleiche, alte Programm brennst oder sowas.
#1094921
Lesenswert?

Hi,

Sry hab mich wieder verschrieben. Meinte die 2. Version!
Es ist übrigends ACSR (nicht ASCR).
Ok nochmal zum Überprüfen ob ich das richtige verstanden hab.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
ISR(ANALOG_COMP_vect)
4
{
5
  PORTB = 0x00;
6
}
7

8

9
int main(void)
10
{
11
  DDRB = 0xff;
12
  PORTB = 0xff;
13
  ACSR = (1 << ACIE);
14
  ACSR = (1 << ACIE) | (1 << ACI);
15
  sei();
16

17
  /* neverending loop */
18
  for(;;);
19
  return 0;
20
}
Das Makefile ist in Ordnung (Wenn ich sinnlose Zeilen dazuschreiben wird 
die gebrannte byte-zahl größer).
Kann es sein, dass nur der comparator kaputt ist und der rest 
funktioniert?
Persönliche Seite #1094929
Lesenswert?

hmmm, ich weiß ja net, was du mit dem Ding alles angestellt hast...

Denkbar wäre auch, daß er verfust ist, zB WDT an ist und er immer einen 
WDT-Reset macht, so daß das kurze Verlöschen der LED nicht zu erkennen 
ist.

Ich hatte mal den Port eines Mega168 frittiert, der µC lief ansonsten 
tadellos, nur der eine Port ging eben nicht mehr. Und der µC wurde 
ziemlich warm dabei, was ich sonst bei AVR noch nie beobachtet habe.
Persönliche Seite #1094945
Lesenswert?

Der WDT ist standardmässig aus, wenn du nix an den Fuses gedreht hast, 
fällt mir nichts mehr ein..

Vielleicht ne instabile Spannungsversorgung? Oder ein 
nicht-stabilisiertes Netzteil. Wenn da 5V draufstehen, liefert das im 
Leerlauf u.U. deutlich mehr. Und ein AVR zieht ja praktisch nichts an 
Strom.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
ISR(ANALOG_COMP_vect)
5
{
6
  PORTB &= ~(1 << PB1);
7
}
8

9
int main(void)
10
{
11
  DDRB  = (1 << PB1) | (1 << PB0);
12
  PORTB |= (1 << PB1);
13

14
  ACSR = (1 << ACIE);
15
  ACSR = (1 << ACIE) | (1 << ACI);
16

17
  sei();
18

19
  while (1)
20
  {
21
      if (ACSR & (1 << ACO))
22
         PORTB |= (1 << PB0);
23
      else
24
         PORTB &= ~(1 << PB0);
25
  }
26
}

Ob der AC überhaupt was macht siehst du an dem Code an Pin B0, ob die 
ISR aufgerufen wird an Pin B1.

Wie gesagt, mir gehen da langsam die Ideen aus...
#1094963
Lesenswert?

Hier die Fuses:

Das kommt raus:
avrdude: Device signature = 0x1e9406
avrdude: safemode: lfuse reads as F7
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as 1

WDTON ist nicht gesetzt.

http://www.engbedded.com/cgi-bin/fc.cgi?P_PREV=ATmega168&P=ATmega168&V_LOW=F7&V_HIGH=DF&V_EXTENDED=1&O_HEX=Apply+user+values&M_LOW_0x3F=0x22&M_LOW_0x80=0x00&M_HIGH_0x07=0x07&M_HIGH_0x20=0x00&M_EXTENDED_0x06=0x00&B_CKDIV8=P&B_SPIEN=P&B_SUT0=P&B_CKSEL3=P&B_CKSEL2=P&B_BOOTSZ1=P&B_BOOTSZ0=P&B_CKSEL0=P

Dein Code tut leider auch nicht. Also PB0 bleibt immer aus und PB1 
bleibt immer an.

Spannungsversorgung ist konstant bei 4,87V.
Persönliche Seite #1095006
Lesenswert?

Ich denke es ist ein Hardwareproblem.

Gehen denn sonstige Testprogramme? ZB Simple Warteschleife und LED 
blinken?

Wie hast du den Quarz angeschlossen?

Die Fuses sehen jedenfalls gut aus (falls ein Quarz etc dran ist)
1
#define F_CPU 8000000
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5

6
int main(void)
7
{
8
    DDRB |= (1 << PB0);
9

10
    while (1)
11
    {
12
        uint8_t i;
13
        for (i=0; i < 100; i++)
14
            _delay_ms (10);
15
            
16
        PORTB ^= (1 << PB0);    
17
    }
18
}
Angehängte Dateien:
#1095078
Lesenswert?

Hi,

hab mit dem Ding schon alles mögliche gemacht(USART, Timer, blinkende 
LEDs).
Es ist ein 20 Mhz Quarz drann der soweit auch tut. (F_CPU ist auf 
20000000 und die warte-funktionen dauern so lang wies sein soll).
Hab jetzt auch mal alle möglichen Spannungen an AIN0 und AIN1 angelegt 
und geändert. Ich bin der Meinung mein Controller hat da ne Macke, werd 
mal bei gelgenheit einen anderen ausprobieren.

Aber danke für die Hilfe

Moritz

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren