Interrupt Priorität ADC TIMER (ATMEGA8)

OP #3041110
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
Gast #3041116
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)
#3041121
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)
OP #3041142
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
#3041170
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.)
OP #3041283
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.
#3041348
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

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.