Hallo, so langsam bin ich völlig am verzweifeln, stehe mit dem uC auf "Kriegsfuss" ;=) Bevor ich mit was großem weiter mache, muss ich erwst weiter Grundlagen lernen. Was ein Interrupt ist, was er macht, wer wann die Steuerung übernimmt ist mir soweit klar. Einzig und allein zur Implementierung (in C) habe ich eine Frage. Meinetwegen habe ich so etwas: void main (void) { // Schleife die immer läuft while (1) { // Schleife die nur läuft wenn der Interrupt ausgelöst wurde while (interrupt_ausgeloest) { // mach was :=) pause Ports lesen Ports schreiben usw. [...] interrupt_ausgeloest = 0; } } } void Interruptroutine (void) { interrupt_ausgeloest = 1; } Was den Interrupt auslöst ist erstmal egal. Was ich letztendlich haben möchte: wenn der Interrupt ausgelöst wurde, soll im Hauptprogramm eine "extra-Schleife" abgearbeitet werden und zwar immer (!) vom Beginn ab an. Obiges macht das ja fast soweit, nur was passiert wenn der Interrupt 2 mal "schnell" hintereinander ausgelöst wird? Soweit ich das verstehe, passiert da nichts weiter, die while (interrupt_ausgeloest) Schleife läuft einfach an der alten Stelle weiter (ok, das Hauptprogramm wird unterbrochen, die Interruptroutine wird abgearbeitet und das Hauptprogramm wird an der alten (!) Stelle fortgesetzt (also nicht wie gewünscht von Beginn an)). Sie beginnt also nicht so wie von mir gewünscht von vorne. Wie kann ich dieses Problem lösen? Soll die ganze Interrupt-Schleife in die Interruptroutine (was passiert dann bei 2 "schnellen" Interrupts?), kann man die while schleife immer von Anfang an beginnen (wäre mir am liebsten)? Freue mich über jeden Tipp, Link, Codeschnipsel... Gruß, Hans
if (interrupt_ausgeloest == 1) danach gleich die Variable auf 0 setzen und dann mit der Portmanipulation fortfahren. Wenn inzwischen der Interrupt noch einmal auftritt, wird im Hauptprogramm wieder in den Programmteil verzweigt.
Hi... Also wenn der Umgang mit Interrupts unter C wirklich so umständlich und kompliziert sein sollte, dann werde ich wohl für immer bei Assembler bleiben. Da kümmert mich der Int in der Hauptschleife nicht, denn jeder Int hat seine eigene ISR, die beim Aufruf abgearbeitet wird. Und in dieser kann man Flags (Bits in einem dafür reservierten Register) setzen, auf die die Hauptschleife reagieren kann... Bit- & Bytebruch... ...HanneS...
Ich hab das vor geraumer Zeit gelernt: Was bei einem IRQ passieren soll, gehört in den IRQ-Handler, nicht ins Main. Wäre es nicht also sinnvoller, die Schleife direkt im Interrupt-Handler ablaufen zu lassen (womit es dann keine Schleife mehr wäre)? Dann würde sich das Problem mit zwei schnell nacheinander auftretenden IRQ's nicht stellen (SEI vorausgesetzt). Darüber hinaus kann der IRQ-Handler ja noch immer ein Flag setzen, das das Hauptprogramm "wenn es Zeit hat" auswertet.
Hallo, erst mal danke für die Antworten. @Elektrolurch: bist du dir da sicher? Wenn der Interrupt abgearbeitet wurde, kehrt der uC doch an seine alte Stelle im Programm zurück, also mitten in die if Schleife und nicht an den Anfang (bzw. sogar noch davor wo die Bedingugn geprüft wurde), oder irre ich da gewaltig? @...HanneS... Keine Angst, das geht in C ja genauso. z.B. folgendes: SIGNAL (SIG_INTERRUPT0) { // int 0 ausgelöst } SIGNAL (SIG_OVERFLOW1) { // Überlauf 1 ausgelöst } SIGNAL (SIG_UART_RECV) { // Empfangen } usw. Es interessiert mich einzig und allein dein Satz "...auf die die Hauptschleife reagieren kann...". Das ist mein "Problem". @Olaf Stieleke: Bis jetzt habe ich immer nur gelesen und gelernt, das eine Interrupt Routine möglichst kurz/schnell fertig sein sollte. "Leider" muss ich auch ein paar Takte bei der Abarbeitung warten. Gruß, Hans
Hi, Interrupts werden durch bestimmte Ereignisse ausgelöst, z.B. Timer-Überlauf (passiert, wenn bspw. der 8-Bit-Timer > 255 werden würde). Auf diese Interrupts kann man reagieren, indem man bestimmte ISR (Interrupt-Service-Routinen) in sein Programm einbaut, also z.B. SIGNAL (SIG_OVERFLOW0) { } um mal beim 8-Bit-Timer zu bleiben. Der Sinn solcher Funktionen liegt nun darin, das gerade laufende Programm zu unterbrechen (deshalb Interrupt = Unterbrechung), weil eben was Wichtiges passiert ist und den in der ISR definierten Code auszuführen. Anschliessend macht das Programm an der Stelle weiter, an der es unterbrochen wurde. Ein C-Programm sieht also dann in etwa so aus: void main (void) { // Schleife die immer läuft for (;;) { } } SIGNAL (interruptkennung) { // mach was :=) Ports lesen Ports schreiben usw. [...] } Pausen (respektive irgendwelche Zählschleifen) sollte man in seinem Programm möglichst vermeiden. Der Prozessor hat meist genug zu tun, als sich mit solchen (meist sinnlosen) Dingen aufzuhalten. Dann sind plötzlich nämlich auch die kleineren unter ihnen ganz schnell. ;o) Joline
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.