mikrocontroller.net

Forum: Compiler & IDEs analog comparator erkennt keine veränderte flanke


Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich hab an meinem ATMega168 an ADC1 3,2 V angelegt und ADC0 auf masse 
gelegt.


#include <avr/io.h>
#include <avr/interrupt.h>
ISR(ANALOG_COMP_vect)
{
  PORTB = 0x00;
}


int main(void)
{
  DDRB = 0xff;
  PORTB = 0xff;
  ACSR |= (1<<ACIE) | (1<<ACIS1);
  sei();
  for(;;);
  return 0;
}
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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Tabelle 21-2 im Datenblatt muß man die Richtungserkennung der 
Flanke  umschalten.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht 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:
Table 22-2.
ACIS1
0
0
1
1
ACIS0
0
1
0
1
Interrupt Mode
Comparator Interrupt on Output Toggle.
Reserved
Comparator Interrupt on Falling Output Edge.
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.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der AC liegt beim ATmega*8 an Port D6 (AIN0) und D7 (AIN1). Teilweise 
kann man andere Pins verwenden, wenn der ADC inaktiv ist und men den 
ADC-Input-Multiplexer entsprechend nutzt. ADC0-ADC5, womöglich auch ADC6 
und ADC7.

Bit ACME in ADCSRB.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber nach meinem Sourcecode muss ich doch einfach an Port D6 (AIN0) und 
D7 (AIN1) anlegen oder?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, aber oben schriebst du was von ADC0 (Port C0) und ADC1 (Port C1)

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Stimmt, mein Fehler sorry. Habs aber an AIN0 und AIN1 angeschlossen.
Muss DDRD eigentlich irgendwie gesetzt sein?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
   ASCR = (1 << ACIE) | (1 << ACIS1);
   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.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(ANALOG_COMP_vect)
{
  PORTB = 0x00;
}


int main(void)
{
  DDRB = 0xff;
  PORTB = 0xff;
  ACSR = (1 << ACIE);
  ACSR = (1 << ACIE) | (1 << ACIS1) | (1 << ACI);
  sei();

  /* neverending loop */
  for(;;);
  return 0;
}
Soweit mein momentaner Code: Bringt nichts, PORTB bleibt an.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das ist nicht was ich oben schrieb.

Das IRQ-Flag nmuss nach Ändern der Flankensensitivität resettet 
werden.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also im Interrupt?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Initialisieren entweder
   ASCR = (1 << ACIE) | (1 << ACIS1);
   ASCR = (1 << ACIE) | (1 << ACIS1) | (1 << ACI);

oder
   ASCR = (1 << ACIE);
   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.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(ANALOG_COMP_vect)
{
  PORTB = 0x00;
}


int main(void)
{
  DDRB = 0xff;
  PORTB = 0xff;
  ACSR = (1 << ACIE);
  ACSR = (1 << ACIE) | (1 << ACI);
  sei();

  /* neverending loop */
  for(;;);
  return 0;
}
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?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Hab noch nie was mit Fuse-Bits gemacht. Ich les mich mal kurz ein, was 
falsch gesetzt sein könnte.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(ANALOG_COMP_vect)
{
  PORTB &= ~(1 << PB1);
}

int main(void)
{
  DDRB  = (1 << PB1) | (1 << PB0);
  PORTB |= (1 << PB1);

  ACSR = (1 << ACIE);
  ACSR = (1 << ACIE) | (1 << ACI);

  sei();

  while (1)
  {
      if (ACSR & (1 << ACO))
         PORTB |= (1 << PB0);
      else
         PORTB &= ~(1 << PB0);
  }
}

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...

Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht 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=ATm...

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

Spannungsversorgung ist konstant bei 4,87V.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)
#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB |= (1 << PB0);

    while (1)
    {
        uint8_t i;
        for (i=0; i < 100; i++)
            _delay_ms (10);
            
        PORTB ^= (1 << PB0);    
    }
}


Autor: Moritz Sch (mollitz)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.