-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: Analog Comparator funktioniert nicht

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    24.09.2009
    Beiträge
    10

    Analog Comparator funktioniert nicht

    Anzeige

    Hallo,

    ich bin gerade dabei, den Analog Comparator meines Atmega32 ein zu
    stellen.
    ich habe mit dem Befehl
    ACSR =(1<<ACBG);
    den AIN0 auf innere Referenz (2,56V) umgeschaltet.

    Danach mit
    DDRB =(0<<PB3);
    den AIN1 als Eingang definiert.


    Laut AVR Tutorial würde der AC immer parallel zum Controller mitlaufen,
    man müßte ihn sogar explizit ausschalten wenn man ihn nicht benötigt, um
    Strom zu sparen.
    Damit er AC auch wirklich eingeschaltet ist, sag ich dem ACSR noch:
    ACSR = (0<<ACD);

    Die Allgemeinen Interrupts werden mit
    sei();
    eingeschaltet

    Über einen Spannungsteiler gebe ich nun die Vergleichsspannung auf den
    Eingang AIN1.
    Nun kommt das Problem:

    Egal wie hoch die Vergleichsspannung ist, der AC gibt mir immer auf ACO
    ein High heraus, er sagt also, die innere Referenzspannung sei höher als
    die Vergleichsspannung.
    Selbst wenn die Vergleichsspannung bei +5V liegt, meint der ACO, die
    Referenzspannung sei aber immer noch höher.
    Habe ich irgendetwas vergessen?


    Ich habe da so ein Gerücht gehört, der AC des Atmega32 würde in der DIL
    Version nicht funktionieren? Hat da jemand schon so etwas gehört, oder
    ähnliche Erfahrungen gemacht?

    Grüße von
    Sylvia

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Was auch immer, um wirksam zu sein, muss das heissen
    DDRB &= ~(1<<PB3);

    ACSR &= ~(1<<ACD);

    schaut pervers aus, is aber eben C, um einzelne Bits auf 0 zu setzen
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    24.09.2009
    Beiträge
    10
    Hallo Robert,
    ich habe den Code abgeändert, es funktioniert trotzdem nicht.
    Aber danke für deine Antwort
    Sylvia

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Ich hab mal das Datenblatt angeschaut.

    Folgende Register müssen mit Werten befüllt werden:
    SFIOR
    ACSR

    Wenns über Interrupts Laufen soll müssen diese auch enabled sein - Rätselhaft.

    MCUCR ist auch eine beliebte Fehlerquelle, hat aber soweit ich sehe kein Bit für den Comperator und die Interrupts hast Du mit #asm("sei"); ja auch freigegeben.

    Das die JTAGEN Fuse ist auch ein beliebter Fehler, betrifft aber nur den Port C

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    24.09.2009
    Beiträge
    10
    Ich habe nun mit

    SFIOR &= ~(1<<ACME);

    ACME auf 0 gesetzt, damit laut Datenblatt AIN1 mit dem negativen Eingang des AC verbunden wird, aber.........
    est verändert sich immer noch nichts.
    Das JTAGEN Fuse ist gesetzt,
    bei MCUCR wüsste ich jetzt nicht, was ich setzen soll.
    Grüße von
    Sylvia

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Was ich jetzt nachgelesen habe, sollte sein
    Code:
    ACSR  &= ~(1<<ACD)                  ' comp aktiv
    ACSR  |=    (1<<ACBG)                ' intern. referenz
    SFIOR &= ~(1<<ACME)                ' AIN1 immer als Ref   neg. Input
    
    DDRB   &= ~(1<<PB3);                  ' PB3 als Input
    PORTB &= ~(1<<PB3);                  ' sicherheitshalber Pullup  abschalten. 
                                                       ' kann nicht schaden
    ehrlich gesagt, mehr weiss ich im moment auch nicht
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    24.09.2009
    Beiträge
    10
    Habe den Code genauso geflasht, geht aber immer noch nicht.
    Vielen Dank trotzdem!
    Gruß
    Sylvia

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Ich will mir nicht deinen Zorn zuziehen, aber vielleicht hat's doch was mit deinem Programm.
    Sei doch mal so gut und zeig dein Programm mal her.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    24.09.2009
    Beiträge
    10
    Der Code ist in ein größeres Programm eingebunden,
    prinzipiell sieht er so aus:
    Code:
    /*                    
    * Der ATMEGA 32 wird als Slave konfiguriert, und wartet auf die Anweisungen des Masters.                   *
    * Bekommt er eine 11 geschickt, soll der seine Lämpchen blinken lassen, bei einer 00 soll das Lauflicht    *
    * gestartet werden.  Unterschreitet die Spannung am AC 2,5V, soll aus dem Programm ausgestiegen werden
    */
    
    #include <avr/io.h>
    #ifndef F_CPU
    #define F_CPU 160000000UL
    #endif
    #include <util/delay.h>
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include "outpin.h"         // Lib um Pins ein und aus zu schalten
    #include "i2csylvia.h"  // Lib für die I2C übertragung
    #include <avr/interrupt.h>  // Externe Interrupts
    
    
    
    
    
    outpin_t led2;
    outpin_t led3;
    outpin_t led4;
    outpin_t led5;
    
    uint16_t i;
    
    uint8_t Spannung_weg;  //Variable zur Betriebsspannungs anzeigen
    
    int befehl;
    
    
    
    void lauflicht(void)
    {
    	....Code für ein Lauflicht
    }
    
    
    void blinklicht(int n, int ms)
    {
    	.....Code für Blinklicht
    }
    
    
    
    // den Befehl ausführen
    void takeorder()
    {
    	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);   // Clear TWINT to start tranmission, send ACK to receive mor Bits
    	while (!(TWCR & (1<<TWINT)));            // Wait for TWIN flag is set.This indicates that
    	                                           // Data byte has been received, and ACK/NACK has been returned 
    	befehl = i2cReadData();
    		switch(befehl)
    		{
    			case 11: blinklicht(2,200);   // wird eine 11 geschikt : 2x langsam blinken
    			break;
    			case 00: lauflicht();           // bei einer 00 : 2 x lauflicht
    			break;
    			//default : blinklicht (4,100);   // wird etwas anderes geschickt: schnelles Fehlerblinken
    			break;
    		}										   
    }
    
    int main (void)
    {
    	DDRB &= ~(1<<PB3); // AIN1 als Eingang initialisieren
    	PORTB &=~(1<<PB3); // Sicherheitshalber Pullup abschalten
    	
    	
    	outpin_init(&led2,'A',7);  // Initialisierung der LED`s 2-3 auf Port    Ausgänge 3-7
    	outpin_init(&led3,'A',6);
    	outpin_init(&led4,'A',4);
    	outpin_init(&led5,'A',3);
    	
    	
    	
    	sei(); // set enable interrupt --> global interrupts einschalten
    	
    	i2cinit(16);
    	uart_init();
    	
    	
    	
    	
    	ACSR |= (1<<ACBG);   // AC Auf Interne Referenzspannung (2,56V) umschalten
    	ACSR &= ~(1<<ACD);  // AC explizit einschalten
    	SFIOR &= ~(1<<ACME);  // AIN1 wird mit dem Invertierten Eingang des Comperators verbunden
    	
    	TWAR = 0x40;       // Die Slave Adresse wird auf "64" festgelegt
    	TWCR = (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO);  // Das Senden der Bestätigungsbits (ACK) zulassen,Start und Stop auf 0 setzen
    	TWCR =(1<<TWIE); // Interrupts zulassen
    	blinklicht(3,1000);   // 3x langsam Blinken als optische bestätigung, das der Slave wartet
    	
    while(1)            // In einer Endlosschleife auf die Befehle des Masters warten
    	{
    
    	Spannung_weg = ACO;   // Comperator auslesen, sobald die Spannung am Testwiderstand 2,56V unterschreitet, ist ACO auf High (1)
    		if(Spannung_weg ==1)  //Wenn die Betriebsspannung weg ist, aus dem Programm ausssteigen
    		{
    			blinklicht(1,1000);
    			break;
    		}
    		
    		
    		takeorder();   // Den gesendeten Befehl ausführen	
    	}
    	
    }

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Au weia. Sollte heissen:
    Code:
       Spannung_weg = ACSR & (1<<ACO);   // ACO aus ACSR rausfummeln
       if(Spannung_weg != 0)
       { 
             blinklicht(1,1000);
    Zur Erläuterung:
    ACO hat den festen Wert 5
    Daher ist
    Spannung_weg = 5

    Und
    if (Spannung_weg == 1)

    geht nie auf
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •