Forum: Mikrocontroller und Digitale Elektronik Interrupt Priorität ADC TIMER (ATMEGA8)


von Stefan H. (hohmi)


Lesenswert?

Hallo Community,

Ich möchte den Interrupt des Timer0 zur Entprellung von Tastern 
verwenden (alle 10ms wird ein Interrupt ausgelöst). Über den ADC lese 
ich 4 verschiedene Analoge Werte nacheinander ein, ebenfalls Interrupt 
basierend. Laut Datenblatt des ATMEGA8 ist die Priorität des Timer0 
(0x009) Interrupt höher als die Priorität des ADC (0x00E) Interrupt.

Ich versteh es jetzt so, dass es während einer Wandlung des ADC zu einer 
Unterbrechung durch den Timer0 Interrupt kommen kann.

Die Frage: Meint ihr es ist unbedenklich oder sollte ich lieber während 
jeder Wandlug durch den ADC die Interrupts ausschalten, also ungefähr 
so:
1
// INTERRUPTROUTINE 2 (Analog-/Digitalkonverter)
2
3
ISR (ADC_vect) {
4
cli();
5
  adc = ADCL + 256 * ADCH;// LO/HI - Anteil von ADC einlesen
6
  adc /=4;                // mache aus 10-bit-wert einen 8-bit-wert
7
sei();
8
}

Danke für eure Antworten

mfg
Hohmi

von Peter II (Gast)


Lesenswert?

Stefan H. schrieb:
> Ich versteh es jetzt so, dass es während einer Wandlung des ADC zu einer
> Unterbrechung durch den Timer0 Interrupt kommen kann.

dann versteht du es falsch. Es gibt keien solche Prio. ISR werden nicht 
unterbrochen (außer man lässt es expliziert durch ein sei zu)

von Karl H. (kbuchegg)


Lesenswert?

Stefan H. schrieb:

> Die Frage: Meint ihr es ist unbedenklich oder sollte ich lieber während
> jeder Wandlug durch den ADC die Interrupts ausschalten, also ungefähr
> so:

Dieses "ungefähr so" ist Blödsinn.
Denn wenn die ADC-ISR aufgerufen wird, ist die Wandlung ja schon 
beendet.

Und ein cli() / sei() in einer ISR solltest du dir schleunigst wieder 
abgewöhnen. Das passiert nämlich erstens automatisch und zweitens kannst 
du dir damit Ärger einhandeln, wenn der sei() zum falschen Zeitpunkt 
kommt (und der kommt praktisch immer zum falschen Zeitpunkt wenn du ihn 
selber machst - nämlich zu früh)

von Stefan H. (hohmi)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Stefan H. schrieb:
>
>> Die Frage: Meint ihr es ist unbedenklich oder sollte ich lieber während
>> jeder Wandlug durch den ADC die Interrupts ausschalten, also ungefähr
>> so:
>
> Dieses "ungefähr so" ist Blödsinn.
> Denn wenn die ADC-ISR aufgerufen wird, ist die Wandlung ja schon
> beendet.
>
> Und ein cli() / sei() in einer ISR solltest du dir schleunigst wieder
> abgewöhnen. Das passiert nämlich erstens automatisch und zweitens kannst
> du dir damit Ärger einhandeln, wenn der sei() zum falschen Zeitpunkt
> kommt (und der kommt praktisch immer zum falschen Zeitpunkt wenn du ihn
> selber machst - nämlich zu früh)

stimmt! vor der Wandlung kann ich die Interrupts jedoch auch nicht 
ausschalten, sonst Wandelt er nicht mehr.

Bleibt also nur noch Vor der Wandlung Timer/Timer INterrupt ausschalten 
oder ADC ohne Interrupt.

Danke für eure Hilfe
Hohmi

von Karl H. (kbuchegg)


Lesenswert?

Stefan H. schrieb:

> Bleibt also nur noch Vor der Wandlung Timer/Timer INterrupt ausschalten
> oder ADC ohne Interrupt.

Wobei sich mir 2 Fragen stellen

* wen kratzt es, wenn ein Timer Interrupt aufläuft während der ADC
  gerade eine Messung macht
* Was bringt dir ein ADC-Complete Interrupt, wenn der sowieso nur
  das Ergebnis abholt?
  (Bis jetzt warte ich immer noch auf ein sinnvolles Beispiel für einen
  ADC-Complete Interrupt abseits vom Free-Running Mode, welches nicht um
  3 Stufen einfacher durch banales Sampling in der Hauptschleife
  erreichbar wäre.)

von Stefan H. (hohmi)


Lesenswert?

> * wen kratzt es, wenn ein Timer Interrupt aufläuft während der ADC
>   gerade eine Messung macht

das war ja meine Frage, ob es da zu komplikationen kommen kann.

> * Was bringt dir ein ADC-Complete Interrupt, wenn der sowieso nur
>   das Ergebnis abholt?
>   (Bis jetzt warte ich immer noch auf ein sinnvolles Beispiel für einen
>   ADC-Complete Interrupt abseits vom Free-Running Mode, welches nicht um
>   3 Stufen einfacher durch banales Sampling in der Hauptschleife
>   erreichbar wäre.)

Hatte den ADC am Anfang im Free Running Mode. Kanal gewählt --> 300us 
gewartet und wert in die variable übertragen. Ich verwende die 
eingelesenen werte um die Helligkeit (PWM) einer 7 Segmentanzeige zu 
steuern. Da kam es sporadisch zum flackern. Seit dem Interrupt 
gesteuerten Wandlen ist das sporadische beseitigt. werde es aber nochmal 
mit dem free running mode versuchen.

von Karl H. (kbuchegg)


Lesenswert?

> Kanal gewählt --> 300us gewartet und wert in die variable übertragen.

Lol
Und inwiefern ist das jetzt einfacher als


   starte ADC
   warte bis ADCS Bit auf 0 zurückgeht
   hole den ADC Wert


ganz ohne Interrupt, einfach nur straightforward runterprogrammiert und 
nur solange gewartet, bis der ADC 'Fertig!' schreit.
Noch eine kleine Mittelwertbildung auf mehrere hintereinander gesampelte 
Werte und dann flackert nichts mehr

von Stefan H. (hohmi)


Lesenswert?

jo da hast recht, ist noch einfacher. Danke für eure Hilfe

mfg
Hohmi

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.