Hallo Zusammen, heute frage ich euch Löcher in den Bauch... ;o) also ich habe die Problematik, das ich weiß wie ich einstellen kann, dass bestimmte Dinge einen Interrupt auslösen können. Aber ich weiß nicht wie ich in WinAVR die Interruptfunktion bekannt gebe!!! Das findet man auch nirgends in der Hilfe. Von Keil kenne ich das noch so: void xxxx_xx (void) interrupt 6 { .... } jetzt erklär mir doch mal bitte einer wie ich das bei WinAVR mache!? Ich bedanke mich schon mal für die super Informationen die man hier erhält und wünsche euch noch einen sonnigen Tag. Gruß Benjamin
Das sollte eigentlich im avr-libc-user-manual-1.4.4.pdf stehen. Ansonsten schau mal in der interrupt.h nach (ISR) Peter
Hallo Zusammen, also ich habe mir mal die HEADER bzgl. der interrupts angesehen, dabei sind unterschiede zu der beschreibung im GCC-Turtorial zu sehen gewesen. denn in der header (trotz neuer version von WinAVR) sind die alten macros für die vectoren enthalten (z.b. SIG_XXXX_XXXX) und als ich dann mit: ISR (SIG_XXXX_XXXX) { ...... } die routine ausprobieren wollte hat sich auch nichts getan!! Was soll ich jetzt tun???? Danke!! Gruß
Welchen Teil des Abschnitts http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Veraltete_Funktionen_zur_Deklaration_von_Interrupt-Routinen aus dem AVR-GCC Tutorial versteht du nicht?
"Was soll ich jetzt tun????" Nicht so tun, als könnten andere in Deinen Kopf schauen. Also was hast Du getan, und was hast Du erwartet und was ist stattdessen passiert ? Peter
Wenn Du die ISRs mit 'ISR' einleitest, dann musst Du auch die 'XXXX_XXXX_vect'-Makros benutzen und nicht die veralteten 'SIG_irgendwas'-Dinger...
mir geht se darum, ab welcher version von WinAVR setze ich die Kommandos ISR(xxxxxx) { .... } ein!? bzw. bis zu welchen version wird noch mit: SIGNAL (xxxxxx) { .... } eigesetzt!? ich habe beides ausprobiert und keiner der befehle hatte keine wirkung!! ich habe den globalen interrupt freigegeben, und auch die nötigen flags in den SFR gesetzt gehabt!!
> Wenn Du die ISRs mit 'ISR' einleitest, dann musst Du auch die > 'XXXX_XXXX_vect'-Makros benutzen und nicht die veralteten > 'SIG_irgendwas'-Dinger... schön und gut!! aber wenn die neuen vectoren nicht in der header stehen dann kann ich sie nicht verwenden!! wenn der compiler bei dem befehl SIGNAL auch nichts macht.... , was dann??????????
ich stelle nachher mal mein programm hier hinein!! dann kann sich das ja vielleicht mal jemand ansehen!!
so jetzt habe ich mal mein komplettes projekt gezipt!! wenn mir jemand mal einen Tip geben könnte!! Das Programm ist einfach erst einmal nur spielerei! darum nicht auf die portbelegungen achten!!
Woher weist du, dass der Timer Overflow Interrupt nicht aufgerufen wird? So wie ich das sehe, machst du im Interrupt: (*czTimer++); wobei uint8_t *czTimer; und dieser Pointer niemals einen Wert zugewiesen kriegt. Das heist, dein Programm ändert ständig die SRAM Speicherzelle 0 (da czTimer ja eine globale Variable ist, und als solche den Wert 0 enthält.) Was da aber an dieser Speicherzelle steht, entzieht sich unserer Kenntnis und Kontrolle. Das entscheidet einzig und alleine der Compiler. Wenn du Glück hast, bügelst du nur eine unwichtige Variable nieder, wenn du Pech hast, hast du das Runtime System zerschossen. Auf jeden Fall: Wenn ich mit einem Feature nicht zurecht komme, dann schreibe ich mir ein eigenes Testprogramm, dass sich nur mit diesem Feature beschäftigt. Zum einen kann ich mich dadurch nur auf mein momentanes Problem konzentrieren (in deinem Fall: warum löst der Interrupt nicht aus), kann mir saubere Testumgebungen überlegen (zb. wenn der Interrupt kommt, soll eine LED leuchten) und ganz wichtig: Ich werde nicht durch mögliche Fehler in meinem eigentlichen Programm behindert und abgelenkt.
Mein Fehler: (*czTimer++); bügelt überhaupt nichts nieder. Es wird einfach nur der Pointer erhöht. Die Dereferenzierung ist an dieser Stelle völlig für die Katz. Damit: Woran erkennst du das der Overflow nie aufgerufen wird?
ich habe einfach nur die zeile hinein geschrieben gehabt, um zu sehen ob der compiler im debugmodus überhaupt in die ISR hineinspringt!! das habe ich nie gesehen, darum gehe ich davon aus das er diese routine nie angesprungen hat! mmmmhhhh.... also wieder mal einen gedanklichen fehler gemacht!! oder??
also ich habe das noch einmal geändert!! //Globale Variable uint8_t Timer; //Initialisierung czTimer = &Timer //ISR SIGNAL (SIG_OVERFLOW0) { uint8_t i; i++; *czTimer = i; } das habe ich simuliert.... die ISR wird nicht angesprungen obwohl im TIFR das flag TOV0 gesetzt wird und im TIMSK das flag TOIE0 gesetzt wurde!! ich komme nicht mehr klar.... entweder ich bin zu blöd oder ich kann keine logischen zusammenhänge mehr erkennen!?
Definiere Deinen Pointer in der ISR als volatile, sonst wird die ganze ISR vom Optimizer weg rationalisiert, weil sie nichts macht... volatile uint8_t *czTimer; //Timer-Laufvariable Dann würde ich noch sicher stellen, das die Interrups wirklich aktiv sind, bzw. sie mit sei() schon vor der Endlosschlaufe freigeben... //Endlosschleife, wenn kein Interrupt sei(); // Globale Interruptfreigabe while(1) { ... } So funktioniert Dein gepostetes Program zumindest bei mir...
Mit dem neuen Interrupt-Macros gehts übrigens bei mir ebenfalls: ========================================== // SIGNAL(SIG_OVERFLOW0) // deprecated interrupt macro ISR(TIMER0_OVF_vect) // new interrupt macro { (*czTimer++); }
hey... wahnsinn... ich sehe das der compiler einen interrupt registriert, aber er springt immer noch nicht die ISR an!!! sondern beginnt der compiler mit meiner initialisierung... das heißt für mich er findet nicht den vector den er anspringen soll!? oder? wenn das so wäre hätte ich auch noch immer ein problem mit der declaration der ISR...
> ich sehe das der compiler einen interrupt > registriert, aber er springt immer noch nicht die ISR an!!! sondern > beginnt der compiler mit meiner initialisierung... Kannst du das mal naeher erläutern? Irgendwie macht der Satz da oben überhaupt keinen Sinn. Wenn du im Simulator mit Single-Step durch dein Programm gehst, wird irgendwann der sei() ausgeführt (hoffentlich). Ab diesem Zeitpunkt müsstest du im Simulator links bei den I/O Devices sehen können, wie bei jedem Single-Step Schritt der Zähler hochzählt. Sobald der über 255 drüber kommt, wird die ISR angesprungen (Breakpoint dorthin setzen, der müsste ansprechen).
ok... gebe zu das ich ein bißchen schnell mit meinen gedanken war... also der globale interrupt ist freigegeben!! der timer interrupt ist enable gesetzt, der timer läuft voll und ein overflow wird registriert. aber die interruptroutine wird nicht angesprungen, sondern mein programm startet direkt wieder hinter meiner "main" declaration!!! komisch.... oder??? und ich habe beide befehle ausprobiert!!!!!!
So ein ähnliches Phänomen hatt eich auch mal. Verwendest du noch SIGNAL oder bist du bei ISR? Wenn du noch SIGNAL benutzt, dann musst du unbedingt #include <avr/signal.h> einbinden. Ansonsten kommts zu solchen Effekten (zumindest wars bei mir so).
Wenn Du mit AVRStudio simulierst, dann schau doch mal im Disassembler-Fenster, was in der Vektortabelle an der entsprechenden Stelle steht. Das hört sich mir fast so an, als ob tatsächlich der Vektor nicht korrekt initialisiert wurde und der µC bei jedem Interrupt nen Reset macht... Das Interrupt-Flag wird doch jedes mal gelöscht, oder?
Hast Du die Timer-Laufvariable als volatile deklariert...??? volatile uint8_t *czTimer; //Timer-Laufvariable Ich hab den Eindruck die ISR-Funktion wird sonst komplett wegoptimiert, und dann die Jump Adresse des ISR-Vectors auf 0 gesetzt => Restart.... IMHO eine gefährliche Eigenschaft des AVR-GCC. Interupt-Vektoren mit volatile uint8_t *czTimer; ____________________________________________________________ +00000000: 940C002A JMP 0x0000002A Jump //Reset +00000002: 940C0045 JMP 0x00000045 Jump +00000004: 940C0045 JMP 0x00000045 Jump +00000006: 940C0045 JMP 0x00000045 Jump +00000008: 940C0045 JMP 0x00000045 Jump +0000000A: 940C0045 JMP 0x00000045 Jump +0000000C: 940C0045 JMP 0x00000045 Jump +0000000E: 940C0045 JMP 0x00000045 Jump +00000010: 940C0045 JMP 0x00000045 Jump +00000012: 940C0045 JMP 0x00000045 Jump +00000014: 940C0045 JMP 0x00000045 Jump +00000016: 940C0047 JMP 0x00000047 Jump //Timer0_OVF => ISR +00000018: 940C0045 JMP 0x00000045 Jump +0000001A: 940C0045 JMP 0x00000045 Jump +0000001C: 940C0045 JMP 0x00000045 Jump +0000001E: 940C0045 JMP 0x00000045 Jump +00000020: 940C0045 JMP 0x00000045 Jump +00000022: 940C0045 JMP 0x00000045 Jump +00000024: 940C0045 JMP 0x00000045 Jump +00000026: 940C0045 JMP 0x00000045 Jump +00000028: 940C0045 JMP 0x00000045 Jump _______________________________________________________ +00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0045 JMP 0x00000045 Jump +00000004: 940C0045 JMP 0x00000045 Jump +00000006: 940C0045 JMP 0x00000045 Jump +00000008: 940C0045 JMP 0x00000045 Jump +0000000A: 940C0045 JMP 0x00000045 Jump +0000000C: 940C0045 JMP 0x00000045 Jump +0000000E: 940C0045 JMP 0x00000045 Jump +00000010: 940C0045 JMP 0x00000045 Jump +00000012: 940C0045 JMP 0x00000045 Jump +00000014: 940C0045 JMP 0x00000045 Jump +00000016: 940C0000 JMP 0x00000000 Jump //Timer0_OVF => RESET +00000018: 940C0045 JMP 0x00000045 Jump +0000001A: 940C0045 JMP 0x00000045 Jump +0000001C: 940C0045 JMP 0x00000045 Jump +0000001E: 940C0045 JMP 0x00000045 Jump +00000020: 940C0045 JMP 0x00000045 Jump +00000022: 940C0045 JMP 0x00000045 Jump +00000024: 940C0045 JMP 0x00000045 Jump +00000026: 940C0045 JMP 0x00000045 Jump +00000028: 940C0045 JMP 0x00000045 Jump
danke!!!!! die einbindung der signal.h hat den entscheidenden effekt gebracht!! ich werde diese jetzt gleich durch die interrupt.h einbinden lassen, damit kann man diese nicht vergessen!! noch einmal danke an alle!!!!!!
> ich werde diese jetzt gleich durch die interrupt.h einbinden > lassen, damit kann man diese nicht vergessen! Spar's dir und nimm die aktuelle Version: die hat gar keine <avr/signal.h> mehr. Da kannst du sie auch nicht mehr vergessen.
An die AVR-GCC Macher: +00000014: 940C0045 JMP 0x00000045 Jump +00000016: 940C0000 JMP 0x00000000 Jump //Timer0_OVF => RESET +00000018: 940C0045 JMP 0x00000045 Jump Im obigen Beispiel sieht man, dass unter Umständen ein Jump auf die Adresse 0 in die Interrupt-Tabelle eingetragen wird, wenn etwas schief läuft (z.B. bei weg optimierter ISR-Funktion?) Ist es nicht möglich, beim comilieren oder linken ein #warning auszugeben, wenn dies passiert und eventuell auch noch ein "reti" Statement oder ein Jump auf ein "reti" Statement? MfG Peter
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.