-         

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 36

Thema: Problem mit Timerablauf/neu ICP1 funktioniert nur einmal

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378

    Problem mit Timerablauf/neu ICP1 funktioniert nur einmal

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    !!!!die fortsetzung mit dem neuen problem ist weiter unten!!!

    ich verwende in einem meiner programme einen timer um eine mikrosekundengenaue pause einzubauen, dafür hab ich den timer2 eines M32 auf PS 1 und FastPWM gesetzt

    in der overflow ISR dekrementier ich ne variable um die überläufe zu zählen, ist der wert dann ebi 0 angelangt, schalte ich den interrupt für das OCR register frei, in dem ich n = rest_µS*16 stehen habe ... ist das compare ereignis eingetreten, ist die pause beendet und der timer wird gestoppt

    komisch nur, dass mir scheinbar öfters genau ein timerüberlauf verloren geht! der timer beendet manchmal 16µS zu früh und ich komm auf denn teufel nciht drauf WARUM bitte helft mir

    Code:
    ISR(SIG_OVERFLOW2)  // Timer 2 
    {
    	if (faktor != 0) faktor--;
    	cli();
    	if (faktor == 0){
    		TIMSK &= ~(1<<TOIE2);
    		if (TCNT2+10 > OCR2) timeUp2();
    		else TIMSK |= (1<<OCIE2);
    	}
    	sei();
    }
    
    ISR(SIG_OUTPUT_COMPARE2) 
    {
    	cli();
    	timeUp2();
    	sei();
    }
    ISR(SIG_COMPARATOR)
    {
    	cli();
    	ACSR &= ~(1<<ACIE); // disable interrupt
    	STOP;   
    	TCNT2 = 0; 
    	TCCR2 |= (1<<CS20); // enable timer2
    	TIFR |= (1<<TOV2);
    	TIMSK |= (1<<TOIE2);
    	sei();   
    }
    void timeUp2()
    {
    	START;
    	TIMSK &= ~(1<<OCIE2); // disable timer2 output compare interrupt
    	TCCR2 &= ~((1<<CS22) | (1<<CS21) | (1<<CS20)); // disable timer2 (clockselect 0)
    }

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Als allererstes entfernst du mal sämtliche cli/sei aus den Interrupt-Funktionen, die haben darin nichts verloren (verursachen höchstens Probleme).

    Dann hast du einen logischen Fehler:
    ist der wert dann ebi 0 angelangt, schalte ich den interrupt für das OCR register frei,
    Das Interrupt-Flag ist aber längst gesetzt, so dass der Interrupt dann sofort nach dem Ende der Overflow-ISR kommt, und nicht erst beim nächsten Compare-Ereignis. Du musst also auch noch das Flag löschen.
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    stimmt ... ich versuchs mal bis gleich

    leider hab ich sehr viele interrupts und die cli() und sei() sind mit bedacht gesetzt und stabilisieren sogar das ergebnis ... ich mag darüber nicht diskutiern sofern es nicht das problem ist, die ergebnisse sprechen bände (ehrlich)

    PS: keine änderung leider

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    Schau dir in der Simulation mal das SREG an wenn ein ISR ausgelöst wird. Du wirst sehen das das I-Bit sofort auf 0 gesetzt wird. Genau das machst du noch mal mit dem cli().
    Was dir passieren kann ist, ein weiterer Interrupt steht an, wird am Ende deiner ISR durch dein sei() freigegeben, diese ISR wird sofort angesprungen ohne die laufende zu beenden. Wozu das führen kann wirst du ja auch bedacht haben.
    Ich will dir keinesfalls etwas einreden, aber stabilisierend kann das nicht wirken.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    ja, streckenweise rechne ich sogar fest mit dieser reaktion! es bleibt aber genügend zeit um die verschachtelung abzubauen ... problematischer ist es wenn zwischen den operationen in der ISR ne unterbrechung entstehen würde!

    die ISR für den Komparator werd ich demnächst reduzieren, ich werd einen externen komoparator einsetzen, der die funktion meiner makros "START" und "STOP" übernimmt und den controller quasi nurnoch über das ereignis informieren, der dann die notwendigen schritte einleitet

    ausserdem es müssten wirklich ziemlich genau 256 takte sein die ins land ziehen um diesen effekt auszulösen ... da der effekt IMMER dieselbe größe hat(und auch nur negativ ist) statt einer 100S pause warte ich 84µS .. ein "mehr" oder "weniger" ist nicht, es sind nur diese beiden ergebnisse .. 100µS sollen es sein, 84µS sind es wenn der timer mal wieder spinnt

    vielleicht hat ja jemand noch nen gedanklichen beitrag, wie ich eine µS genaue verzögerung einbauen kann, die in der summe aber bis 500mS (eventuell mehr) dehnbar ist und parallel die abarbeitung eines datenbus erlaubt

    und noch einmal, sehr viele testläufe haben erwiesen, dass die menge der ISR und die verwendung von cli() und sei() darin auf das gesamte timing keinen einfluss haben, nur eben dieser eine effekt stört gewaltig und bleibt mir ein rätsel .. der code den ich oben geschrieben habe beinhaltet eigentlich alles was mit den timern zu tun hat und auch alle ISR die größer sind als 2 zeilen

    in de rmain werden nur diverse variablen abgefragt um auf kommunikation und probleme reagieren zu können

    leider kann cih hier nicht alles posten

    PS: für die simulation fehlen mir die externen ereignisse und ne handeingabe fällt flach, wegen der zufälligkeit (was mich auch an dem simulationsergebnis zweifeln lässt) ^^

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Ich kann meinen Vorrednern nur zustimmen.
    Die ganze Struktur dieses Codes (und sein Format ganz neben
    bei auch, dafür gibt es Code-Tags...) mit CLI und SEIs in der ISR und dann auch noch Unterprogrammaufrufen in diesen Ausmaßen sind einer mikrosekundengenauen Zeitmessung mehr als gegenläufig.
    Außerdem ist das Programm so nicht zuverlässig terminiert, was dazu führen kann, dass es stundenlang läuft und sich dann mit einem Stackoverflow verabschiedet.
    SEI und CLI sind zudem in allen Fällen außer Overflow2 völlig überflüssig, weil beim Eintritt in eine ISR ohnehin ein CLI ausgeführt wird und bei Austritt entsprechend ein SEI. Kann sogar sein, dass der Compiler diesen Unfug gleich wegoptimiert, sofern Du die Optimierung eingeschaltet hast, was ich doch hoffe.
    Zuverlässig wäre es, wenn die ISR viel kleiner wird, möglicherweise nur ein Flag gesetzt wird, alle SEIs und CLIs draußen sind und die Unterprogrammaufrufe möglichst durch Code ersetzt werden, denn diese kosten Zeit.
    Dann fällt auf, dass Du entweder eine alte GCC oder einen anderen Compiler benutzt. In ersterem Fall würde sich ein Update lohnen.
    Ich befürchte, Dein Problem ist zuverlässig nicht nebenbei zu lösen, ohne den Rest des Programms auch zu kennen.
    Gruß

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    (und sein Format ganz neben
    bei auch, dafür gibt es Code-Tags...)
    ich versteh jetzt nciht ganz was du meinst

    und die Unterprogrammaufrufe möglichst durch Code ersetzt werden
    naja das ist jetzt nur ne variante gewesen weil ich das OC ereignis im verdacht hatte, da hab ich den code in ne nmethode ausgelagert und im overflow kontrolliert ob ich mindestens ne 10 im OCR stehen hab und sonst direkt in den zweig einsteige

    und jetzt noch die preisfrage, wie kommst du darauf, dass mein compiler zu alt sein soll ??? ich hab mal neuesten winavr installiert aber geändert hat siocih nix

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Das sind Code-Tags:
    Code:
    ISR(SIG_OVERFLOW2)  // Timer 2
    {
       if (faktor != 0) faktor--;
       cli();
       if (faktor == 0){
          TIMSK &= ~(1<<TOIE2);
          if (TCNT2+10 > OCR2) timeUp2();
          else TIMSK |= (1<<OCIE2);
       }
       sei();
    }
    Du schreibst "[ code ]...[/ code ] ohne die Leerzeichen zwischen den Code. Außerdem ließe sich Dein Geschreibsel wesentlich besser lesen, wenn Du richtige deutsche Wörter (ein statt "ne") und Satzzeichen benutzen würdest.
    Du benutzt "ISR(SIG_OVERFLOW)"
    Das hat mich verwirrt, weil SIG... ist die alte Schreibweise, das heißt jetzt (TIMER1_OVF_vect)". Die neuen GCCs prüfen das aber und es funktioniert.
    Gruß

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    achsoooooo ja gut hab mich halt so dran gewöhnt mit den SIG'S ..

    tut mir leid dass ich nicht grammatikalisch korrekt schreibe, satzzeichen verwende ich auch schon hin und wieder

    ich weis dass diese art des schreibens manchen leuten "eines forums unwürdig" erscheint und ich verpflichte sie auch nicht zu antworten wenns ihnen nicht passt

    ich rechne es dir dennoch hoch an dass du es trotzdem tust

    ich "rede" halt mehr als dass ich schreibe, hab halt immer zu viel gechattet und da gewöhnt man sich ein paar übelkeiten an

    zu den tags, ich hab doch code tags verwendet oder hast du die da jetzt rein editiert wie ich sie vergessen habe .. oder hab ich jetzt wieder was falsch verstanden .. sorry ich bin ein wenig unkonzentriert weil ich der verzweiflung nahe bin, kann sein, dass ich vergessen habdie einzufügen ..

    der code an sich sah auch schonmal schöner aus ... des debuggings wegen hab ich ihn nur schwer verschandelt um mögliche ursachen einzugrenzen (alles in methoden verpackt und dann schrittweise abgeschaltet)


    PS:
    ich hab jetzt deinen rat befolgt und flags verwendet, die ich in der main polle und bei bedarf von dort aus die methoden aufrufe

    zumindest hat diese aktion die reproduzierbarkeit auf scheinbar 0 zurückgeführt

    möglicherweise ist das problem auch gelöst, aber da helfen mal wieder nur tests ..

    ausserdem hab ich mir irgendwann im verlauf der untersuchung meine automatische kalibrierung zerschossen ^^ aber das wird schon wieder

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Nach dem Lesen deiner Antworten drängt sich mir der Verdacht auf, dass du das mit den cli/sei noch nicht wirklich verstanden hast. Das macht die Hardware von ganz alleine. Beim Ausführen einer ISR wird das I-Flag gelöscht und durch das reti am Ende wieder gesetzt. Dein cli ist damit schon mal ohne jegliche Funktion, und das sei enabled die Interrupts nur etwas eher als es ohne der Fall wäre. Das bringt dir keinerlei Vorteil, nur potenzielle Nachteile.
    MfG
    Stefan

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •