lpcware

How to clear Timer0 match IT?

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by Bela on Thu Jul 09 11:26:11 MST 2015
Ladies and gentlemen,

I need assistance again.

I wrote a silly little code for my LPCXpresso board. It is connected to a base board, and I try to control the brightness of the RGB LED by PWM.
I' like to use Timer0 to generate the PWM signal, using Match0 - Match3 registers.
My plan is to independently control the 3 LEDs, but at the moment I control them all together.
Match1 determines the PWM period, when I got a Match1 IT, I turn all LEDs on.
Match0, Match2, Match3 registers are to determine the duty cycle, the corresponding IT routines turn the LEDs off.

If I write the Timer0_IT routine the following way, then it works:

void TIMER0_IRQHandler (void)
{
NVIC_ClearPendingIRQ(TIMER0_IRQn);
if (( LPC_TIMER0->IR & 1<<0) == 1)  // if Timer0 Match0 resulted an IT
{
LPC_TIMER0->IR |= (1<<0);             // clear Match0 IT request
Timer0Match0IT ();                           // then call Timer0Match0IT
}
else
{ Timer0Match1IT () ;};                     // call Timer0Match1IT
        return ;
}

So, this code works, but if I single step through it (LPCXpresso 7.8.0), neither the Match0 nor the Match1 IT request bits are cleared. I see peripherals->Timer0->IR->MR0I and MR1I bits.

Since my plan is to use all the 4 match registers, I modified my code:

void TIMER0_IRQHandler (void)
{
NVIC_ClearPendingIRQ(TIMER0_IRQn);
if (( LPC_TIMER0->IR & 1<<0) == 1)// if Timer0 Match0 resulted an IT
{
LPC_TIMER0->IR |= (1<<0);// clear IT request
Timer0Match0IT ();// then call Timer0Match0IT
};
if (( LPC_TIMER0->IR & 1<<1) == 1)// if Timer0 Match1 resulted an IT
{
LPC_TIMER0->IR |= (1<<1);// clear IT request
Timer0Match1IT ();// then call Timer0Match1IT service routine
};
       return ;
}

When I debug this code, Timer0Match0IT is called periodically, but Timer0Match1IT never called, despite I see the corresponding IT request bit is set.

What is the reason, the second if condition doesn't get true?
What is the proper way to delete the Timer0Match0 interrupt? (Yes, I read in the manual: I have to write a 1 into the corresponding register. But it doesn't clear the bit.)

Here's the routine that sets Timer0 up at the begin of the program:

void Timer0Setup (void)// Timer0 creates the PWM signal to control the brightness of the LED.
{LPC_SYSCTL->PCONP|= 1<<1;// Power up Timer0
LPC_SYSCTL->PCLKSEL[0] = (LPC_SYSCTL->PCLKSEL[0] & ~(1<<2 | 1<<3)) | (1<<2 | 0<<3);
LPC_TIMER0->MCR = 0;// clear all bits in Match Control Register
LPC_TIMER0->CCR= 0;// clear all bits in Capture Control Register
LPC_TIMER0->CTCR= 0;// Clear all bits in Count Control Register
LPC_TIMER0->TCR = 0;// clear all bits in Timer Control Register
LPC_TIMER0->EMR= 0;// clear all bits in Timer External Match Register
LPC_TIMER0->PR = 12;// Prescale register = 12
LPC_TIMER0->MCR= (LPC_TIMER0->MCR & ~0x7ff) | (1<<0 | 0<<1 | 1<<3 | 1<<4 ); //| 1<<6 | 1<<9);// Match control register IT enabled
LPC_TIMER0->MR[0]  = 503;// initial value for Match0 register (Duty cycle Red LEDs) at 26°(145. Value Up)
LPC_TIMER0->MR[1]  = 10100;// initial value for Match1 register (PWM Period)
LPC_TIMER0->MR[2] = 9153;// initial value for Match2 register (Duty Cycle Green Led) at 146° (812. value UP)
LPC_TIMER0->MR[3]= 5345 ;// initial value for Match3 register (Duty cycle Blue Led at 266°   (1479. value Down)
LPC_TIMER0->TCR= 1<<0;// Timer control register. Timer0 enabled
return ;
}

Outcomes