User manual

LPCXpresso Experiment Kit - User’s Guide
Page 88
Copyright 2013 © Embedded Artists AB
An interrupts source is enabled by the call below. The example enables the 16-bit timer #0 interrupt.
/* enable 16-bit timer #0 interrupt */
NVIC_EnableIRQ(TIMER_16_0_IRQn);
It is also possible to disable an interrupt source.
/* disable 16-bit timer #0 interrupt */
NVIC_DisableIRQ(TIMER_16_0_IRQn);
Normally it is good system design practice to keep the execution time in the interrupts as short as
possible. The actions that are needed immediately are done in the interrupt service routine (ISR).
Actions that can wait should be scheduled for later execution in the normal program flow. If it is not
possible to keep execution time in an ISR short, nested interrupts can be used. Nested interrupts
means that an interrupt can interrupt another interrupt if it has higher priority. Four priority levels (0-3)
are supported in the NVIC hardware. The lower the number is, the higher the priority is. Interrupts with
the same priority cannot interrupt each other. It is possible to set the priority of an interrupt like this:
/* set priority of specified interrupt
IRQn_Type , priority (0..3) */
void NVIC_SetPriority(TIMER_16_0_IRQn, (prio<<1)|0x01;
Creating an ISR is very simple. The ISR can be written entirely as a C-routine. Have a look in file
cr_startup_lpc11.c. It is found in the project’s src sub-directory. Amongst other things this
file contains declarations of the ISR:s, as seen below. The functions are called ISR handlers, but that is
just another name for the same thing an interrupt service routine, ISR.
...
//*****************************************************************************
//
// Forward declaration of the specific IRQ handlers. These are aliased
// to the IntDefaultHandler, which is a 'forever' loop. When the application
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//
//*****************************************************************************
void CAN_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
void I2C_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
void UART_IRQHandler (void) ALIAS(IntDefaultHandler);
void ADC_IRQHandler (void) ALIAS(IntDefaultHandler);
void WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
void BOD_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT3_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT2_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void WAKEUP_IRQHandler (void) ALIAS(IntDefaultHandler);
...
If the user program does not contain declarations of these routines/handlers, then they will default to
the default interrupt handler (IntDefaultHandler). The exact same name of the routines must
be used. Below is an example of a custom ISR for 16-bit timer #0.
/* My own ISR for 16-bit timer #0 */
void TIMER16_0_IRQHandler (void)
{
//Service the interrupt and finish with clearing interrupt
...
}