LPC timer interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC timer interrupts

5,960 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Sun Sep 06 12:50:52 MST 2015
I am very new at programming but using examples i am developing me own code. I am trying to set 16 bit timmer for increasing variable 'count' that I am using to display digit on 7 segment indicator. I am trying to get timer interrupt and at that moment increase variable 'count', but now it doesn't seem to work. Please find the code below:



#include "LPC11xx.h"                        /* LPC11xx definitions */
#include "timer16.h"
#include "clkconfig.h"
#include "gpio.h"

#include <cr_section_macros.h>
#include <NXP/crp.h>

__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#define LED_ON 0
#define LED_OFF 1

int main (void) {

  GPIOInit();
  long count;

  // Set port for LED to output
  // GPIOSetDir( LED_PORT, LED_BIT, 1 );
  GPIOSetDir( 2, 2, 1 );
  GPIOSetDir( 0, 7, 1 );
  GPIOSetDir( 0, 6, 1 );
  GPIOSetDir( 1, 8, 1 );
  GPIOSetDir( 3, 1, 1 );
  GPIOSetDir( 3, 2, 1 );
  GPIOSetDir( 3, 0, 1 );
  // Set port for input
  // GPIOSetDir( LED_PORT, LED_BIT, 0 );
  GPIOSetDir( 1, 10, 0 );

  // Initial variable values
  count=0;


  //Set up 16 bit timer
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);                                  //enable clock signal to 16 bit timer0 (sec 3.5.14)
  LPC_TMR16B0->PR           = 0x0;                                      //set prescaler max value, not used here (sec 18.7.4)
  LPC_TMR16B0->MCR          = 0x10;                                     //set for reset on counter match (sec 18.7.6)
  LPC_TMR16B0->CCR          = 0;                                        //set to timer mode (sec 18.7.11)
  LPC_TMR16B0->MR1          = 0x64;                                     //set value for period (sec 18.7.7)
  LPC_TMR16B0->TCR          |= 0x3;                                     //enable and reset counter (sec 18.7.2)
  LPC_TMR16B0->TCR          &= ~(0x2);                                  //clear reset bit (sec 18.7.2)

  while (1)                                   // Loop forever
  {

   // 7 SEGMENT INDICATOR CODES FOR DIFFERENT NUMBERS
   //1
      if (count==1) {
      GPIOSetValue( 2, 2, LED_OFF );
      GPIOSetValue( 0, 7, LED_OFF );
      GPIOSetValue( 0, 6, LED_OFF );
      GPIOSetValue( 1, 8, LED_ON );
      GPIOSetValue( 3, 0, LED_OFF );
      GPIOSetValue( 3, 1, LED_ON );
      GPIOSetValue( 3, 2, LED_OFF );
      }
   //2
      if (count==2) {
      GPIOSetValue( 2, 2, LED_ON );
      GPIOSetValue( 0, 7, LED_OFF );
      GPIOSetValue( 0, 6, LED_ON );
      GPIOSetValue( 1, 8, LED_ON );
      GPIOSetValue( 3, 0, LED_ON );
      GPIOSetValue( 3, 1, LED_OFF );
      GPIOSetValue( 3, 2, LED_ON );
      }
   //3
      if (count==3) {
      GPIOSetValue( 2, 2, LED_ON );
      GPIOSetValue( 0, 7, LED_OFF );
      GPIOSetValue( 0, 6, LED_ON );
      GPIOSetValue( 1, 8, LED_ON );
       GPIOSetValue( 3, 0, LED_ON );
       GPIOSetValue( 3, 1, LED_ON );
       GPIOSetValue( 3, 2, LED_OFF );
      }
   //4
      if (count==4) {
      GPIOSetValue( 2, 2, LED_ON );
      GPIOSetValue( 0, 7, LED_ON );
        GPIOSetValue( 0, 6, LED_OFF );
        GPIOSetValue( 1, 8, LED_ON );
      GPIOSetValue( 3, 0, LED_OFF );
       GPIOSetValue( 3, 1, LED_ON );
       GPIOSetValue( 3, 2, LED_OFF );
      }
   //5
      if (count==5) {
      GPIOSetValue( 2, 2, LED_ON );
       GPIOSetValue( 0, 7, LED_ON );
       GPIOSetValue( 0, 6, LED_ON );
       GPIOSetValue( 1, 8, LED_OFF );
       GPIOSetValue( 3, 0, LED_ON );
        GPIOSetValue( 3, 1, LED_ON );
       GPIOSetValue( 3, 2, LED_OFF );
      }
   //6
      if (count==6) {
      GPIOSetValue( 2, 2, LED_ON );
       GPIOSetValue( 0, 7, LED_ON );
      GPIOSetValue( 0, 6, LED_ON );
       GPIOSetValue( 1, 8, LED_OFF );
       GPIOSetValue( 3, 0, LED_ON );
      GPIOSetValue( 3, 1, LED_ON );
       GPIOSetValue( 3, 2, LED_ON );
      }
   //7
      if (count==7) {
      GPIOSetValue( 2, 2, LED_OFF );
       GPIOSetValue( 0, 7, LED_OFF );
      GPIOSetValue( 0, 6, LED_ON );
       GPIOSetValue( 1, 8, LED_ON );
        GPIOSetValue( 3, 0, LED_OFF );
        GPIOSetValue( 3, 1, LED_ON );
        GPIOSetValue( 3, 2, LED_OFF );
      }
   //8
      if (count==8) {
      GPIOSetValue( 2, 2, LED_ON );
       GPIOSetValue( 0, 7, LED_ON );
       GPIOSetValue( 0, 6, LED_ON );
       GPIOSetValue( 1, 8, LED_ON );
      GPIOSetValue( 3, 0, LED_ON );
       GPIOSetValue( 3, 1, LED_ON );
        GPIOSetValue( 3, 2, LED_ON );
      }
   //9
      if (count==9) {
      GPIOSetValue( 2, 2, LED_ON );
        GPIOSetValue( 0, 7, LED_ON );
       GPIOSetValue( 0, 6, LED_ON );
        GPIOSetValue( 1, 8, LED_ON );
      GPIOSetValue( 3, 0, LED_ON );
        GPIOSetValue( 3, 1, LED_ON );
        GPIOSetValue( 3, 2, LED_OFF );
      }
      if (count==10) {count=0;}
   //0
      if (count==0) {
      GPIOSetValue( 2, 2, LED_OFF );
       GPIOSetValue( 0, 7, LED_ON );
       GPIOSetValue( 0, 6, LED_ON );
       GPIOSetValue( 1, 8, LED_ON );
       GPIOSetValue( 3, 0, LED_ON );
       GPIOSetValue( 3, 1, LED_ON );
       GPIOSetValue( 3, 2, LED_ON );
          }

  }

void TIMER16_0_IRQHandler(void)
{
if(LPC_TMR16B0->IR & (1<<4))            //capture interrupt?
{
  LPC_TMR16B0->TC = 0;                    //reset timer
  count++;
  LPC_TMR16B0->IR |= (1<<4);            //reset capture interrupt
}                                         //end capture interrupt
}

}

Labels (1)
0 Kudos
Reply
12 Replies

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Wed Sep 09 10:47:00 MST 2015
Thank you both for your help. Finally found the solution
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Tue Sep 08 01:39:17 MST 2015

Quote: audriusmerfeldas

  LPC_TMR16B0->IR |= (1<<1);

This is wrong, it will reset all match and capture interrupts (though not a problem in your little project).
It should be
  LPC_TMR16B0->IR = (1<<1);

I.e. you should just write a 1 to the bit you want to reset, don't do the logical or.
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue Sep 08 01:30:13 MST 2015

Quote: audriusmerfeldas
Any ideas



- Start the timer after you've enabled NVIC...

- Increase MR1, 0x18 is very short, probably too short to execute a complete interrupt handler...

- Post a complete project. Project and clock settings can affect you code...

Anyway, your code is working here in a new LPCXpresso 7.9 CMSIS2.0 project 

Sample:

/*
===============================================================================
 Name        : LPC11_MATCH.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : main definition
===============================================================================
*/

#include "LPC11xx.h"
#include <cr_section_macros.h>

#define LED_TOGGLE LPC_GPIO0->DATA^= (1<<7)//LED at 0.7

volatile uint32_t count;//counter

void timer16_0_setup(void)
{
//Set up 16 bit timer
 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);//enable timer clock
 LPC_TMR16B0->PR  = 48-1; //prescaler 48 = 1us
 LPC_TMR16B0->MCR = (3<<3); //interrupt and reset counter match1
 LPC_TMR16B0->CCR = 0; //timer mode
 LPC_TMR16B0->MR1 = 10-1; //set match1 time in us
 NVIC_EnableIRQ(TIMER_16_0_IRQn); //enable interrupt
 LPC_TMR16B0->TCR = 1; //start timer
}

void TIMER16_0_IRQHandler(void)
{
 if(LPC_TMR16B0->IR & (1<<1))//match1 interrupt?
 {
  LPC_TMR16B0->IR = (1<<1); //reset flag
  count++;//inc counter
 } //end match1 interrupt
}

int main(void)
{
 volatile static int i = 0;
 LPC_GPIO0->DIR |= (1<<7);
 timer16_0_setup();
 while(1)
 {
  i++;
  if(count>= 1E4)//timer limit 1E4*10 us = 0.1s
  {
   count=0;//reset counter
   LED_TOGGLE;
  }//end timer limit
 }
 return 0 ;
}

0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Mon Sep 07 22:00:38 MST 2015
Nope it isn't triggering interrupt. I was using debuging mode, set the breake point at the line you have mentioned, but i looks it never reaches it. I was going step by step and noticed that all lines of initialization works except "NVIC_EnableIRQ(TIMER_16_0_IRQn);" After it reaches ths line something went wrong and all buttons to move to other line were disabled. I need to terminate debugging.
I have tried to comment this line and then it moves to following lines but never trigers interrupt.

Any ideas
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Mon Sep 07 16:52:38 MST 2015
Is the interrupt triggered or not :quest:

Set a breakpoint at:

if(LPC_TMR16B0->IR & (1<<1)) //match 1 interrupt?

0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Mon Sep 07 14:39:22 MST 2015
Ok I have tried to debug now.

Seems that program stucks at this line:

NVIC_EnableIRQ(TIMER_16_0_IRQn);

0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Mon Sep 07 13:58:33 MST 2015
I haven't set breakepoint to check is it triggers because my workspace at the moment isn't configured for debugging. I need to spend some time to check how to do this.

I have change interrupt to this:

void TIMER16_0_IRQHandler(void)
{
if(LPC_TMR16B0->IR & (1<<1))            //capture interrupt?
{
  LPC_TMR16B0->TC = 0;                    //reset timer
  count++;
  LPC_TMR16B0->IR |= (1<<1);            //reset capture interrupt
}                                         //end capture interrupt
}

but still doesn't work
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Mon Sep 07 13:30:54 MST 2015

Quote: audriusmerfeldas
Thanks for your help but still haven't work it out what is wrong.



Did you set a breakpoint inside interrupt handler? Is it triggered?

Did you change capture interupt (bit 4) to match 1 interrupt (bit 1)?
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Mon Sep 07 12:14:13 MST 2015
Thanks for your help but still haven't work it out what is wrong. Timer initialization now looks:

  //Set up 16 bit timer
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);                                  //enable clock signal to 16 bit timer0 (sec 3.5.14)
  LPC_TMR16B0->PR           = 0x0;                                      //set prescaler max value, not used here (sec 18.7.4)
  LPC_TMR16B0->MCR          = 0x18;                                     //set for reset on counter match (sec 18.7.6)
  LPC_TMR16B0->CCR          = 0;                                        //set to timer mode (sec 18.7.11)
  LPC_TMR16B0->MR1          = 0x18;                                     //set value for period (sec 18.7.7)
  LPC_TMR16B0->TCR          |= 0x3;                                     //enable and reset counter (sec 18.7.2)
  LPC_TMR16B0->TCR          &= ~(0x2);                                  //clear reset bit (sec 18.7.2)
  NVIC_EnableIRQ(TIMER_16_0_IRQn);                              /* Enable NVIC interrupt for timer 0 */

Looking on the board now looks like something happened but my LED indicator is not glowing at all. Still looks like something starts to work but not exactly how I need.

Thanks for hlping, still trying to sort it out
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Sun Sep 06 14:47:43 MST 2015

Quote: audriusmerfeldas


  LPC_TMR16B0->MCR = (3 << 0);                               
  NVIC_EnableIRQ(TIMER_16_0_IRQn);        

That suppose to do what you have noted...



Nope  :)

You are using match register 1, so reset and interrupt of MR1 is 0x18  :exmark:

After that your interrupt should be triggered  (set a breakpoint there and check it) :)

Unfortunately you've copied a capture sample, so you're checking the wrong interrupt there and your counter isn't counting...

0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Sun Sep 06 14:38:32 MST 2015
Thanks for help. I have tried to add this:

  LPC_TMR16B0->MCR = (3 << 0);                               
  NVIC_EnableIRQ(TIMER_16_0_IRQn);        

That suppose to do what you have noted, but doesn't seem to work. Any other advices?
0 Kudos
Reply

3,623 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Sun Sep 06 13:41:42 MST 2015

Quote: audriusmerfeldas
I am very new at programming but using examples i am developing me own code.



What's wrong with working samples  :quest:

If you want to use an interrupt, you have to enable it in MCR and NVIC  ;-)
0 Kudos
Reply