www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Analog Digital Converter ATMega8 mit Interrupt betreiben


Autor: Christian W. (christian_w)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

nachdem jetzt der ADC tadellos funktioniert, möchte ich nun die 
"einfache" ADC-Wandlung in ein Interruptgesteuertes Ereignis umbauen.

Funktioniert nur noch nicht so ganz.

Es soll ein Lauflicht aus 4 LEDs werden, je nachdem ob das Poti auf 0 V 
oder auf 5 V ist, soll die Laufgeschwindigkeit schneller oder langsamer 
sein.

Irgendwas stimmt aber mit meinem ISR-Abschnitt noch nicht.

Oder liegt der Fehler woanders?

Kann mal bitte jemand kurz drübersehen? Wenn ich es richtig deute, 
bleibt die Variable "result" ständig auf Null.

Christian

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht nicht
      PORTD |= (1<<PD0); _delay_ms(result); PORTD &= ~(1<<PD0);

_delay_ms kann man nicht mit Variablen benutzen.
D.h. man kann schon. Nur stimmen die Zeiten nicht
void my_delay_ms( uint16_t value )
{
  while( value ) {
    _delay_ms( 1 );
    value--;
  }
}

....

      PORTD |= (1<<PD0); my_delay_ms(result); PORTD &= ~(1<<PD0);




ISR(ADC_vect) 
{
  char sreg=SREG; // Interrupt Status auslesen

  cli(); // Interrupts aus
  
  // Ergebnis der Konvertierung auslesen
    result = ADCW;
  
  SREG=sreg; // Interrupt Status zurückschreiben
}

Lass das SREG in Ruhe. Das ist ein Register, das geht dich nichts an!
cli brauchst du nicht innerhalb einer ISR. In einer iSR sind Interrupts 
automatisch aus.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>_delay_ms(result);

Blödsinn Nummer 1:
_delay_ms(); arbeitet nur mit Konstanten Werten.

Für variable delays bau dir eine Routine ala:

void MyDelayMs(uint16_t delay)
{
 while(delay--) _delay_ms(1);
}

Blödsinn Nummer 2:

cli(); in einem Interrupt macht keinen Sinn

ISR(ADC_vect)
{
  // Ergebnis der Konvertierung auslesen
    result = ADCW;
}

Ach wie schön klein ist diese Interruptroutine jetzt;)
Und funktioniert ohne das ganze Geraffel das von einem
unglaublichen Halbwissen zu stammen scheint.

Autor: Christian W. (christian_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger, spar dir diese saublöde Anmache, bitte.

Wenn du dich über "Geraffel" und "Halbwissen" beschwerst, dann macht 
vielleicht mal dieses Forum dicht, schließlich ist es dafür da, Fragen 
von Personen zu beantworten die sich nicht so gut auskennen (Ich).

Da kann ich sonst auch genausogut meine Glaskugel zu Hause fragen, die 
gibt mir bestimmt keine so dummen Kommentare als Antwort.

Falls jemand noch konstruktive Vorschläge hat, die mir wirklich 
weiterhelfen, ich bin ganz Ohr. Danke.

Die besagten Vorschläge von vorhin brachten übrigens keine Besserung im 
Programmablauf. Trotzdem Danke.

Christian

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Vielleicht bin ich blind, aber ich sehe keine Zeile, in der du den ADC 
startest.

MfG Spess

Autor: Christian W. (christian_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier:
// ADC aktivieren und Teilungsfaktor auf 8 stellen
ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);

und hier:
// ADC Dauerfeuer (Endlosschleifenbetrieb) einschalten
ADCSRA |= (1<<ADFR);

:)

Oder? Geht doch so?

Christian

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Oder? Geht doch so?

Nein. Der Free Running Mode muss durch setzen von ADSC in ADCSRA 
gestartet werden.

MfG Spess

Autor: Christian W. (christian_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jawoll, perfekt, genau das wars. Danke Spess.

Hab die Zeile noch hinzugefügt, jetzt gehts!
// Free Running Mode aktivieren durch erste Messung
ADCSRA |= (1<<ADSC);

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@christian_w

>holger, spar dir diese saublöde Anmache, bitte.

Mach ich. Ich merk mir auch deinen Namen.

Autor: Christian W. (christian_w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mach ich.

Danke :-)

Christian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.