Problem with Interrupt - match

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Problem with Interrupt - match

899 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gillys on Fri May 11 19:23:41 MST 2012
Hello,

I am confused about the code I attached below. For small values of PWM_VALUE the code works fine (LED is nearly off). For increasing values of PWM_VALUE the LED gets brighter. But for values near the value from LPC_TIM0->MR0 (e.g. 995) the LED is nearly off, however it should be almost the maximum brightness. What is wrong about my code?


#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

enum {
    PCTIM0 = 1, MR0 = 0, MR1 = 3
};

int main(void) {
    LPC_SC->PCONP |= (1 << PCTIM0);        // turn power for TIMER0 on
    LPC_TIM0->MR0 = 1000;                // match register 0
    LPC_TIM0->MCR |= (0x3<< MR0);        // Interrupt + reset
    LPC_TIM0->MR1 = PWM_VALUE;                // match register 1
    LPC_TIM0->MCR |= (0x1<< MR1);        // interrupt if MR1 = TC
    LPC_TIM0->TCR = 1;                    // enable Timer0
    NVIC_EnableIRQ(TIMER0_IRQn);

    LPC_GPIO0->FIODIR |= (1 << 22);        // LED pin

    while(1) asm volatile("nop");
    return 0 ;
}


void TIMER0_IRQHandler(void)
    {
        if (LPC_TIM0->IR & (0x1 << 0)) //Interrupt flag for match channel 0.
        {
            LPC_TIM0->IR = (0x1 << 0); //kill flag
            LPC_GPIO0->FIOSET |= (1 << 22);
        }
        if (LPC_TIM0->IR & (0x1 << 1)) //Interrupt flag for match channel 1.
        {
            LPC_TIM0->IR = (0x1 << 1); //kill flag
            LPC_GPIO0->FIOCLR |= (1 << 22);
        }
    }
0 项奖励
回复
2 回复数

835 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gillys on Sat May 12 10:41:54 MST 2012

Quote: Zero
I'm also confused about your code. And your LPC1769 is confused, too. What are you trying to do?


:)
Thank you very much! You helped me a lot!
0 项奖励
回复

835 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sat May 12 04:25:25 MST 2012

Quote:

I am confused about the code I attached below.

I'm also confused about your code. And your LPC1769 is confused, too. What are you trying to do?

You are running a 25MHz timer to switch a LED with 25kHz.With (1000-995)* 1/25MHz there are 200ns left for you interrupt :eek:

Believe it or not, interrupts need time :mad:

So what's happening here is easy to explain:

Your interrupt handler is getting both interrupts. Instead of setting or resetting your LED, it's doing both. And exactly in that order you've programmed :rolleyes:
As result you are generating a little pulse in your interrupt handler.

Possible solutions

#1 Give your hard working interrupt handler a little bit more time.[INDENT] Use a prescaler if it's possible for your LED to run with 2.5kHz instead of 25kHz.
LPC_TIM0->PR  = 9;                    //prescaler 10
[/INDENT]#2 Don't use interrupts. This chips can generate PWM without interrupts.[INDENT] This sample is generating a real PWM at PWM1.1 (P2.0) without interrupts:
//init PWM
 LPC_SC->PCONP |= (1 << 6);            //PWM on
 LPC_PINCON->PINSEL4 &=~3;            //reset
 LPC_PINCON->PINSEL4 |= 1;            //set PWM1.1 at P2.0
 LPC_PWM1->TCR = 2;                    //counter reset
 LPC_PWM1->PR = 24;                    //clock /4 / prescaler (= PR +1) = 1 µs
 LPC_PWM1->MCR = (1<<1);            //reset on MR0
 LPC_PWM1->MR0 = 1000;                //set PWM cycle 1khz
 LPC_PWM1->MR1 = 999;                //set duty
 LPC_PWM1->LER = (1<<0)|(1<<1);        //latch MR0 & MR1
 LPC_PWM1->PCR = (1<<9);            //PWM1 output enable
 LPC_PWM1->TCR = (1<<0)|(1<<3);        //counter enable, PWM enable
[/INDENT]
0 项奖励
回复