We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi everybody! I need some help. I 'm trying to blink a led by using Timer0 and an IRQ Routine on a LPC2129. I know my Timer work well (bit 0 in TOIR is generated about 900ms) But I don't understand why it never launch my ISR routine. I put a breakpoint and it never go there.
Maybe someone can help me to resolve it! he would be nice! Thank you.
#include <stdlib.h> #include <LPC23xx.H> #define Fpclk 12000000 char data; void TIMER1_ISR(void) __irq { //VICSoftIntClear=0xFFFFFFFF; //Clear all interrupts T0IR = 0x01; // set match 0 T0TCR=0x03; //counter reset if(IOSET1==0x10000){ IOCLR1 = 0x10000; } else if (IOCLR1==0x10000){ IOSET1 = 0x10000; } } int main( void ){ IODIR1 = 0x10000; //init VIC VICIntSelect=0x00000000; //all interupts: IRQ VICIntEnable=0xFFFFFFFF; //all interupts : enabled VICVectCntl4=0x00000014;//Uart interupt selected and enbled VICVectAddr4 = (unsigned long)TIMER1_ISR; //adress of the irq routine PCONP=0x02; //do not activate power saving T0MR0 = Fpclk - 1; // when T0TC arrived to 1 seconde (12000000 ticks) , the match between T0TC and T0MR0 do an interuption T0PR = 0x00; //1 incrementation every tick T0MCR = 0x07; //stop ,reset,interuption enabled when timer 0 match to match0 */ T0TCR = 0x01; //start counter while(1); }
It goes to my ISR routine only one time! I would like to make it periodic! Do you know what is the problem?
#include <LPC23xx.H> #define Fpclk 12000000 void TIMER1_ISR(void) __irq { //VICSoftIntClear=0xFFFFFFFF; //Clear all interrupts T0IR = 0x01; // set match 0 if((IOPIN1<<16)==1){ IOCLR1 = 0x10000; } else if ((IOPIN1<<16)==0){ IOSET1 = 0x10000; } T0TCR=0x02; //counter reset T0TCR=0x01; //counter start VICVectAddr = 0x00;/* Dummy write to ACK the VIC */ } int main( void ){ IODIR1 = 0x10000; //init VIC VICIntSelect=0x00000000; //all interupts: IRQ VICIntEnable=0xFFFFFFFF; //all interupts : enabled VICVectCntl4=0x00000024;//timer interupt selected and enbled VICVectAddr4 = (unsigned long)TIMER1_ISR; //adress of the irq routine PCONP=0x02; //do not activate power saving T0MR0 = Fpclk - 1; // when T0TC arrived to 1 seconde (12000000 ticks) , the match between T0TC and T0MR0 do an interuption T0PR = 0x00; //1 incrementation every tick T0MCR = 0x07; //stop ,reset,interuption enabled when timer 0 match to match0 */ T0TCR = 0x01; //start counter while(1); }
You want a continuous sequence of interrupts from the timer?
So why then do you configure it to generate a single interrupt and then stop?
You do:
T0MCR = 0x07; //stop ,reset,interuption enabled when timer 0 match to match0 */
Why?
Why not just set T0MCR = 3 so the timer counts for one second? Then generates an interrupts and at the same time restarts ticking from zero again.
It should be enough to have your ISR only doing the following:
void my_isr(void) __irq { // do stuff ... T0IR = 1; // Clear interrupt flag VICVectAddr = 0xff; // Acknowledge Interrupt }
Another thing. Why do you enable _all_ interrupts, when your only goal is to allow interrupts from a single timer?
VICIntEnable=0xFFFFFFFF;
Don't enable something you are not going to use.
I have done all the modifications you told me. T0TC always count. But the problem is still here. The program goes to My ISR routine only once! I work with te keil simulator.
Look at this ways:
When "T0TC" match with "T0MR0". An interrupt is create in T0IR:TOIR: 0x01000000 When i look to the datasheet It's T0CR2!!!!!!!
I don't understand, it should be : TOIR: 0x00000001 which correspond to T0MR0 interrupt.
Nevertheless, when When "T0TC" match with "T0MR0" for the first time,TOIR: 0x01000000, the program goes into the ISR routine.
when When "T0TC" match with "T0MR0" for the second time.TOIR: 0x01000000, the program doesn't go into the ISR routine. And T0TC never stop to count!!!!
T0IR:0xE0004000 T0TC:0xE0004008
#include <LPC23xx.H> #define Fpclk 12000000 void TIMER1_ISR(void) __irq { if((IOPIN1<<16)==1){ IOCLR1 = 0x10000; } else if ((IOPIN1<<16)==0){ IOSET1 = 0x10000; } //T0TCR=0x02; //counter reset //T0TCR=0x01; //counter start //VICSoftIntClear=0xFFFFFFFF; //Clear all interrupts T0IR = 0x01; // set match 0 VICVectAddr = 0xff;/* Dummy write to ACK the VIC */ } int main( void ){ IODIR1 = 0x10000; //init VIC VICIntSelect=0x00000000; //all interupts: IRQ VICIntEnable=0x00000010; //TMR0 interupt : enabled VICVectCntl4=0x00000024;//timer interupt selected and enbled VICVectAddr4 = (unsigned long)TIMER1_ISR; //adress of the irq routine PCONP=0x02; //do not activate power saving T0MR0 = Fpclk - 1; // when T0TC arrived to 1 seconde (12000000 ticks) , the match between T0TC and T0MR0 do an interuption T0PR = 0x00; //1 incrementation every tick T0MCR = 0x03; //stop ,reset,interuption enabled when timer 0 match to match0 */ T0TCR = 0x01; //start counter while(1); }
Time to compare your header files. Do they specify the correct register addresses and bits for the timer?
Keil have goofed before. And I work with LPC23xx - not LPC21xx.
Wow - just noticed something.
You say you have a LPC2129.
But why then do you use the include file #include <LPC23xx.H>?
The LPC23xx is a newer processor family that just happens to be very similar since most of the peripherials are supersets of the LPC21xx functionality for ease of migration.
Of course your program doesn't work as it should. You have just been unlucky that it seemed to _almost_ work.
Yeah, it works well!!! Thanks "Per Westermark" i'm going to make a little sheduler now!
here is my code:
#include <LPC21xx.H> #define Fpclk 12000000 void TIMER1_ISR(void) __irq { if(((IOPIN1&0x10000)>>16)==1){ IOCLR1 = 0x10000; } else if (((IOPIN1&0x10000)>>16)==0){ IOSET1 = 0x10000; } T0IR = 0x01; // set match 0 VICVectAddr = 0xff;/* Dummy write to ACK the VIC */ } int main( void ){ IODIR1 = 0x10000; //init VIC VICIntSelect=0xFFFFFFEF; //TMR0 interupt: IRQ VICIntEnable=0x00000010; //TMR0 interupt : enabled VICVectCntl4=0x00000024;//timer interupt selected and enbled VICVectAddr4 = (unsigned long)TIMER1_ISR; //adress of the irq routine PCONP=0x02; //do not activate power saving T0MR0 = Fpclk - 1; // when T0TC arrived to 1 seconde (12000000 ticks) , the match between T0TC and T0MR0 do an interuption T0PR = 0x00; //1 incrementation every tick T0MCR = 0x03; //stop ,reset,interuption enabled when timer 0 match to match0 */ T0TCR = 0x01; //start counter while(1); }