-
        

Ergebnis 1 bis 5 von 5

Thema: ADC will nicht Kanal umschalten

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    26
    Beiträge
    460

    ADC will nicht Kanal umschalten

    Anzeige

    Hallo!

    Ich schreibe gerade ein Programm, das die Lichtstärke und die Luftfeuchtigkeit misst uns sie auf einem Display anzeigt.

    Es funktioniert problemlos, wenn man nur eine der beiden größen ausliest. Sobald ich aber beide hintereinander auslese und anzeige, funktioniert es aber nichtmehr. Er zeigt dann für beide größen den selben Wert an, den er von einem eingang ermittelt.

    Der verwendete Controller ist ein Mega8 mit 4 Mhz. Die ADC-Pins sind auf Port C. An die ADC-Pins 0 und 1 habe ich je ein Poti angeschlossen.

    Hier ist mein code:
    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <uart.h>
    #include <avr/pgmspace.h>
    
    
    #include <pwm.h>
    #include <lcd.h>
    #include <i2cmaster.h>
    #include <uart.h>
    
    uint16_t adc(uint8_t);
    void lcd_var16(uint16_t);
    
    int main(void)
    {	
    	DDRB |= (1<<1) | (1<<2) | (1<<4);			// B1, B2, B4 auf Ausgang
    
    	DDRC=0x00;
    
    
    	uint16_t lichtstaerke_a;
    	uint16_t feuchtigkeit;
    	
    	lcd_init(LCD_DISP_ON);
    	
    	while(1)	// Beginn der Hauptschleife
    	{		
    	
    			lcd_clrscr();
    			lcd_gotoxy(0,0);
    			lcd_puts("Hallo Welt");
    	
    			
    			lichtstaerke_a = adc(0);
    			lcd_gotoxy(15,0);
    			lcd_var16(lichtstaerke_a);
    
    			
    			feuchtigkeit = adc(1);
    			lcd_gotoxy(15,1);
    			lcd_var16(feuchtigkeit);
    
    			_delay_ms(300);
    	
    				
    	} 		// Ende der Hauptschleife (Endlosschleife)
    
    
    	return 0;
    }
    
    
    //################################################################################################
    
    
    uint16_t adc(uint8_t mux)
    {
      	uint8_t i;
      	uint16_t result;
     
      	ADMUX |= (mux & 0b00000111);   // Kanal waehlen
     
    	ADMUX &= ~(1<<REFS0);
     	ADMUX |=(1<<REFS1);
    	
    
    	//Frequenzvorteiler setzen auf 32 und ADC aktivieren
    
      	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);
    	ADCSRA &=~ (1<<ADPS1);
          
      	// Dummy-readout
      	ADCSRA |= (1<<ADSC);              	// eine ADC-Wandlung 
      	while ( ADCSRA & (1<<ADSC) )
      	{	;     				// auf Abschluss der Konvertierung warten 
      	}
    	
    	result = ADCW;  	
     
    	//----------------------------------------------------------------------------
    	
    	// Eigentliche Messung - Mittelwert aus 2 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
     
      	result /= 4;                		// Summe durch 10 teilen = arithm. Mittelwert
     
      return result;
    }
    
    
    //################################################################################################
    
    
    void lcd_var16(uint16_t var)
    {	
    	char buffer[5];			// array für Zeichen definieren
    	uint8_t i;	
    
    	for(i=0; i<5; i++)
    	{	buffer[i]=0;
    	}
    
    	itoa(var, buffer, 10);		// int in einen String umwandeln (zur Basis 10 -> dezimal)
    	
    	lcd_puts(buffer);			// char ausgeben
    
    }
    An der Ausgabe am Display und der umwandlung ing->string kann es nicht liegen, wenn ich nämlich statt adc(0); und adc(1); zwei zahlen hinschreibe, stehen auch die richtigen zahlen am Display.

    Mir ist außerdem aufgefallen, dass nach einem reset ganz kurz die beiden richtigen werte am display aufblitzen, danach nimmt der zweite wert aber automatisch den wert des anderen adc wertes an und beide haben den selben wert...

    Kann es sein dass man bei der Umschaltung zwischen den ADC Kanälen irgendetwas beachten muss?

    lg Christoph

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.07.2009
    Ort
    Wien
    Beiträge
    131
    du setzt REFS1:0 auf 10, und das ist lt datenblatt "reserved"...

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    26
    Beiträge
    460
    aja an der referenzspannung hab ich rumexperimentiert... vorher hatte ich sie auf 0:0, jetzt habe ich 0:1 probiert, hat auch nicht geklappt...

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Müsste man nicht erst den alten Kanal zurücksetzen?

    ADMUX &= ~0b00000111; // alten Kanal loeschen
    ADMUX |= (mux & 0b00000111); // Kanal waehlen

    Nachdem Kanal 1 gewählt wurde wird sonst Bit0 in ADMUX nie mehr gelöscht.

    Gruß

    mic

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

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    25.03.2006
    Ort
    nahe Tulln (Niederösterreich)
    Alter
    26
    Beiträge
    460
    juhuuu super danke das wars!!!

    Danke!!!

    lg Christoph

Berechtigungen

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