Datum: 07.05.2008 17:45
Bin noch neu beim AT91SAM7X und bitte die triviale Frage nach der Realisierung eines Interrupts zu entschuldigen, aber ich finde im Netz einfach keine Anleitung für Dummies. Wenn der Joystick links gedrückt wird (PA15), soll die LED (PB21) per externem Interrupt angehen (von "Hand" setzen der LED mit AT91C_BASE_PIOB->PIO_CODR=AT91C_PIO_PB21 funktioniert und den Joystick mit AT91C_BASE_PIOB->PIO_PDSR&AT91C_PIO_PA23 abfragen klappt auch). Folgender Code mit Interrupt (der nicht beim Tastendruck aufgerufen wird) funktioniert leider nicht: #include "AT91SAM7X256.h" //+************************************************************************************* void ex_int_handler (void) { unsigned int dummy; //status lesen um INT zu löschen dummy = AT91C_BASE_PIOA->PIO_ISR; AT91C_BASE_PIOB->PIO_CODR= AT91C_PIO_PB21; //led einschalten //printf("Interrupt occured\r\n\r"); *AT91C_AIC_EOICR = 0; /* Ende des Interrupts*/ AT91C_BASE_AIC->AIC_EOICR = 0; } //+************************************************************************************* int main(void) { AT91C_BASE_PIOB->PIO_OER=LED1; AT91C_BASE_PIOB->PIO_SODR = LED1; AT91C_BASE_PIOA->PIO_PDR=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_ODR=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_CODR=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_PPUER=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_ASR=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_OWDR=AT91C_PIO_PA23; AT91C_BASE_PIOA->PIO_IER=AT91C_PIO_PA23; AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE|0; AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned int)ex_int_handler; AT91C_BASE_AIC->AIC_IECR=(1<<AT91C_ID_PIOA); while(1); return 0; } Wäre supertoll, wenn jemand den Code komplettieren würde (irgend etwas fehlt bestimmt) oder einen Link auf einen funktionierenden setzen könnte...
Datum: 08.05.2008 12:31
Im Moment teste ich
void ex_int_handler (void)
{
volatile unsigned int dummy;
dummy = 135;
printf("Ein Interrupt trat auf");
dummy =AT91C_BASE_PIOB->PIO_ISR;
dummy =dummy;
AT91C_BASE_AIC->AIC_IVR = 0;
AT91C_BASE_AIC->AIC_ICCR = AT91C_ID_SYS;
AT91C_BASE_AIC->AIC_EOICR = 0;
}
und
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA);
AT91C_BASE_PIOA->PIO_ODR = INTTAST;
AT91C_BASE_PIOA->PIO_PER = INTTAST;
AT91C_BASE_PIOA->PIO_SODR=INTTAST;
AT91C_BASE_AIC->AIC_IDCR=(1<<AT91C_ID_PIOA);
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned int)ex_int_handler ;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE|AT91C_AIC_PRIOR_LOWEST;
AT91C_BASE_AIC->AIC_ICCR=(1<<AT91C_ID_PIOA);
AT91C_BASE_PIOA->PIO_IER=INTTAST;
AT91C_BASE_AIC->AIC_IECR=(1<<AT91C_ID_PIOA);
aber die Zuweisung AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned
int)ex_int_handler; scheint irgendwie den Interrupt aufzurufen (Ausgabe
"Ein Interrupt trat auf") und dann bleibt das Programm auch irgendwie im
Interrupt hängen und kommt nicht weiter in die Hauptprogrammschleife.
Alleine schaffe ich das wohl wirklich nicht und bräuchte einen Hinweis
(oder Link zu einem lauffähigen Ext-Interrupt-Sample oder einer leicht
verständlichen Doku zum Thema).
Datum: 08.05.2008 12:37
im Anhang ein Beispiel-Projekt (allerdings für iar workbench). gruss gerhard
Datum: 08.05.2008 13:39
Tja, da müßte ich meinen Chef schon überreden können, das Geld für den
Compiler auszugeben...
Das Anpassen allein schon von __ramfunc mit #define RAMFUNC
_attribute_ ((long_call, section (".ramsection"))) und Anpassen des
Linkers mit
.data : AT (_etext)
{
_data =3D . ;
KEEP(*(.vectram)) /* added by mthomas */=09
*(.data)
SORT(CONSTRUCTORS)
. =3D ALIGN(4);
*(.ramsection) /* here your ramsection will be located */
} >DATA
. =3D ALIGN(4);
klappt bei mir nicht wirklich (von den ganzen, übrigen Anpassungen für
den gcc ganz abgesehen...) :(
Aber vielleicht liest den Thread hier ja noch jemand, der mit dem gcc
einen externen Interrupt hinbekommen hat...
Datum: 09.05.2008 14:37
Weiß inzwischen zwar woran es liegt (an ethernut; brauche ich leider wegen tcpip) kann es aber auch nicht ändern, weil das ethernut und die dort veränderten Interruptregister für mich nicht mal eben in ein paar Stunden zu durchschauen sind. Ohne ethernut läuft bei mir folgendes Mini-Testprogramm jetzt:
void ex_int_handler (void) { volatile unsigned int dummy; dummy = AT91C_BASE_PIOA->PIO_ISR; AT91C_BASE_AIC->AIC_EOICR=AT91C_BASE_TC0->TC_SR; AT91C_BASE_AIC->AIC_ICCR=(1<<AT91C_ID_TC0); *AT91C_AIC_EOICR=0; AT91C_BASE_PIOB->PIO_CODR=AT91C_PIO_PB19;// LED1 hier zum Int.-Test anmachen AT91C_BASE_AIC->AIC_EOICR = 0; } |
und in
main(){
...
AT91C_BASE_PIOA->PIO_PER=INTTAST;
AT91C_BASE_PIOA->PIO_ODR =INTTAST;
AT91C_BASE_PIOA->PIO_CODR=INTTAST;
AT91C_BASE_PIOA->PIO_PPUER=INTTAST;
AT91C_BASE_PIOA->PIO_ASR=INTTAST;
AT91C_BASE_PIOA->PIO_OWDR=INTTAST;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 0;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned int)ex_int_handler;
AT91C_BASE_PIOA->PIO_IFER=INTTAST;
int io_status = AT91C_BASE_PIOA->PIO_ISR;
AT91C_BASE_AIC->AIC_IECR=(1 << AT91C_ID_PIOA);
AT91C_BASE_PIOA->PIO_IER=INTTAST;
...
while(1){
... // hier LED2 blinken lassen
}
|
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel