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


von Christian W. (christian_w)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


Lesenswert?

Das geht nicht
1
      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
1
void my_delay_ms( uint16_t value )
2
{
3
  while( value ) {
4
    _delay_ms( 1 );
5
    value--;
6
  }
7
}
8
9
....
10
11
      PORTD |= (1<<PD0); my_delay_ms(result); PORTD &= ~(1<<PD0);




1
ISR(ADC_vect) 
2
{
3
  char sreg=SREG; // Interrupt Status auslesen
4
5
  cli(); // Interrupts aus
6
  
7
  // Ergebnis der Konvertierung auslesen
8
    result = ADCW;
9
  
10
  SREG=sreg; // Interrupt Status zurückschreiben
11
}

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.

von holger (Gast)


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.

von Christian W. (christian_w)


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

von Spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von Christian W. (christian_w)


Lesenswert?

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

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

:)

Oder? Geht doch so?

Christian

von Spess53 (Gast)


Lesenswert?

Hi

>Oder? Geht doch so?

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

MfG Spess

von Christian W. (christian_w)


Lesenswert?

Jawoll, perfekt, genau das wars. Danke Spess.

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

von holger (Gast)


Lesenswert?

@christian_w

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

Mach ich. Ich merk mir auch deinen Namen.

von Christian W. (christian_w)


Lesenswert?

> Mach ich.

Danke :-)

Christian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.