-         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 30

Thema: Dieses Mal: ADC-Probleme

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    33
    Beiträge
    199

    Dieses Mal: ADC-Probleme

    Anzeige

    Moin Izaseba und die anderen
    Ich hab mal wieder ein Problem (was auch sonst).
    Ich hab mir jetzt endlich mal den ADC vorgenommen.
    Wenn ich brennen will, kommen 2 Fehlermeldungen:
    main.c:19: error: called object is not a function
    main.c:32:4: warning: no newline at end of file

    und hier ist mein Code:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
      {
      DDRC |= (1<<PC0);
      uint8_t x;
      
      ADCSRA = (1<<ADEN); 	//Damit ist der Converter gestartet
      ADCSRA = (1<<ADSC); 	//hiermit wird die Messung initialisiert und gestartet
      ADCSRA = (1<<ADATE);	//hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser
    						//(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data-
    						//Register gespeichert
      ADCSRA = ((1<<ADPS0) | (1<<ADPS1)) 	//Hier wird dem ADC Prescaler ein teilungsfaktor von 8
    										//gegeben, das bedeutet es ist dem ADC eine frequenz von
    										//1.000.000 durch 8 also 125kHz im Tutorial steht das der
    										//ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll
      ADMUX = PA0;  //hier is C:19
      
      while(1)
        {
    	x = ADCW;	//hier wird das ADC-Register ausgelesen
    	
    	if (x >= 128)	//wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
    					//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF 
    					//(hier 2,5V) überschreitet
    	  {
    	  PORTC |= (1<<PC0);
    	  }
        }
      }  //hier ist c:23:4
    Ich möchte eigentlich erreichen, das der ADC eingang die ganze Zeit ausgelesen wird und es soll eine LED eingeschaltet werden sobald die Spannung 2,5V übersteigt bzw. erreicht.
    Bis bald,
    MfG Jan

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    32
    Beiträge
    4.255
    Der übliche Tippfehler: Semikolon fehlt nach ADCSRA = ((1<<ADPS0) | (1<<ADPS1))

    (generell sollte man bei allen Fehlermeldungen, die man nicht versteht, erst einmal rund um die beanstandete Stelle nach Tippfehlen suchen sowie Klammern und Semikolons prüfen.)

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    33
    Beiträge
    199
    Oh, das ist mir jetzt ein bisschen peinlich.
    Ich hab das jetzt geändert, aber wenn ich an PA0 die Spannung erhöhe, tut sich nix. Bin bis auf 5V gegangen. Hab an AREF und AVCC 5V gelegt (einfach von VCC gebrückt), soll ja nicht besonders genau sein, will ja nur mal die funktion sehen, is das den von der Grundstruktur und so richtig?
    Gruß Jan

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    Hallo Jan,
    irgendwie fühle ich mich schuld, weil ich Dir irgendwann mal erzählt habe Du solltest an der einen oder anderen Stelle den oder | Operator weglassen
    Sollte aber heißen nicht immer weglassen!
    Ich habe jetzt keine Lust hier wieder ein C Grundkurs zu machen, weil mir die Augen zufallen, ich kopiere einfach nur die wichtigsten Zeilen aus Deinem Programm, und Du überlegst was da faul ist
    Code:
     ADCSRA = (1<<ADEN);    //Damit ist der Converter gestartet 
      ADCSRA = (1<<ADSC);    //hiermit wird die Messung initialisiert und gestartet 
      ADCSRA = (1<<ADATE);   //hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser 
                      //(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data- 
                      //Register gespeichert 
      ADCSRA = ((1<<ADPS0) | (1<<ADPS1))    //Hier wird dem ADC Prescaler ein teilungsfaktor von 8 
                                  //gegeben, das bedeutet es ist dem ADC eine frequenz von 
                                  //1.000.000 durch 8 also 125kHz im Tutorial steht das der 
                                  //ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll 
      ADMUX = PA0;  //hier is C:19
    Die letzte Zeile bei Admux, bin mir jetzt nicht sicher, was da für die 2.56V Ref gesetzt werden muß.
    PA0 könnte durch ein Zufall passen, die Bits heißen da aber anders

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    33
    Beiträge
    199
    Ne, bist nicht schuld dran, war wohl vorhin bloß ein bisschen hektisch und überstürtzt. Mit dem ADMUX wollte ich nicht die interne Referenzspannung einschalten, sondern festlegen das der PA0 der genutzte Analogeingang ist, oder macht man das anders? Das ist in dem Tutorial über WinAVR so komisch beschrieben.
    MfG Jan

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    33
    Beiträge
    199
    Moin!!!
    Ich hab das jetzt geändert und zusätzlich noch einen else zweig gemacht. Also so:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
      {
      DDRC |= (1<<PC0);
      uint8_t x;
      
      ADCSRA |= (1<<ADEN); 	//Damit ist der Converter gestartet
      ADCSRA |= (1<<ADSC); 	//hiermit wird die Messung initialisiert und gestartet
      ADCSRA |= (1<<ADATE);	//hier wird auf freilaufmodus geschaltet da im SFIOR-Register kein Auslöser
    						//(Trigger) eingestellt ist die Daten werden von jetzt an im ADC-Data-
    						//Register gespeichert
      ADCSRA |= ((1<<ADPS0) | (1<<ADPS1)); 	//Hier wird dem ADC Prescaler ein teilungsfaktor von 8
    										//gegeben, das bedeutet es ist dem ADC eine frequenz von
    										//1.000.000 durch 8 also 125kHz im Tutorial steht das der
    										//ADC eine Frequenz von 50 bis 200 kHz gegeben haben soll
      ADMUX |= (1<<REFS0);
    
      ADMUX = PA0;
      
      while(1)
        {
    	x = ADCW;	//hier wird das ADC-Register ausgelesen
    	
    	if (x >= 255)	//wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
    					//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF
    					//(hier 2,5V) überschreitet
    	  {
    	  PORTC |= (1<<PC0);
    	  }
    	else
    	  {
    	  PORTC &= ~(1<<PC0);
    	  }
        }
      }
    Irgendwie ist es egal ob ich if (x >=10) oder if (x >= 200) eingebe.
    sobald ich die spannung auf ca. 1V aufdrehe, geht die LED an, aber sie geht auch nicht wieder aus wenn ich die Spannung wieder senke.

    Der ADC is ja ganzschön kompliziert.

    MfG Jan

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    55
    Beiträge
    5.789
    Blog-Einträge
    8
    Hallo

    Ich bin auch noch ADC-Anfänger, aber so würde ich das nicht machen:

    ADCSRA |= (1<<ADEN); //Damit ist der Converter gestartet
    ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet
    Bei der ersten Zuweisung sollte man nur = verwenden um alle alten Bits im Controllregister zu löschen. Auf dieser Basis kann man dann alles weitere verodern. Oder Zuweisung mit = als Einzeiler.

    ADSC würde ich als letztes setzen wenn alles andere erledigt ist. SFIOR würde ich zur Sicherheit extra auf free-runnig setzen.


    ADMUX |= (1<<REFS0);

    ADMUX = PA0;
    Setzt erst zusätzlich das REFS0-Bit und löscht dann ADMUX komplett mit = PA0 ( PA0 entspricht 0!)

    So wäre besser:

    ADMUX = (1<<REFS0) | (0<<REFS1); // Spannungsreferenz AVCC

    ADMUX |= (0<<ADLAR) // zusätzlich Ergebniss rechtsbündig
    ADMUX |= PA0; // zusätzlich Kanal wählen
    Bei dieser Spannungsreferenz muss an AREF ein Kondensator gegen GND geschaltet werden (10nF beim RP6-AtMega32). Genauer wäre vermutlich die Verwendung der internen 2,56V-Referenz, allerdings braucht man dann auch einen Kondensator. Und einen Spannungsteiler für die 5V-Eingangsspannung. Die Eingangsspannung darf nie größer als die Referenz sein!

    uint8_t x;
    X sollte ein 16-Bit-Wert sein.

    Der ADC is ja ganzschön kompliziert.
    Reine Übungssache. Ich hoffe, ich habe das meiste gefunden. ADC macht Spass!
    Bei mir war übrigends dies hier die Initialzündung: A V R -Tutorial

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    Hallo Radbruch, danke, daß Du hier zur Hilfe eilst
    Bei der ersten Zuweisung sollte man nur = verwenden um alle alten Bits im Controllregister zu löschen. Auf dieser Basis kann man dann alles weitere verodern. Oder Zuweisung mit = als Einzeiler.
    Jep, das habe ich schon dem Spongebob85, leider hat er es falsch verstanden und alle | weggelassen, jetzt weißt es hoffich doch bescheid.

    ADMUX = PA0;
    Das ist unsinn und funktioniert nur durch einen Zufall.
    Die Bits in ADMUX heißen u.a. MUX* und ergeben eine Maske für den Kanal, und nicht direkt die Pinnummer(sehe Dattenblatt)
    Außerdem beschreiben REFS0 und REFS1 die Referenzspannung,(das hast Du schon gesagt)
    Warum willst Du ADLAR setzen ?
    das ist interessant wenn einem 8 Bit ausreichen, dann kann man ja ADCL unter den Tisch fallen lassen und ADCH nehmen, aber bei 10 Bit stehen die Bits schon an der richtigen Stelle
    Ob Freilauf, oder nicht, muß man je nach Anwendung entscheiden.

    ADC ist aber nicht so richtig kompliziert, es gibt schlimmere Sachen

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  9. #9
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    55
    Beiträge
    5.789
    Blog-Einträge
    8
    Hallo

    Naja, er hat's eben genau nach Anleitung gemacht: "Die = durch |= ersetzen" *gg*

    Das mit der Datenausrichtung war eh Quatsch. Nach

    ADMUX = (1<<REFS0) | (0<<REFS1);
    ist das ADLAR-Bit eh nicht gesetzt, denn Default ist ja "rechtsbündig".

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    33
    Beiträge
    199
    Das mit den = und den |= hab ich jetzt denke ich verstanden.
    Tut mir leid wenn ich eich bisschen bratzig rüberkomme, aber wartet mal erst ab wenn ich irgendwas mit zeiten und interrups machen will. Das hab ich nämlich als nächstes vor
    Naja, ich werde mal das Programm ändern und mich dann wieder melden,
    dankeschön erstmal für alles.

    Gruß Jan

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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