Hallo ich habe folgendes Problem(seit Stunden), Ich habe ein Unterprogramm geschrieben welches den Timer0 benutzt und beim Überlauf eine Interruptroutine abarbeiten soll.Den Timer habe ich initialisiert, TCCR0 gesetzt,TIMSK gesetzt,sei() auch eingegeben. Im AVR-Studio Simmulator zählt der Timer auch hoch,springt aber beim Erreichen des Endwertes an den Anfang der Main und arbeitet diese wieder ab. die Interrupt Service Routine wird ignoriert, bringe ich aber den Quelltext der Routine an das Ende der Quelldatei springt die ISR weningstens dort hinein, aber nach hochzählen des Timers wieder an den Anfang der Main! Muß nach abrbeiten der ISR nicht wieder an die Stelle gesprungen werden von wo sie aufgerufen wurde? Und warum wird sie manchmal garnicht angesprungen? ISR (Timer0) oder ISR (Timer0_OVF) falsch? Danke für eure Hilfe
Wenn Du den Code nicht postest, kann Dir hier keiner wirklich helfen, außer mit schwammigen Vermutungen. Wenn Du mit WINAVR-C programmierst, dann kann ich Dir wenigstens sagen, dass ISR (Timer0) und ISR (Timer0_OVF) falsch sind und dass das wahrscheinlich das Problem sein dürfte, da der Interrupt zwar freigegeben ist, aber der µC keine gültige ISR zur Bearbeitung hat. Deshalb wird in den Spurious Interrupt Handler gesprungen, was i.d.R. einen Reset bedeutet. Die richtigen Namen der Interrupt-Vektoren stehen in der iom8.h. Sie enden alle mit _vect.
Probier erst das mit den richtigen Interrupt-Vektoren aus! Vielleicht brauchste dann gar nix mehr zu schicken!
Ich kann Dir so viel verraten, dass z.B. der Vektor für den Overflow-Interrupt von Timer 0 mit TIMER0_OVF_vect definiert ist...
Entweder tatsächlich blind, oder Du kannst nicht lesen. Warum schreib ich eigentlich den ganzen Scheiß? Kann ich mir dann wohl auch sparen...
@J. Ustiz: Hä??? @Andreas2000: Schön, dass Du den Code doch noch schickst, aber einen Fehler hab ich Dir ja schon mitgeteilt. Abgesehen von dem falschen Vektornamen bekommst Du wahrscheinlich Probleme mit Variablen, die Du in der ISR veränderst, wenn Du sie nicht volatile deklarierst.
Vectornamen habe ich angepasst, Aber trotzdem wird die ISR nicht angesprungen. Das müsste doch klappen? Was meinst du mit "volatile"?
Die ISR wird jetzt aufgerufen.(Ein Zeichen war noch falsch). Hat denn jemand ne Idee wie man es schaft das der Timer z.B. 5 mal durchlaufen wird,und dann in die Main zurück springt ?
Wenn eine globale Variable, die in einer Interrupt-Routine verändert werden soll, nicht volatile deklariert wird, kann es passieren (vereinfacht gesagt), dass das Hauptprogramm von einer Änderung nichts mitbekommt. Der Typqualifizierer volatile teilt dem Compiler mit, dass die betreffende Variable nicht im Rechenregistersatz abgelegt werden soll, sondern im SRAM, da die vom Programm benutzten Rechenregister am Anfang der ISR gesichert und am Ende wiederhergestellt werden.
Achja, und das mit dem 'Timer 5 mal durchlaufen und dann in die main zurück' müsstest Du mal näher erläutern. Du willst doch hoffentlich nicht in der ISR eine Warteschleife einbauen? So was ist nämlich Pfui...
Pfui möchte ich natürlich nicht!! Mein Bemühen ist es ein und Ausschalten eines Ports zu realisieren, also eine bestimmte Frequenz mit dem Timer zu erzeugen. Diese sollte aber insgesammt nur 5 Perioden haben(zu Testen). Später sollen es dann einmal 20 Periden mit einer Frequenz von 41,...kHz werden, um eine US-Transceiver_Schaltung anzusteuern(). Zum erzeugen der Frequenz eignen sich Timer ja gut nur das durchlaufen des Timers mus irgendwie abzählbar sein!
Hat denn jemand ne Idee wie man Timerdurchläufe zählbar macht, oder wie man trotz ISR ein Schleife geschickt einbindet? Wäre für eine Code Idee dankbar.
Hallo, Du schreibst in der ISR eine 1 in das Bit TOV0 des Registers TIFR. Damit setzt Du das Overflow Interrupt-Flag zurück. Dann pollst Du das Bit TOV0 und wen es wieder gesetzt ist, dann ist wieder ein Overflow aufgetreten. Bit wieder zurücksetzen und dann wieder pollen (pollen = abfragen). Aber ansich ist eine Warteschleife in einer ISR eine Todsünde. Gruß Wolfgang -- www.ibweinmann.de Brushless Development Kit - Der Weg zum Brushlessregler mit AVR
Nimm eine globale Variable setze sie auf 10, und zähle bei jedem Interrupt 1 ab. Wenn sie 0 erreicht schaltest du das Port-Bit nicht mehr um - fertig. Jedesmal wenn du wieder erneut ein Signal senden willst setzt du im Main die Variable wieder auf 10 (oder später auf 40). Timer_Interrupt: if(PeriodCount > 0) { Port toggeln; PeriodCount--; } EndeInterrupt Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register setzt. Gruss Andi
Hallo, wie wär's damit: Die Timer Interrupt Routine (ISR) zählt bei jedem Überlauf eine Variable um eine Einheit hoch. Jetzt folgt noch die Abfrage, ob diese Variable schon einen bestimmten Wert erreicht hat (weiteres Bit setzen) oder nicht (kein Bit setzen g) und es wird ins Hauptprogramm gesprungen. Entweder wird jetzt bei jedem Durchlauf des Hauptprogramms dieses Bit (in irgendeinem beliebigen Register; "privates Statusregister") abgefragt, oder Du legst es auf einen Pin, der als externer Interrupt festgelegt ist. Wird aus der ISR zurückgesprungen, wird das Interrupt enable Bit gesetzt und anschließend sofort die Service Routine für X Timerdurchläufe ausgeführt. Gruß Fred
> Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren > AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register > setzt. Laut Betreff handelt es sich um den Mega8 und der kann das noch nicht. ...
>> > Noch ein Tipp: Port toggeln (=Zustand wechseln) kann man bei neueren > AVRs ganz einfach in dem man das entsprechende Bit im PINxx Register > setzt. Laut Betreff handelt es sich um den Mega8 und der kann das noch nicht. ... >> Welches Bit der "neueren" ist das? Muss ich mir glatt mal ansehen. PORTTOGGLEBIT oder so? Wenn man nicht ständig auf dem laufenden bleibt... AxelR.
@Axel: Bei Mega48/88/168 z.B. bewirkt das Setzen von Bits (Schreiben mit sbi oder out) in den PIN-Registern (PINB, PINC, PIND) das Toggeln des zugehörigen Ausgangs. Ist ein nettes Feature, aber dafür wurden etliche oft gebrauchte I/O-Register (auch Timer) in den Extended-I/O-Space verlagert, wo sie nicht meht mit IN/OUT (also mit nur einem Takt) angesprochen werden können. ...
Kapitel 12.2.2 im Datenblatt, habs gefunden. Danke. Muss ich für mich aber noch den Nutzen abwägen. kommt man da nicht mit den Portzuständen komplett durcheineander? Na egal, danke nochmal Zu den IN/OUT vs. LD/ST habe ich hier irgentwann mal ein ASM Makro von der ATMEL Seite gepostet, wo das automatisch berücksichtigt wird. AxelR.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.