-         

Ergebnis 1 bis 4 von 4

Thema: ADC-Interrupt springt nicht an

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    23
    Beiträge
    449

    ADC-Interrupt springt nicht an

    Anzeige

    Hallo zusammen,

    ich mache im Moment etwas mit vielen Timern und Interrupts. Der Overflow-Interrupt funktioniert auch, Code:
    Code:
    ISR(TIMER1_OVF_vect)              // Timer1 Überlauf
    {
        TCNT1 = 64202;                   //64202 vorladen
        POS_LED_TOGGLE ();
    }
    Das "POS_LED_TOGGLE ();" kann ich wunderbar auf dem Oszi sehen, die Zeiten stimmen auch (83µs)

    Jetzt soll der ADC bei jedem Überlauf gestartet/getriggert werden und wenn er fertig ist soll er einen Interrupt auslösen:
    Code:
    void POS_LDR_INIT (void)
    {
        ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIF);    // ADC enable + triggern enable + interrupt wenn fertig
        SFIOR |= (1 << ADTS2) | (1 << ADTS1);                // triggern bei timer1 überlauf
        sei();
    }
    Das LED_TOGGLE hab ich aus dem Timer1-Interrupt rausgeschmissen, dafür hier hinein gepackt:
    Code:
    ISR(ADC_vect)
    {
        POS_LED_TOGGLE ();
    }
    Ich hab aber auf dem Oszi ein dauerhaftes high (<- kommt vom INIT). Nix Rechteck...

    Weis jemand warum? Hab ich irgend ein Register beim ADC vergessen?

    Viele Grüße und vielen Dank schonmal
    -schumi-

    PS: µC = Atmega32, Compiler = AVR-GCC

    EDIT: Hier gibts alle Sources als Zip: http://dl.dropbox.com/u/19005544/RN-ADC-Interrupt.zip

  2. #2
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    Benutz mal diese Zeilen hier um den ADC zu initialisieren
    Code:
    void ADC_Init(void)                             // ADC initalisieren
    {
        ADMUX = (1<<REFS1) | (1<<REFS0);            // Interne Referenzspannung nutzen
          ADCSRA = (1<<ADPS1) | (1<<ADPS0);           // Frequenzvorteiler
        ADCSRA |= (1<<ADEN);                        // ADC aktivieren
        ADCSRA |= (1<<ADSC);                        // Eine ADC-Wandlung 
          
          while (ADCSRA & (1<<ADSC))                     // Warten bis Wandlung abgeschlossen ist
    
        Ergebniss = ADCW;                            // Ergebniss der ersten Wandlung speichern
    }
    Du musst nämlich nachdem initialisieren erstmal eine Wandlung machen um das Register leer zu räumen.
    Und das hier brauchste natürlich auch:

    SREG = (1<<7); // Global Interrupt Enable

    Anschließend setzt du in der Timer-ISR nur noch das Enable Bit von dem ADC und ließt ihn aus.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    23
    Beiträge
    449
    Das ist ja so, wie man es "normal" macht?

    Sprich 1:1 wie du es da schreibst hat es nicht hingehauen, weil der ADC ja nicht weis, dass er bei einem Überlauf von Timer1 starten und wenn er fertig ist selbst einen Interrupt auslösen soll. Ich habe das dann noch dazugefügt (So wies oben steht), hat aber keine Verbesserung gebracht.

    * Die Refferenzspg hatte ich ehrlich gesagt vergessen einzustellen, auf AVCC zu stellen hat aber keine Verbesserung gebracht
    * Frequenzvorteiler hab ich alles auf 0 gelassen (Teiler = 2) weil der ADC verdammt schnell sein muss *g*
    * ADC aktivierung hab ich oben auch
    * Eine ADC-Wandlung machen bringt leider auch keine Verbesserung...
    * "SREG = (1<<7);" (Bzw. "SREG |= (1<<7);") hat auch nichts gebracht... (Ist das nicht das selbe, wie "sei();" ?)

    Anschließend setzt du in der Timer-ISR nur noch das Enable Bit von dem ADC und ließt ihn aus.
    * Ich wollte aber das der ADC selbst startet wenn Timer1 überläuft (Das geht laut Seite 218 vom Datasheet ( http://www.atmicroprog.com/download/atmel/atmega32.pdf ))
    * Der ADC soll nicht abgefragt werden ob er fertig ist, sondern selbst nen Interrupt reinknallen (Es muss alles sehr schnell gehen)


    Das Problem kann ja theoretisch von 2 Stellen kommen:
    * Entweder der ADC startet nicht wenn Timer1 überläuft
    * Oder der ADC löst keinen Interrupt aus wenn er fertig ist...

    Vielen Dank für deine Hilfe :-D
    -schumi-

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    23
    Beiträge
    449
    LÖSUNG:


    JUCHU - Es funzt!!!

    Zitat aus dem Datenblatt:
    Bit 4 – ADIF: ADC Interrupt Flag
    This bit is set when an ADC conversion completes and the Data Registers are updated. The
    ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set.
    ADIF is cleared by hardware when executing the corresponding interrupt handling vector. Alter-
    natively, ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-
    Write on ADCSRA, a pending interrupt can be disabled. This also applies if the SBI and CBI
    instructions are used.
    In den Quellcode mit rein:
    Code:
    void POS_LDR_INIT (void)
    {
        ADMUX |= (1 << REFS0);                                                // AVCC als Refferenz
        ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIF) | (1 << ADIE);    // ADC enable + triggern enable + ISR wenn fertig + enable interrupt 
        SFIOR |= (1 << ADTS2) | (1 << ADTS1);                                // triggern bei timer1 überlauf
        sei();
    }
    Und schon geht es :-D

    (Und zu allem Überfluss schafft es der ADC doch glatt, in weniger als 83µs zu Wandeln -> Angst unbegründet -> PERFEKT :-D )

    Viele Grüße und vielen Dank!
    -schumi-

    PS: Den Sourcen-Download oben habe ich aktualisiert und funzt jetz - Wer abgucken möchte^^
    Geändert von -schumi- (04.10.2011 um 00:18 Uhr)

Ähnliche Themen

  1. AVRStudio springt nicht in die Zeile der Fehlermeldung
    Von manhunt im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 19
    Letzter Beitrag: 03.03.2009, 22:01
  2. Programm "springt" nicht jedesmal an ?
    Von Blamaster im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 30.12.2008, 13:27
  3. Timer0 springt zu früh an
    Von Paisley im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 11.07.2005, 15:43
  4. Atmega8, Fototransistor, ADC springt
    Von prefect im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 27.01.2005, 22:59
  5. ret springt nicht nach rcall befehl
    Von freddy0815 im Forum AVR Hardwarethemen
    Antworten: 9
    Letzter Beitrag: 03.12.2004, 10:13

Berechtigungen

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