Hallo allerseits, folgendes Problem: Daten die über die serielle Schnittstelle den MC erreichen sollen ans Display geschrieben werden. Das geht mit folgendem CODE Schnipsel prima: SIGNAL(SIG_UART_RECV) { putchar_lcd(inp(UDR)); } Warum aber hauts nicht hin wenn man anstelle von SIGNAL INTERRUPT schreibt?? Die Zeichen kommen so langsam an den MC dass die Displayroutine mit Sicherheit abgearbeitet ist bevor das nächste byte kommt.... Freu mich auf eure Antworten!! Vielen Dank Christian
> Warum aber hauts nicht hin wenn man anstelle von SIGNAL INTERRUPT > schreibt? Weil Du den Unterschied zwischen beiden entweder nicht verstanden hast und/oder das Datenblatt nicht richtig gelesen. Besonders SIG_UART_RECV ist absolut ungeeignet für INTERRUPT(), das das schlagartig zu einer endlosen Rekursion führt.
ma ne frage ich hab bisher angenommen, das es kein unterschied gibt zw interrupt und signal kann mich ma einer aufklären MfG eugen
Hab gerade mal die AVR-Libc durchgeschaut. Hab aber keine eindeutige zuweisung gefunden. Aber grundsätzlich: Wenn ich mich nicht täusche, so ist Signal() ein ganz normaler Interrupt. Wenn du jedoch Interrupt() schreibst, so ist der erste ASM-Befehl in der Routiene sei. Also gleich nach dem Betreten der Interruptschleife werden die Interrupts wieder freigegeben. Wenn aber das Interrupt-Flag von der Hardware noch nicht gelöscht wurde, so wird der Interrupt sofort wieder aufgerufen. Das geht so lange bis dein Stack überläuft. Ich weiß nicht wozu man die Interrupt() braucht, ich habs bis jetzt immer von Hand gemacht: Interruptroutiene mit Signal(), dann das dazugehörige Interrupt-Flag gelöscht und erst dann wieder eine Globale Interruptfreigabe. Gruß, Florian
> Aber grundsätzlich: Wenn ich mich nicht täusche, so ist Signal() ein > ganz normaler Interrupt. Wenn du jedoch Interrupt() schreibst, so > ist der erste ASM-Befehl in der Routiene sei. Genau so ist es (außer daß sich beide komplett GROSS schreiben -- C unterscheidet zwischen Groß-/Kleinschreibung). Ich verstehe auch gar nicht, warum das aus der Doku so schwierig herauszulesen sein soll: SIGNAL(): Introduces an interrupt handler function that runs with global interrupts initially disabled. INTERRUPT(): Introduces an interrupt handler function that runs with global interrupts initially enabled. This allows interrupt handlers to be interrupted. > Ich weiß nicht wozu man die Interrupt() braucht, ... Die Grundregel #1 ist: wenn Du nicht weißt, wofür Du es brauchst, dann brauchst Du es nicht. ;-) In der Tat braucht man das wohl eher für Spezialfälle, bei denen man keine Zeit damit vergeuden will, die Interrupts sofort wieder freizugeben, um andere (zeitkritische) Interrupts nicht zu verzögern. Logischerweise kann man es nur bei Interrupts benutzen, die sich nicht aufgrund des Hardware-Flags sofort wieder selbst auslösen würden. Meiner Meinung nach sind sie etwas unglückselig benannt, so daß zu viele Leute geneigt sind, INTERRUPT() überhaupt in Betracht zu ziehen.
Hallo zusammen und vielen Dank für eure Antworten!!! ich konnte das Problem jetzt recht erfolgreich ohne "Interrupt" (sondern mit Signal) lösen, allerdings ist mir immer noch nicht klar warums nicht funktioniert hat, auch wenn ich innerhalb der Interrupt routine lediglich den Empfangswert der seriellen schnittstelle in eine andere Variable kopiert habe?? Macht aber nix - brauchs ja jetzt nicht mehr ..... Danke für eure Hilfe und alles Gute fürs neue Jahr!! Christian
> ich konnte das Problem jetzt recht erfolgreich ohne "Interrupt" > (sondern mit Signal) lösen, allerdings ist mir immer noch nicht klar > warums nicht funktioniert hat, auch wenn ich innerhalb der Interrupt > routine lediglich den Empfangswert der seriellen schnittstelle in > eine andere Variable kopiert habe? Weil Du nur mit trial & error arbeitest und leider immer noch nicht verstanden hast, was Du denn überhaupt tust. ,,lediglich den Empfangswert ... kopiert'' ist halt exakt die Operation (lesen von UDR), die die anhängige Interruptbedingung wieder zurücknimmt. Wenn Du zuvor aber bereits die globalen Interrupts wieder freigibst (wie es in INTERRUPT() ja passiert), dann wird sofort nach dem SEI ein neuer Interrupt ausgelöst (für das gleiche Ereignis), was unweigerlich zum Stacküberlauf führt.
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.