Hallo, ich schreibe an einem Programm, wo ich 2 timer von LPC2468 benutze, der Timer 1 sollte einen FIQ auslösen, der die ISR (IRQ) von Timer 2 unterbricht und seinen Timer Counter zurücksetzt,der FIQ von Timer 1 funktioniert einwandfrei aber die ISR von Timer 2 wird nicht ausgeführt, hat jemand vielleicht eine Idee? die Init. Routinen von Timer ,FIQ und IRQ sind folgendes: /************************************************ TIMER 1 und der zugehörigen FIQ : /************************************************ #include "irq.h" // von Keil void init_timer1(void) { PCLKSEL0 &= (~(0x3<<4)); //PCLK = CCLK/4 PINSEL3 |= 0x000C0000; // set P1.25 to Match 1.1 T1CTCR = 0; // Timer mode T1PR = 144; //Load prescaler T1TCR = 0x00000002; //Reset TC and PR T1TC = 0; //Timer Counter: Set to zero T1MR0 = 62500; // Toggle by TC=MR0 (500ms) T1EMR = 0xC2; //Ext. mach reg. at match1.1 //and set to toggle P1.25 T1MR1=62500; //Interrupt by TC=MR1 (500ms) T1MCR=(3<<3)|(1<<1); //Reset timer on match and generate interrupt VICIntSelect |= 0x00000020; // Enable a VIC Channel as FIQ VICIntEnable |= 0x00000020; // Enable the Timer/counter1 interrupt in the VIC*/ } extern void FIQ_Handler(void) _attribute_ ((interrupt(""))); void FIQ_Handler(void) { time_ms += 1; //increment T2TC = 0; //Timer Counter 2: Set to zero T1IR |= 0x02; // clear interrupt flag on timer 1 } /*********************************************************** TIMER 2 und der zugehörigen IRQ: /*********************************************************** void init_timer2(void) { PCLKSEL1 = (PCLKSEL1 & (~(0x3<<12))) | (0x01 << 12); // PCLK= CCLK = 72MHz FIO0DIR |= 0x01; T2CTCR = 0; // Timer mode T2PR = 7; //load the prescal Register T2TCR = 0x00000002; //Reset TC and PR T2TC = 0; //Timer Counter: Set to zero T2MR0 = 1; // load MR0 (100ns) T2MCR = 0x01; // generate interrupt when TC = MR0 install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY ) ; } /*** extern void timer2_Handler(void) _attribute_ ((interrupt())); void timer2_Handler(void) { T2MR0 += 1; // load MR0 with new value /* 100 ns */ time_ns += 1; T2IR |= 0x01; // clear interrupt flag VICVectAddr = 0; //Acknowledge Interrupt } ich bin für jede Anweisung sehr dankbar.
ich möchte gerne wissen, warum ich hier keine Hilfe bekomme! und zwar jedesmal.....!!!!!!!!
> install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY )
timestamp_Handler ist nicht der Name deines Int. Handlers.
Hi! Hatte mit einem anderen LPC ein ähnliches Problem. Lösung war, dass ich verschachtelte Interrupts erst enablen musste. Von sich aus arbeitet der VIC kooperativ, d.h. eine ISR kann nicht unterbrochen werden. Schau mal nach der Funktion enableIRQ(), oder so ähnlich, findet man hier im Forum oder in diversen Beispielprogrammen. Gruß Jansus
Hallo, soweit ich weiss braucht man einen nested interrupt nur wenn man zwei IRQ ausführen muss...oder?
..und ein FIQ Interrupt kann doch einen IRQ unterbrechen ohne einen nested interrupt zu insatllieren..
nach dem FIQ Beispielprogramm vom LPC2300-Buch(Hitex) wird VICVectAddr nicht benötigt! und das ist auch logisch so, weil die FIQ`s vom VIC-Controller zum ARM Core nur weitgeleitet werden und nicht verarbeitet..
was ich jetzt gerne gewusst hätte ist, ob man einen nested Interrupt braucht wenn man FIQ und IRQ gleichzeitig verwendet... ich wäre sehr dankbar für eine Antwort..
Ja, Fehler von mir, der FIQ_Handler() braucht KEIN "VICVectAddr = 0;" War bei mir drinnen hat aber scheinbar nicht gestört ... FIQ und IRQ hab ich "gleichzeitig" in Betrieb ohne nested. Was ist mit: install_irq( TIMER2_INT, (void *)timestamp_Handler, HIGHEST_PRIORITY ) Wo ist hier der "timestamp_Handler", meckert da der Linker nicht ?
der startup code hätte ich vielleicht posten müssen: /*********************************************************************** ****** * * Project : lwIP Web * Subproject : * Name : Startarm.s * Function : Initialisation and vector table * Designer : K. Sterckx * Creation date : 22/01/2007 * Compiler : GNU ARM * Processor : LPC2368 * Last update : * Last updated by : * History : * ************************************************************************ ***** * * See linker script lpc2368_rom.ld for memory map * ************************************************************************ ****/ /*********************************************************************** ****** * * External references * ************************************************************************ ****/ /* * Located in linker script lpc2368_rom.ld */ .extern _data_beg_src_ .extern _data_beg_ .extern _data_end_ .extern _bss_beg_ .extern _bss_end_ .extern _stack_usr_top_ .extern _stack_scv_top_ .extern _stack_irq_top_ .extern _stack_fiq_top_ .extern _stack_und_top_ /* * Located in handlers.c */ .extern Undef_Handler .extern SWI_Handler .extern PAbt_Handler .extern DAbt_Handler .extern FIQ_Handler /* * Located in init_cpu.c */ .extern Init_Wait .extern Init_Clocks .extern Init_MAM .extern Init_Pins .extern Init_CPU .extern Init_Modules .extern Exit_Main /* * Located in main.c */ .extern main /*********************************************************************** ****** * * Definitions * ************************************************************************ ****/ /* * Standard definitions for Mode and interrupt bits in PSRs */ .equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 .equ Mode_SVC, 0x13 .equ Mode_ABT, 0x17 .equ Mode_UND, 0x1B .equ Mode_SYS, 0x1F .equ I_Bit, 0x80 .equ F_Bit, 0x40 /* * Definitions for IO registers */ .equ IOPIN0, 0xE0028000 .equ IODIR0, 0xE0028008 .equ IOPIN1, 0xE0028010 .equ IODIR1, 0xE0028018 .equ IOPIN2, 0x3FFFC054 .equ IODIR2, 0x3FFFC040 .equ IOPIN3, 0x3FFFC074 .equ IODIR3, 0x3FFFC060 .equ IOPIN4, 0x3FFFC094 .equ IODIR4, 0x3FFFC080 /* * PORT setup values */ .equ IOPIN0_VALUE, 0x00000000 .equ IODIR0_VALUE, 0xF0000000 .equ IOPIN1_VALUE, 0x00000000 .equ IODIR1_VALUE, 0x00000000 .equ IOPIN2_VALUE, 0x00000000 .equ IODIR2_VALUE, 0x00000000 .equ IOPIN3_VALUE, 0x00000000 .equ IODIR3_VALUE, 0x00000000 .equ IOPIN4_VALUE, 0x00000000 .equ IODIR4_VALUE, 0x00000000 /*********************************************************************** ****** * * Vector table * ************************************************************************ ****/ .section .startup,"ax" .arm .align 0 _vectors: B _reset_handler LDR PC,Undef_Addr LDR PC,SWI_Addr LDR PC,PAbt_Addr LDR PC,DAbt_Addr NOP /* Used for Checksum */ LDR PC,[PC,#-0x0120] LDR PC,FIQ_Addr Undef_Addr: .word Undef_Handler SWI_Addr: .word SWI_Handler PAbt_Addr: .word PAbt_Handler DAbt_Addr: .word DAbt_Handler /*FIQ_Addr: .word FIQ_Handler*/ FIQ_Addr: .word SyncFIQ_Handler /*********************************************************************** ****** * * Protection code * ************************************************************************ ***** * * Fill up to PROTECTION_CODE with 0xFF, make sure that PROTECTION_CODE is * on correct address. * * Change code to 0x87654321 to enable protection * ************************************************************************ ****/ .org 0x01FC, 0xFF PROTECTION_CODE: .word 0xFFFFFFFF .size _vectors, . - vectors /*********************************************************************** ***** * * Startup code * ************************************************************************ ****/ .org 0x0200 .arm .global _reset_handler _reset_handler: /* * Setup ports 0 and 1 in Slow mode */ /* LDR R1,=IOPIN0_VALUE LDR R0,=IOPIN0 STR R1,[R0,#0x0] LDR R1,=IODIR0_VALUE LDR R0,=IODIR0 STR R1,[R0,#0x0] LDR R1,=IOPIN1_VALUE LDR R0,=IOPIN1 STR R1,[R0,#0x0] LDR R1,=IODIR1_VALUE LDR R0,=IODIR1 STR R1,[R0,#0x0] */ /* * Setup ports 2,3 and 4 in Fast mode */ /* LDR R1,=IOPIN2_VALUE LDR R0,=IOPIN2 STR R1,[R0,#0x0] LDR R1,=IODIR2_VALUE LDR R0,=IODIR2 STR R1,[R0,#0x0] LDR R1,=IOPIN3_VALUE LDR R0,=IOPIN3 STR R1,[R0,#0x0] LDR R1,=IODIR3_VALUE LDR R0,=IODIR3 STR R1,[R0,#0x0] LDR R1,=IOPIN4_VALUE LDR R0,=IOPIN4 STR R1,[R0,#0x0] LDR R1,=IODIR4_VALUE LDR R0,=IODIR4 STR R1,[R0,#0x0] */ /* * Wait a moment so that ULink can interrupt use * This is done before the PLL is running, so the * clock is equal to the crystal frequency. */ LDR R0,=__stack_scv_top__ MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit MOV SP,R0 BL Init_Wait BL Init_Clocks BL Init_MAM BL Init_Pins /* * Setup stacks */ /* Undefined instruction -> Undefined mode, uses Undefined stack */ /*LDR R0,=__stack_und_top__ MSR CPSR_c, #Mode_UND|I_Bit|F_Bit MOV SP,R0 /* Abort (prefetch+data) -> Abort mode, uses Undefined stack */ MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit MOV SP,R0 /* FIQ -> FIQ mode, use FIQ stack */ LDR R0,=__stack_fiq_top__ MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit MOV SP,R0 /* IRQ -> IRQ mode, use IRQ stack */ LDR R0,=__stack_irq_top__ MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit MOV SP,R0 /* Supervisor mode, use supervisor stack */ LDR R0,=__stack_scv_top__ MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit MOV SP,R0 /* We keep running in supervisor mode */ /* * Initialize .data : Copy from Flash to RAM */ LDR R1,=__data_beg_src__ LDR R2,=__data_beg__ LDR R3,=__data_end__ LoopRel: CMP R2, R3 LDRLO R0, [R1], #4 STRLO R0, [R2], #4 BLO LoopRel /* * Initialize .bss : Make zero */ MOV R0, #0 LDR R1,=__bss_beg__ LDR R2,=__bss_end__ LoopZI: CMP R1, R2 STRLO R0, [R1], #4 BLO LoopZI /* * Initialize CPU */ BL Init_CPU BL Init_Modules /* * Enable interrupts */ MSR CPSR_c, #Mode_SVC /* * Jump to main */ BL main /* * Jump to Exit_Main */ BL Exit_Main /*********************************************************************** ***** * * Endless loop, normaly never executed * ************************************************************************ ****/ endless_loop: B endless_loop .size _reset_handler, . - _reset_handler /*********************************************************************** ***** * * End marker * ************************************************************************ ****/ .end
das was einen einen Fehler von mir beim posten: install_irq( TIMER2_INT, (void *)timer2_Handler, HIGHEST_PRIORITY )
ich komme langsam zum Verzweifeln, Leute ich brauche Hilfe..!
Funktioniert denn Deine IRQ alleine? Was macht install_IRQ genau? Tippe darauf, dass der Fehler im Zusammenhang mit dem VIC zu finden ist...
hallo, ja, die IRQ alleine funktioniert, die irq install macht folgendes: DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority ) { DWORD *vect_addr; DWORD *vect_prio; VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */ if ( IntNumber >= VIC_SIZE ) { return ( FALSE ); } else { /* find first un-assigned VIC address for the handler */ vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4); vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4); *vect_addr = (DWORD)HandlerAddr; /* set interrupt vector */ *vect_prio = Priority; VICIntEnable = 1 << IntNumber; /* Enable Interrupt */ return( TRUE ); } }
hmm, die VIC-Einstellung für meinen Timer0 schauen so aus: VICIntSelect = 0x00;//nur IRQ -hier muss entspr. Deiner FIQ ne 1 wo rein VICVectCntl0=0x20|4; // 4 = Timer0 VICVectAddr0=(unsigned long)timer0; // name der isr VICIntEnable = (1<<4); Bin mir nicht sicher ob das Deine Funktion auch macht... Hast mal mit nested probiert?
Mal ne ganz bloede Frage, bist Du sicher, dass der Timer 2 ueberhaupt laeuft? T0 und T1 sind nach Reset naemlich automatisch enabled, es koennte allerdings sein, dass man das fuer den T2 selbst machen muss. Die aelteren LPC2000 Modelle hatten nur T0 und T1. Alle neuen Peripherals des LPC2000 kommen aus Stromspargruenden nicht enabled aus dem Reset. Hab nicht den Code analysiert, ist mir nur so eingefallen. Robert Some additional info www.lpc2000.com see "Application Notes" compatibility
@ Robert Teufel: danke schön das war es! ich finde es echt schade das es im user manual unter Timer-Kapitel nichts darüber steht. danke nochmal!
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.