- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: ADC Probleme

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119

    ADC Probleme

    Anzeige

    Praxistest und DIY Projekte
    Hallo, ich hab folgende Funktion geschrieben um von einem PIN von Port a den ADC Wert zu erhalten, aber ich erhalte komischer weise auch wenn nix dran ist werte um ca 486, aber warum ????

    Code:
    int getADC(uint8_t pin)
    {
    	int adc_value = 0;
    	
    	ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Prescalar 8 
     
    	ADMUX = pin;
    	ADMUX |= (1<<REFS1) | (1<<REFS0); // use internal voltage
    	ADCSRA |= (1<<ADSC);
    
    	while (!(ADCSRA & (1<<ADIF)));	// wait for finish converting ADIF bit
    	adc_value = ADCW; 	  // read result 
    	ADCSRA = (1<<ADIF);	// delete ADIF, cause it could trigger ISR	
    		
    	ADCSRA &= (1<<ADEN);		// deactivating ADC
    	return adc_value;			// return result
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    41
    Beiträge
    1.780
    heisst "nix dran" dass der Pin in der Luft hängt, oder liegt er auf Masse?

    wenn er auf Masse liegt stimmt was nicht, denn dann sollte der Wert 0 sein
    (mal abgesehen von minimalsten Abweichungen)


    In der Funktion habe ich jetzt auf den ersten Blick keine groben Fehler gefunden, die müsste eigentlich funktionieren.
    (allerdings würde ich empfehlen einen Interrupt zu benutzen, dann ist der µC beim Warten auf das Messergebnis nicht komplett blockiert)
    So viele Treppen und so wenig Zeit!

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119
    Hallo Felix,
    ich habe an Porta.1 eine 5 Taster in einer Widerstandskombination, wenn keiner gedrückt ist, dann liegt 0 (Masse) an diesem an, wenn ein Taster gedrück wird eine Spannung an den Port gelegt.

    An was könnte es liegen und wie meinst du das mit den Interrupts?

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119
    Hi, hab noch mal alles überprüft, und ich hatte leider nen peinlichen Flüchtigkeitsfehler gemacht, denn Porta1 ist nicht gleich pin1 an port a
    Sorry!!!

    Aber dennoch ist es komisch das der niedrigste Wert = 130 ist, kann das sein ?

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    diese beiden Zeilen machen nicht das wie es gemeint war:
    Code:
       ADCSRA = (1<<ADIF);   // delete ADIF, cause it could trigger ISR   
          
       ADCSRA &= (1<<ADEN);      // deactivating ADC
    die erste Zuweisung löscht alle anderen Bits,
    sodass die 2. eigentlich nix mehr zu tun hat.

    Dann würde ich nicht jedesmal den ganzen ADC deaktivieren, dann gehts beim 2. mal etwas schneller.

    Wie schnell Taktet der AVR, hast Du den Prescaler richtig berechnet?
    Wie ist der ADC extern beschaltet, also AVCC/VRef usw. bei interner Ref muss da aussen was mit Kondensator anders sein ?
    Welchen Wert übergibts Du der Funktion bei pin ?
    Welchen AVR hast Du ?

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119
    Hallo Linux_80,

    also ich hab einen Mega32..
    Berechnung des Prescaler, gute Frage ich hab 8 benutzt,
    wenn ich den Prescaler auf 128 setze nix mehr passiert, erhängt einfach, aber ich hab keine Ahnung wo

    Prescalar auf 8
    Code:
    ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
    und Prescaler auf 128
    Code:
    ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
    laut meiner berechnung müsste er ja min bei 80 und max bei 320 liegen mit 16 Mhz aber warum funktioniert er nur bei Prescaler 8 ?

    mit pin übergebe ich an welchen pin gemessen werden soll...

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119
    Hallo, hab jetzt auch das Problem mit dem Prescaler gefunden ... wieder einer der vielen Flüchtigkeitsfehler... denn da fehlte : (1<<ADEN) , nun funktioniert es

    Danke \/

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    41
    Beiträge
    1.780
    Zitat Zitat von alecs
    wie meinst du das mit den Interrupts?
    Naja...
    momentan startet deine Funktion den ADC, wartet dann bis er endlich fertig ist und liefert schliesslich das Ergebnis zurück.
    In der Zeit in der der µC auf den ADC wartet könnte er eigentlich noch eine Menge anderer Dinge tun,
    aber so ist er gezwungen für eine recht lange Zeit einfach garnichts zu machen.


    Ein Interrupt tut genau das was der Name besagt: er unterbricht das Programm
    d.h. sobald ein bestimmtes Ereignis auftritt, wird das Programm an der momentanen Stelle unterbrochen,
    und eine bestimmte Funktion (ISR - Interrupt Service Routine) ausgeführt.
    Sobald diese Funktion fertig ist, läuft das Programm an der alten Stelle weiter.

    Der ADC kann einen Interrupt auslösen wenn er mit einer Wandlung fertig ist.
    In der passenden ISR kann man dann z.B. den Wert in irgendeiner Variable speichern
    (ISRs sollten möglichst kurz sein, aufwändige Berechnungen haben da nichts zu suchen).


    Anstatt also den µC während der Wartezeit komplett zu blockieren, wird das Programm nur ganz kurz unterbrochen wenn wirklich ein neuer Wert da ist.
    So viele Treppen und so wenig Zeit!

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hi alecs,
    der Prescaler ist abhängig von der Geschwindigkeit des µC, bei Dir 16MHz,
    der Wert soll aber unter 200kHz sein, also geht bei 16MHz nur Teiler 128, das ergibt 125kHz.

    Um gleich die Sache mit dem Interrrupt aufzugreifen, eine AD-Wandlung dauert 13 Takte des ADC, also 13*128 Takte des µC,
    in dieser Zeit könnte man im günstigsten Fall 1664 Befehle ausführen (bei 16MHz).

    Edit:
    Mit Befehle meine ich Assemblerbefehle.

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.09.2004
    Beiträge
    119
    Was Interrupts tun, ist mir so weit eigentlich bewusst, nur im Moment wüßte ich nicht was der µC in dem Moment wo er auf das Ergebnis des ADC wartet noch erledigen könnte, denn ich benutze den ADC um meine Taster und 3 IR Sensoren auszuwerten. Könntet ihr mir da nen bisl unter die Arme greifen, wie man es besser machen könnte ?

    Danke !!!

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen