- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 6 von 6

Thema: ATMEGA2560 ADC-Kanäle lesen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.11.2004
    Beiträge
    123

    ATMEGA2560 ADC-Kanäle lesen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    ich bastle gerade mit dem RN-Atmega2560 herum, bekomme es aber nicht hin die ADC Kanäle auszulesen, habe etwas Angst da einfach so was rumzuprogrammieren damit das ding nicht den Geist auf gibt.

    Ich verwende folgende Funktion zum auslesen (hat bei einemATMEGA8 funktioniert).

    Die Zeilen im Code wo die Fragezeichen dahinter stehen, hab ich selbst hinzugefügt. (im Datenblatt gefunden).

    Die Funktion gibt jedoch immer den konstanten Wert 510 komischerweise.

    Wäre toll wenn jemand hilft.


    Code:
    uint16_t GetAdc(uint8_t pin) {
    
    	// min Prescaler = µC Frequ / 200 KHz & max Prescaler = µC Freq. / 50 khz = min 80 & max 320
    	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); 				 		// Prescalar = 128
    	ADCSRB = (1<<ACME); //??????????
       DIDR0=0x03; //?????????
    	
       uint8_t i;
       uint8_t ii;
       uint16_t result;
       uint16_t ergebnis;
       ergebnis = 0;
       //    +------------ Dummy-Check ------------+
       i = 5;                              // i x Dummy-Check
       while(i){
          ADMUX = pin;                      	// Kanal waehlen
          ADCSRA |= (1<<ADSC);               // eine Wandlung "single conversion"
          while(!(ADCSRA & (1<<ADIF)));     // auf Abschluss der Konvertierung warten (ADIF-bit)
          result = ADCL + (ADCH << 8);       // Wandlungsergebnisse erfassen
          result = 0;                        // Zurücksetzen
          i--;
       }
       //    +------------- Ermittlung ------------+
       i = 10;
       ii = i;                              // Schnitt aus i Ergebnissen
       while(i){
          ADMUX = pin;                        // Kanal waehlen
          ADCSRA |= (1<<ADSC);               // eine Wandlung "single conversion"
          while(!(ADCSRA & (1<<ADIF)));         // auf Abschluss der Konvertierung warten (ADIF-bit)
          result = ADCL + (ADCH << 8);         // Wandlungsergebnisse erfassen
          ergebnis = ergebnis + result;         // Aufaddieren
          i--;
       }
       //    +-------- Umrechnung & Ausgabe -------+
       ergebnis = ergebnis / ii ;
       return ergebnis;
    }

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    Also was auf jeden fall besser wäre, wär wenn du "ergebnis = ADC" schreibst da das auselsen von 16bi registern nicht so einfach ist.

    while(i){ ... wird nie gehen. sondern: ist auch eleganter
    while((i--)>0) {
    ...
    }
    ich machs anders.

    ergebnis = ergebnis / ii ; //Enelegant

    (ADIF-bit) //was bedeutet das?
    es reicht eine dummy zum warmlaufen und es reichen 3 wandlungen zum mittelwert bilden. sonst wartest ja so lange bis der wert da ist und dan stimmt er erst wieder nicht.

    So schauts bei mir aus.
    Code:
    /*************************************************
    
    AUTHOR: Thomas Grübler
    Version: 0.1
    Beschreibung: Erfasst werte am ADC Port
    
    Beispielfunkton zum auslesen der Werte:
    void beispiel(void)
    {
      uint16_t adcval;
      adcstart();
      adcval = adcget(0); // MUX-Bits auf 0b0000 -> Channel 0 
      adcval = adcget(2); // MUX-Bits auf 0b0010 -> Channel 2 
      adcstop();
    }
    
    *************************************************/
    
    #include <avr/io.h>
    #include "adc.h"
    #include "usart.h"
    #include "nuetzliches.h"
    #define wandlungen 3
    
    void adcstart(void);
    void adcstop(void);
    uint16_t adcget(uint8_t kanal);
    
    void adcstart(void) {
       ADCSRA |= ((1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2) | (1<<ADEN));//ADPS0-2(Vorteiler 128), ADEN (Enable)
    
       ADMUX = 0;
       ADMUX |= (1<<REFS1) | (1<<REFS0);
       
       ADCSRA |= (1<<ADSC);      // eine ADC-Wandlung als Dummy zum warmlaufen
       while ( ADCSRA & (1<<ADSC) ) {
       ;                    // auf Abschluss der Konvertierung warten
       }
    }
    
    void adcstop(void) {
    	ADCSRA &= ~(1<<ADEN);
    }
    
    uint16_t adcget(uint8_t kanal) {
       uint8_t i = 0;
       uint16_t ergebnis = 0;
    
       ADMUX = kanal;                  // Kanal waehlen
       ADMUX |= (1<<REFS1) | (1<<REFS0);   // interne Referenzspannung nutzen
    
       while (i!=wandlungen) {		//Mehrere wandlungen und durchschnittswert ermitteln
       	ADCSRA |= (1<<ADSC);         // eine Wandlung "single conversion"
       	while ( ADCSRA & (1<<ADSC) ) {
       	;                  // auf Abschluss der Konvertierung warten
    	}
    	i++;
    	ergebnis += ADC;
       }
       ergebnis = ergebnis/wandlungen;	//Durchschnittswert bilden
    
       return ergebnis;
    
    }

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.11.2004
    Beiträge
    123
    Also die Funktion so wie Sie oben steht funktioniert in meinem ATMega32 problemlos.

    Ich habe deine auch mal testweise eingebunden, liefert aber genau das gleiche zurück.

    Beim ATMega2560 muss man warscheinlich noch das ADCSRB und DIDR0 setzen, aber wie ?...

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    Damit kenn ich mich leider nicht aus. da ich bis jetzt nur m16 und m32 benutzte. und mein nächster schritt ein pc sein wird

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.11.2004
    Beiträge
    123
    Kann ich eingendlich die Kabel direkt an die Pins anschliessen oder müssen da noch irgendwelche Kondenstoren oder Widerstände dran?

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    Du kannst sie direkt anschliesen solange sie die referenzspannung nicht übersteigen. und falls du zb nur ein poti hast einen pullup/down widerstand nicht vergessen.
    bei vcc-widerstand-adc wär immer die selbe spannung zu messen.

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress