Forum: Mikrocontroller und Digitale Elektronik SAM7-EX256 Interrupt


von Henk (Gast)


Lesenswert?

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

von R.Freitag (Gast)


Lesenswert?

Ich habe das nicht verstanden: du möchtest eine ISR aufrufen, wenn eine 
Nachricht eingegangen ist?

Gruss

Robert

von Henk (Gast)


Lesenswert?

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

von R.Freitag (Gast)


Lesenswert?

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

von Henk (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.