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 ;
}