Hi Leute Ich versuche gerade mit einem AT90s8515 serielle Übertragung hinzubekommen. Und zwar mit dem Receive Complete Interrupt. Das Problem ist, dass der Interrupt nicht einmal aufgerufen wird. So wie das Programm jetzt aussieht blinken 3 LEDs an PORTD Pin 5-7. Der Interrupt sollte als erstes diese LEDs ausschalten, aber nicht einmal das passiert! Das Programm "hängt sich auf". Die LEDs bleiben an und nichts geschieht mehr. Ich hab schon im Forum gesucht, allerdings haben mir die gefundenen Antworten nicht wirklich weiter geholfen. Vielen Dank schonmal für eure Hilfe! Benjamin
So ganz blicke ich mit der Mimik deiner LEDs nicht durch. Du lässt sie in main() blinken, in der ISR aber auch -- wie willst Du da auseinanderhalten, wer wann was macht? Die Abarbeitungszeit der ISR ist so kurz, dass du das Ein- und Ausschalten (ich weiß gar nicht, welche Polarität bei Dir was macht, in der Regel sind LED-Ausgänge low-aktiv) innerhalb der ISR nie und nimmer beobachten kannst. Außerdem, typischer Fehler: volatile beim Schreib- und Lesezeiger vergessen (buf_read, buf_write). Für eine sinnvolle Verzögerung benutze besser die Funktionen aus <avr/delay.h>.
So ganz schlau werde ich aus deinen Beitrag auch nicht. Schaue dir mal das Ding im Anhang an, dies waren so meine ersten schritte. Häng doch mal in den eventhandler für das von Dir genannten Int eine warteschleife ?! Vielleicht siehst Du ja dann auch die LED mal kurz aufblinken. Das Blinken solltest Du generell mal sein lassen, wenn du Dir die UDR auslesung aneignen willst, ich glaub das verwirrt dich ein wenig. Irgendjemand hier aus dem Forum sagte mal. Lerne C lerne Debuggen ( oder so ähnlich )
Hey vielen Dank für die schnelle Antwort. Das Problem hab ich grad selber gelöst. Die Sache war die, dass ich ITNERRUPT verwendet hatte. Es hätte aber SIGNAL heißen müssen. So wurde der Interrupt scheinbar immer wieder aufgerufen, während die ISR noch lief. Zumindest wenn ich den Unterschied zwischen INTERRUPT und SIGNAL richtig verstanden haben. Zu den LEDs: das ganze war so gedacht, dass ich durch das Blinken erstmal die Bestätigung hatte, dass das Programm überhaupt läuft. Danach habe ich versucht herauszufinden inwiefern die ISR überhaupt arbeitet. (Mir war klar, dass sie irgendwo hängen bleibt... Die LEDs haben nicht weiter geblinkt) Deshalb hab ich nach jedem Schritt in der ISR eine LED angschaltet, um zu sehen wo es hängen bleibt. Dumme Frage: (ich bin noch neu ich C) Was heißt volatile, bzw. was bewirkt es? Das mit dem delay wusst ich noch nicht. Danke. Benjamin PS: Bist du DER Jörg Wunsch? Der (Mit)Entwickler von AVR-libc? :-)
Hi, hier ist ein gutes Openbook da sollten einige Fragen beantwortet werden. http://www.pronix.de.speedpartner.de/modules/C/openbook/
Sorry, das mit dem INTERRUPT hätte ich natürlich sehen sollen. Ja, INTERRUPT statt SIGNAL in einer UART-ISR ist komplett tödlich. Sofort nach dem SEI im Prolog der ISR (das in diesem Falle bereits vom Compiler erzeugt wird) löst die Hardware einen neuen Interrupt aus, sodass diese verschachtelt werden ad nauseum. Das hängt damit zusammen, dass das hardwareseitige `interrupt pending' flag nicht (wie teilweise bei anderen Interrupts üblich) bereits beim Eintritt in die ISR gelöscht wird sondern erst beim Lesen (bzw. Schreiben beim Sender-Interrupt) von UDR. > Was heißt volatile, bzw. was bewirkt es? Die genaue Definition lässt sich im C-Stanard nachlesen. Effektiv bewirkt es, dass Zugriffe auf eine derart gekennzeichnete Variable nicht mehr optimiert werden, sondern immer ausgeführt. In deinem Falle manipulierst du eine der Indexvariablen in einer ISR, aber die Codeflussanalyse im Hauptprogramm merkt natürlich davon nichts. Folglich könnte sie Zugriffe auf diese Variable u. U. komplett optimieren (bspw. aus Schleifen herausziehen), da sich die Variable nach Meinung des Optimizers ja ohnehin nicht ändern kann. Das hat natürlich auch einen negativen Seiteneffekt. Die Variable wird dann wirklich jedesmal von ihrer Speicherstelle eingelesen, auch innerhalb der ISR, wo sich ihr Wert ja wirklich nicht geändert haben kann. Besser als Deine Version wäre dann das Cachen in einer temporären Variable innerhalb der ISR (das wird dann typisch ein Register sein): SIGNAL(SIG_UART_RECV) { uint8_t buf_write_local = buf_write; // Hier ggf. auf Pufferüberlauf testen buffer[buf_write_local] = UDR; if (++buf_write_local >= MAXBUFFER) buf_write_local = 0; buf_write = buf_write_local; } > Bist du DER Jörg Wunsch? Ganz bestimmt. Wer denn sonst? :-) DIE Jörg Wunsch jedenfalls nicht. ;-) > Der (Mit)Entwickler von AVR-libc? *Mit*Entwickler, ja, wohl mittlerweile. Der Entwickler der avr-libc war/ist Marek Michalkiewicz, auch wenn er mittlerweile nicht mehr ganz so aktiv ist.
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.