Content originally posted in LPCWare by Ex-Zero on Wed May 11 13:49:16 MST 2011
As suggested earlier a smarter way to switch your LED is to use PWM (with prescaler) and it's interrupts:
Quote:
#define LED1 (1 << 8)
#define LED1_ON LPC_GPIO0->DATA |= LED1; //LED ON
#define LED1_OFF LPC_GPIO0->DATA &=~LED1; //LED OFF
#define LED1_TOG LPC_GPIO0->DATA ^= LED1; //LED TOG
volatile unsigned short pwm_period = 1000; //with prescaler 0.1 ms = 100ms period
volatile unsigned short pwm_on = 200; //with prescaler 0.1 ms = 20ms ON
//ISR timer 16B0 for PWM
void TIMER16_0_IRQHandler(void)
{
if (LPC_TMR16B0->IR & (1<<0) ) //match0
{
LPC_TMR16B0->IR = (1<<0); //LED OFF
LED1_OFF;
}
if ( LPC_TMR16B0->IR & (1<<3) ) //match2
{
LPC_TMR16B0->IR = (1<<3); //reset timer & LED ON
LED1_ON;
}
}
//init timer 16B0 for PWM
void init_tmr0pwm(unsigned short init_period, unsigned short init_on)
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
LPC_TMR16B0->TCR = 0;
LPC_TMR16B0->PR = 7200-1; //set prescaler to 0.1ms
LPC_TMR16B0->PWMC = (1<<0)|(1<<3); //match 0 & match3
LPC_TMR16B0->MR3 = init_period;
LPC_TMR16B0->MR0 = init_on;
LPC_TMR16B0->MCR = (1<<0)|(1<<9)|(1<<10); //int on Match 0 & 3, reset match 3
NVIC_EnableIRQ(TIMER_16_0_IRQn);
LPC_TMR16B0->TCR = 1;
}
int main(void)
{
LPC_GPIO0->DIR = LED1; //set LED1 output
init_tmr0pwm(pwm_period, pwm_on);
// Enter an infinite loop, just incrementing a counter
volatile static int i = 0 ;
while(1)
{
if(i>100000) //delay
{
i=0;
pwm_on++;
if(pwm_on>800)pwm_on=200; //change 20-80ms ON
LPC_TMR16B0->MR0 = pwm_on; //write to match0
}
i++ ;
}
return 0 ;
}
No delay, just setting period and On-time in MR3/MR0 :)