Hi.. I am trying to blink an led using a timer interrupt. Connected the led to P0.0 and the code is as shown below. Is there any problem with the code??
#include<lpc21xx.h> void __irq timer0(void); void timersetup(void); int main() { PINSEL0 = 0x00000000; PINSEL1 = 0x00000000; IODIR0 = 0x01; IOSET0=0x01; timersetup(); while(1); } void timersetup(void) { VICIntSelect=0x0; VICVectCntl0=0x20|4; VICVectAddr0=(unsigned long)timer0; VICIntEnable=(1<<4); T0TCR = 0x02; //Reset the timer0 T0PR=0x00; //Set prescaler to 0 T0MR0=0x0FFF; //Match register value T0IR=0x01; //Clear match0 interrupt T0MCR= 0x03; //Enable interrupt on MR0 and enable Reset on MR0 T0TCR = 0x01; //Start timer0 } void __irq timer0(void) { IOPIN0^=0x01; //Toggle LED on p0.0 VICVectAddr=0; T0IR=0x01; //Reset match0 interrupt }
Breakdown the problem, and debug it
Can you toggle the LED? Does the timer tick? Do you get an interrupt?
Yes... Broke down the problem. Wanted to check whether pieces of the code were working.. But i am not sure if timer is ticking or not. I have referred to other threads and made changes to the code, but it is still not working.
So that's where you need to concentrate your debugging efforts, then - isn't it?
Well, Andrew, I checked whether there is any problem with the interrupt routine. I triggered the irq using software interrupt for timer, introducing a delay as shown below. It worked, and the led blinks beautifully. Then on going back to timer code and on step by step debugging, the code enters the irq, but the led is not blinking on the hardware. It justs stays in on condition.
#include<lpc21xx.h> void delay10ms(unsigned char); void __irq timer0(void); void timersetup(void); int main() { PINSEL0 = 0x00000000; PINSEL1 = 0x00000000; IODIR0 = 0x01; IOSET0=0x01; timersetup(); while(1) { VICSoftInt = 0x00000010; //IOPIN0^=0x01; delay10ms(100); } } void delay10ms(unsigned char val) { unsigned int j; unsigned char i; for(;val>=1;val--) { for(j=0;j<1623;j++) for(i=10;i>=1;i--); } } void timersetup(void) { VICIntSelect=0x00000000; VICVectCntl0=0x20|4; VICVectAddr0=(unsigned long)timer0; VICIntEnable=(1<<4); /* VPBDIV=0x01; T0PR=0x00; T0MR0=0x00000FFF; T0MCR= 0x03; T0TCR = 0x01; */ } void __irq timer0(void) { IOPIN0^=0x01; VICSoftIntClr=(1<<4); VICVectAddr=0x0; // T0IR=0x01; }
Try this:
void timersetup(void) { T0MR0=0x1FFFFFF; // Match register value, Try a larger number void Timer0Handler (void) __irq { T0IR = 1; /* clear interrupt flag */ timer0_counter++; VICVectAddr = 0; /* Acknowledge Interrupt */ }
Sorry John. I forgot to mention that I got it working, but the problem was in how the delay was set up, and you are right of course. I loaded my code using ISP so Fosc was set to 10 to 25Mhz. I read up on PLL and configured the PLL for 12Mhz, and now the LED is blinking ok. I have not made any other major change to the code, and the below code works correctly. It provides 1 sec delay. Thanks everyone for your help and prompt reply. I really appreciate it!!
Details for the code are: For PLL: M=1, P=8... Selected cclk=12Mhz and Fosc=12Mhz.. Refer to datasheet of lpc2129 for details on configuring PLL. Selection of Fosc is also given there.
As clock is 12Mhz, 1 tick=1/12MHz= 0.083 microseconds. So for 1 ms, no.of ticks= 1ms/.083us=12048192 (dec) = 0xB7D740 (hex).. I hav given this value in T0MR0 for matching to the timer. Checked and confirmed that 1s delay occurs.
Thanks again... :-)
#include<lpc21xx.h> void init_pll(void); //initialise PLL void __irq timer0(void); //Interrupt routine for timer0 void timer_setup(void); //Setup timer int main() { VPBDIV= 0x01; init_pll(); timer_setup(); PINSEL0 = 0x00000000; IODIR0 = 0x01; //LED connected to P0.0 while(1); } void init_pll(void) { PLLCFG = 0x60; //For 12Mhz operation: M=1,P=8 PLLCON = 0x01; //Enable PLL while(!(PLLSTAT & 0x00000400)); //Check for lock condition (bit 10) PLLCON = 0x03; //Enable and connect PLL PLLFEED = 0x0AA; //Write to PLLFEED to activate PLL PLLFEED = 0x055; //Same as above.. Mandatory steps. } void timer_setup(void) { T0PR = 0x00; //Prescaler to 0. Timer same as cclk T0MR0 = 0xB7D740; //For 12 Mhz operation T0MCR = 0x03; //Select interrupt and reset bits in register T0TCR = 0x01; //Enable the timer VICIntSelect = 0x00000000; //All IRQ VICVectCntl0 = 0x20|4; //Select timer0 interrupt with highest priority VICVectAddr0 = (unsigned long)timer0; //Assign address for timer0 VICIntEnable = (1<<4); //Enable timer0 interrupt } void __irq timer0(void) { T0IR = 0x01; //Clear Timer interrupt IOPIN0 ^= 0x01; //Toggle LED VICVectAddr=0x0; //Reset interrupt }
Hopes this helps others.. Will come soon with some other doubt!! ;-)