Hallo zusammen, ich beschäftige mich seit ein paar Wochen mit dem SAM7-EX256 Board von Olimex. Die ersten Programme konnte ich auch schon zum laufen bringen... Ich habe nun holgendes Problem: Ich möchte die CAN Schnittstelle mit Interrupt Inbetrieb nehmen (z.B. soll eine Interrupt Service Routine (ISR) nach erfolgreicher Übertragung aufgerufen werden). Zur Initialisierung verwende ich meine eigene can.h / can.c. Alle Funktionen sind bereits ohne Interrupt getestet und funktionieren! Die Einbindung des Interrupts schien anfangs auch recht schnell zu klappen. Bei der Übermittlung einer CAN-Nachricht wird die ISR aufgerufen und ausgeführt - ABER: der Rücksprung ins Hauptprogramm erfolgt nicht an die richtigen Adresse und mein Board befindet sich an einer beliebigen Stelle in einer Endlos-Schleife. Wie schaffe ich es, dass das Hauptprogramm an der richtigen Stelle wieder fortgesetzt wird? Meine Init: int CAN_Init(void) { ... //Interrupt Init CAN_IER = iIntMask; AIC_ConfigureIT(AT91C_ID_CAN0,AT91C_AIC_PRIOR_HIGHEST|(1<<5), CAN0_Handler); AIC_EnableIT(AT91C_ID_CAN0); // Enable CAN CAN_MR |= 0x1; //AT91C_BASE_CAN->CAN_MR = AT91C_CAN_CANEN; } und meine ISR void CAN0_Handler(void) { volatile unsigned int i; i=AT91C_BASE_AIC->AIC_IVR; ... //to do AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_CAN0); AT91C_BASE_AIC->AIC_EOICR = 0; } Bin trotz intensiver Suche im Forum noch nicht auf eine Lösung gestossen und kann jede Hilfe gebrauchen! Danke schon mal im Voraus! Gruß Henk
Ich habe das nicht verstanden: du möchtest eine ISR aufrufen, wenn eine Nachricht eingegangen ist? Gruss Robert
Hallo Robert, Ja, ich möchte später einmal eine ISR bei Eingang einer Nachricht ausführen. Zur zeit teste ich aber meine ISR (mein "to do" in der ISR ist im Moment nur USART0_WRITE("Interrupt!")). Dies geht am einfachsten indem ich eine CAN-Nachricht rausschicke. Sobald eine Nachricht übermittelt wurde, wird ein Interrupt automatisch ausgelöst. Dies funktioniert bereits. Der Interrupt wird ausgelöst, die ISR wird ausgeführt, aber der Rücksprung geht nicht an die richtige Stelle. Da ich bei der Abhandlung der ISR genau nach Datenblatt vorgehe, vermute ich, dass ich eventuell bei der Initialisierung etwas falsch mache oder vergesse. Werde demnächst mal die vorgegebenen AIC_ConfigureIt(), AIC_EnableIT() durch meine eigene Interrupt_Init() ersetzen - vielleicht funktionierts dann... Gruß Henk
Eigebntlich erwarte ich, daß der Programmablauf da fortgesetzt wird, wo der Einsprung erfolgte. Ist denn der Stack initialisiert worden, und wird der Stack in der ISR richtig behandelt? Gruss Robert
Hallo, Zuerst auf deine Frage:
1 | Ist denn der Stack initialisiert worden, und wird der Stack in der ISR richtig behandelt? |
Ich verwende zur Programmierung des AT91SAM7X256 das Originalfile von Keil - ich gehe davon aus, dass dort alle Adressen und Bereiche richtig definiert sind. Gestern habe ich mal probiert die AIC-Register selber zu intialisieren (ohne die Software von Atmel zu verwenden) und siehe da der Rücksprung aus der ISR geht nun an die richtige Stelle. Lag wohl doch an der Initialisierung... Zur Zeit habe ich noch das Problem, dass die ISR nur beim ersten Interrupt aufgerufen wird. Bei weiteren Interrupts passiert gar nix. Ich teste jetzt erstmal alle Flags, die eventuell noch gelöscht werden müssen (das sollte nicht allzu viel Zeit in Anspruch nehmen!) Viele Grüße Henk
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.