-         

Ergebnis 1 bis 2 von 2

Thema: ADC am Atmel Evaluation board

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

    ADC am Atmel Evaluation board

    Anzeige

    Hallo,

    ich hab mir vor einiger Zeit das Atmel Evaluationboard von Pollin gekauft und mich jetzt mal mit dem ADC des Atmgega32 beschäftigt. Zum Messen und Ausgeben kam folgender Code zum Einsatz. (Man einer bemekrt vielleicht, dass ich den Code aus Beispielen zusammengeschustert habe)

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    
    // Sollte schon im Makefile definiert sein.
    // In dem Fall hier einfach löschen.
    #define F_CPU       16000000L
    
    #define BAUD        19200UL
    #define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)
    
    void uart_init(void)
    {
        // Baudrate einstellen (Normaler Modus)
        UBRRH = (unsigned char) (UBRR_BAUD>>8);
        UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
    
        // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
        UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
        // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
        UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }
    
    void uart_send(char c) {
    	while ( !( UCSRA & (1<<UDRE)) );
        UDR = c;
    }
    
    void uart_send(char *s){
    	while (*s)
    	{   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    		uart_send(*s);
       	    s++;
        }
    }
    
    uint16_t ReadChannel(uint8_t mux)
    {
      uint8_t i;
      uint16_t result;
     
      ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
                                   // setzen auf 8 (1) und ADC aktivieren (1)
     
      ADMUX = mux;                      // Kanal waehlen
      ADMUX |= (0<<REFS1) | (1<<REFS0); // VCC als Referenzspannung nutzen 
     
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
         also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
      ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
      while ( ADCSRA & (1<<ADSC) ) {
         ;     // auf Abschluss der Konvertierung warten 
      }
      result = ADCW;  // ADCW muss einmal gelesen werden,
                      // sonst wird Ergebnis der nächsten Wandlung
                      // nicht übernommen.
     
      /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
      result = 0; 
      for( i=0; i<4; i++ )
      {
        ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
        while ( ADCSRA & (1<<ADSC) ) {
          ;   // auf Abschluss der Konvertierung warten
        }
        result += ADCW;		    // Wandlungsergebnisse aufaddieren
      }
      ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
     
      result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
     
      return result;
    }
    
    int main(void)
    {
        // USART initialisieren
        uart_init();
    
        sei();
    
        // Nichts tun. Die Interrupts erledigten den Rest
        
        uint32_t i = 0;
    	while (1) {
    		i = 0;
    		while (i < 100000) i++;
    		uint16_t adcval;
     
     		adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
    		char c[10];
    		itoa(adcval, c, 10);
    		uart_send(c);
    		uart_send("\n\r");
    	}
    }
    Nach dem Programmieren hab ich das ganze erst einmal unbeschaltet ausprobiert, das heißt an dem 40poligen Kabel, an dem die ganzen Ports herausgeführt sind war nichts dran gesteckt. Auffällig war ertwmal ein starkes Rauschen um den Wert 500. Sobald ich das Kabel dann mit in meinen Breadboard Adapter eingesteckt hate und ein loses Kabel mit Verbindung zum ADC port 0 mit meinen Fingern berührt habe, gab es plötzlich seltsame Schwingungnen. Nach der anfänglichen Überraschung(Ich wollte schn meinen Herzschlag dafür verantwortlich machen) hab ich dann entdeckt, dass das ganze auch mit größeren Metallansammlungen funktioniert(zange, langes Kabel, Metalltisch). Die Schwingungen sahen etwa so aus:

    • 736
      1023
      1023
      648
      27
      0
      11
      127
      672
      1023
      1023
      707
      72
      3
      13
      90
      517
      1023
      1023
      871
      289
      3
      9


    Mit etwas Rechnerei habe ich dann eine Schwingungsfrequenz von 49,987 Hz ausgetrechnet, das erinnert auch mich Elektronik Anfänger an die 50 Hz NNetzfrequenz. Ich hab dann mal den ADC pin über 5,6 Mohm (10 Widerstände hntereinander, soviele wie ich gefunden habe) mit VCC verbunden, da gab es dann gleich den Messswert 1023.

    Wie kommt das, dass der ADC auf so geringe Einflüsse schon anspricht? Hab ich das Prinzip des ADC vielleicht falsch verstanden? Ein Aanalog Digital Wandler wandelt doch schließlich Spannungen in Messwerte um, oder?

    Mr. Serious
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken atmeva.gif  

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Der ADC Eingang ist sehr hochohmig, laut Datenblatt ca. 100 MOhm (eher als Größenordnung zu verstehen). Wenn man eine Signalquelle / einen Sensor anschließt, wird das ganze schon viel niederohmiger und damit weniger empfindlich gegen Störungen.
    Wie schon richtg erkannt sind die Stärungen die Netzfrequenz. Die werden Kappatzitive von irgentwelchen 230 V Kabeln oder Geräten eingekoppelt.

Berechtigungen

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