Forum: Compiler & IDEs Problem bei Programmablauf mit Interrupts


von Jens K. (jens_)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich habe mittlerweile mein Programm theoretisch soweit, dass es macht 
was es machen soll -> nur wie immer kommt es immer anders als man denkt.

Die Programmteile einzeln (ADC-Auswertung (Interrupt); 
Frequenzauswertung (Interrupt); Menü, Ausgabe) funktionieren, dies hab 
ich getestet.

Nur beim Zusammenspiel hapert es, wenn die beiden Interruptroutinen 
gleichzeitig im Programmablauf vorhanden sind.
Prinzipieller Programmablauf ist folgender:
(endlosschleife)

wenn adc mehr als 8 mal ausgewertet wurde -> auswertung 
vornehmen,variable setzen, damit erst wieder Interrupt durchlaufen wird, 
wenn Ausgabe erfolgt ist und "Erlaubnis" für Display geben;

wenn Frequenzmessung beendet -> auswertung vornehmen,variable setzen, 
damit erst wieder Interrupt durchlaufen wird, wenn Ausgabe erfolgt ist 
und "Erlaubnis" für Display geben;

wenn Ausgabe erlaubt -> Schreibe werte auf Display, setze 
Interruptvariablen zurück;

(ende)

So als kurzer Auszug.(Teil des Quellcodes ist oben angehängt.)

Mein Poblem ist jetzt, dass bei der Frequenzmessung ca. jedes 3. mal 
extrem falsche werte vorhanden sind  -> und ich hab keine Ahnung warum?
Wäre super wenn sich dasjemand mal ansehen könnte.

MFG


P.S. Die Variablen die nicht lokal in der main() deklariert sind, sidn 
alle  global deklariert (ja, mit volatile ;-) )

von Jens K. (jens_)


Lesenswert?

Niemand eine Idee worans leigen könnt?

von Stefan (Gast)


Lesenswert?

1/ Der angegebene Quellcode ist nicht vollständig.

2/ Welche Variablen sind global und werden wo in welchen Funktionen 
(Interrupts) benutzt? Eine tabellarische Übersicht kann hier helfen.

von Mister mit Kanister (Gast)


Lesenswert?

Wenn sich die Interrupts gegenseitig unterbrechen, kann helfen wenn man 
in jeder ISR am Anfang und Ende ein cli(); bzw. sei(); macht. Wenn z.B. 
die Frequenzmessung unterbrochen wird, läuft der Timer weiter aber kann 
keine Ereignisse zählen.

von Peter D. (peda)


Lesenswert?

Mister mit Kanister wrote:
> Wenn sich die Interrupts gegenseitig unterbrechen, kann helfen wenn man
> in jeder ISR am Anfang und Ende ein cli(); bzw. sei(); macht.


Das ist Quatsch mit Soße.

Beim AVR kann kein Interrupt einen anderen unterbrechen.


Unterbrechung ist nur bei MCs (z.B. 8051) mit Interruptprioritäten 
möglich.

Und da muß man erst einem Interrupt eine höhere Priorität zuweisen, ehe 
er andere unterbrechen darf.

Und dann wäre es superblöd, wenn man die höhere Priorität wieder mit 
Interruptsperre aushebelt.

Man wird ja wohl nicht ohne Grund eine hohe Priorität vergeben haben.


Peter

von Jens K. (jens_)


Angehängte Dateien:

Lesenswert?

Hi!

Also anbei mal der Quellcode -> Nur das Menü und das Display wurde 
weggelassen.
Das Interessante ist, dass solange ich in der main() die Schleife für 
die ADC-Auswertung weglasse die Frequenzauswertung funktioniert.
Ist die ADC-Auswertung aktiv, funktioniert die Frequenzauswertung nur in 
einem Bereich von ca. 5kHz bis 25kHz.

MFG und Danke.

von Stefan (Gast)


Lesenswert?

Du sperrst in main()/while bei der Ausgabe zeitweise die Interrupts und 
wunderst dich, dass die Frequenzauswertung (die auf Interrupts basiert) 
nicht richtig funktioniert? Nee, oder?

von Jens K. (jens_)


Lesenswert?

Hi!

Also das mit den Interrupts deaktivieren is Absicht(sind "nur" der ICP 
und der Timer Overflow) -> steht auch im Kommentar dahinter warum. Das 
bereitet auch bei einer "satnd-alone"(Also ohne ADC) Messung keinerlei 
Probleme. Ganz nebenbei findet während einer Ausgabe so oder so keine 
Auswertung der Frequenz statt.(Ich kann das mit dem 
Interruptabschalten(nur Timer/ICP) auch weglassen - Effekt: keiner, 
ausser dass bei hohen Frequenzen der Overflow Interrupt vom Timer so oft 
aufgerufen wird, dass meine Displayausgabe extrem verlangsamt wird.)
Wie gesagt - solange ich das ADC Ergebnis nicht auswerte oder nur den 
ADC auswerete hab ich auch kein Problem.(Interrupts beliben jeweils an, 
aber die if-Schleifen in der main() werden weggelassen)
Erst wenn beides "zeitgleich" aktiv ist hab ich ein Problem -> es kommen 
komiche Werte für die Frequenz raus - und ich hab keine Ahnung warum.

MFG

von Mister mit Kanister (Gast)


Lesenswert?

Sorry, hab das mit den Interrupts verwechselt. Bei AVR gibts das 
natürlich nicht. Danke Peter.

von Hans Dampf (Gast)


Lesenswert?

Hi!

Also ich hab das Problem jetzt dadurch gelöst, dass ich von "quasi 
Multitasking" dazu übergegangen bin, den ADC durch Polling auszuwerten 
und nur noch die Frequenzmessung über Interrupts laufen zu lassen.
-> Zumindestens funktioniert das ganze schon mal sicher.

Danke soweit für eure Tips.

MFG

von Oliver (Gast)


Lesenswert?

arrgh - falschen Button erwischt. Also nochmal:

Hast du dir mal überlegt, wie lange deine Interrupts tatsächlich
gesperrt sind? Dein Code dazwischen enthält immerhin solch "harmlose"
Zeilen wie
1
sprintf (adrehmoment, "%.2f", adcergebnis);
 oder auch
1
LCD_WritePosString(0, 0,"RS232-Modus aktiv", 1);
Das dauert.

Aber eigentlich hast du dir ja deine Frage im Code schon selber
beantwortet.
1
//Interrupts für Timer deaktvieren, da sonst Displayausgabe bei sehr hohen Frequenzen extrem verlangsamt (->Überlauf sehr oft voll)
UND eine flankengesteuerte Frequenzmessung passt nicht zusammen.

Oliver

von Jens K. (jens_)


Lesenswert?

Hi Oliver!

Ja dass die Displayausgabe sehr lange dauert war mir klar. Daher war 
meine ursprüngliche Idee folgende:
Interrupts ADC + ICP aktiv, solange nicht auf Display geschrieben wird.
Sobald hier eine Messung zu Ende ist -> Interrupts deaktivieren um quasi 
in Ruhe aufs Display schreiben zu können.
Interrupts nach Displayausgabe wieder aktivieren.
[Und ich mache ja immer erst nach einer Ausgabe wieder eine neue 
Messung]

Das Problem war ja nicht, dass die Frequenzmessung an sich nicht 
funktioniert hat, das Problem war eher, dass die Auswertung des ADC 
durch Interrupts nur einen gewissen messbaren Frequenzbereich zugelassen 
hat.
Um dies nun zu umgehen bin ich hergegangen und hab die ADC-Auswertung 
als Polling mit in die Ausgabefunktion gezogen, während der keine 
Frequenzmessung stattfindet.
Ich hoffe es ist klar geworden, wie ich das jetzt "gelöst" habe.
Bzw. wenn jemand Anmerkunge, weitere Verbesserungsvorschläge, etc. hat 
immer her damit -> ich lerne gerne und steh auch noch ziehmlich am 
Anfang mit meinem "Können"(wenn mandavon überhaupt schon sprechen kann ) 
bei der µC Programmierung.

Danke auf jeden Fall an alle!

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.