This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

TImer_Interrupts

Hi Folks,

I am trying to work on Timer Interrupts. I want to start an LED when a TIMER match occurs. I have called an Interrupt on match and the LED should glow when the match occurs. I am not able to perceive the output. I am not exactly getting where its going wrong. Can you please help me out on this. Below is the code, please review

#include<lpc21xx.h>

#define MR0I_FLAG 0X01
void led(void)__irq
{ long int regval; regval = T0IR;

if(T0IR & MR0I_FLAG) { T0MR0 = 0XFF; T0TC = 0X00; T0TCR = 0X00000001;

IO0CLR = 0X00000002; IO0SET = 0X00000008; }

T0IR = regval; VICVectAddr0 = 0X00000000;
}

int main()
{ IO0DIR = 0X0000000A; T0TCR = 0X00000000; T0MCR = 0X00000003; //Reset and generate an interrupt on Match T0PC = 0X00000000; T0PR = 0X00000000;

VICIntEnable = 0X00000010; VICVectCntl0 = 0X00000024; VICVectAddr0 = (unsigned)led;

IO0SET = 0X00000002;
}

Parents
  • Hi Per,

    Thanks for your valuable feedback. I'll take your comments positively as I am a beginner in Embedded C programming and also in ARM, so comments like these are always welcome!

    In reply to your mentioned points,

    1.I saw the posting instructions about source code.
    2.I am using NXP's - LPC2129

    4.I incorporated this change.
    5.I wanted to tick the Timer Counter on every PR+1 clock, hence I used T0PR = 0X00000000
    6.Yes, I want an Interrupt when match occurs. Hence I have mentioned this "T0MCR = 0X00000003; //Reset and generate an interrupt on Match" in the code. I have specified the Match value in the IRQ as "T0MR0 = 0XFF"
    7.Got your point.

    10.#define MR0I_Flag 0X01 //I am AND'ing the value which I specified in the Match Control register with T0IR register and now comparing it with 0X01

    Why the compiler is not entering into the IRQ?

Reply
  • Hi Per,

    Thanks for your valuable feedback. I'll take your comments positively as I am a beginner in Embedded C programming and also in ARM, so comments like these are always welcome!

    In reply to your mentioned points,

    1.I saw the posting instructions about source code.
    2.I am using NXP's - LPC2129

    4.I incorporated this change.
    5.I wanted to tick the Timer Counter on every PR+1 clock, hence I used T0PR = 0X00000000
    6.Yes, I want an Interrupt when match occurs. Hence I have mentioned this "T0MCR = 0X00000003; //Reset and generate an interrupt on Match" in the code. I have specified the Match value in the IRQ as "T0MR0 = 0XFF"
    7.Got your point.

    10.#define MR0I_Flag 0X01 //I am AND'ing the value which I specified in the Match Control register with T0IR register and now comparing it with 0X01

    Why the compiler is not entering into the IRQ?

Children
  • I have updated the code as shown below. I debugged the code and noticed, that the VICVectAddr0 is updated with an address where its handler (void Timer0_IRQ(void)__irq) is located. Still the compiler is not jumping into the IRQ.

    Need help!!

    #include <LPC21xx.H>
    
    void Timer0_IRQ(void)__irq;
    
    int main()
    {
    
            IO0DIR = 0X0000000A;
    
            T0TCR = 0X00000000;          //Disable Timer
    
            T0MCR = 0X00000003;          //Reset and generate an interrupt on Match
    
            T0PC = 0X00000000;
    
            T0PR = 0X00000000;           //T0TC should increment on PR+1 clk
    
    
    
            T0MR0 = 0XFF;                //Value in Match Register
    
            T0TC = 0X00;                 //Reset Value in Timer Counter
    
            T0TCR = 0X00000001;          // Enable Timer
    
    
    
            VICVectAddr0 = (unsigned)Timer0_IRQ;
    
            VICVectCntl0 = 0X00000024;       //Assigning Timer0 Interrupt to an IRQ Slot
    
            VICIntEnable = 0X00000010;       //Enabling the vector
    
    
            IO0SET = 0X00000002;
    }
    
    
    void Timer0_IRQ(void)__irq
    
    {
    
            IO0CLR = 0X00000002;
    
            IO0SET = 0X00000008;
    
            T0IR = 0X01;                     //Clear Timer Match0 interrupt flag
    
            VICVectAddr = 0X00000000;        // End of Interrupt execution
    
    }
    

  • Your program is still running out of main() instantly. So - do you expect there to be a cozy command line or GUI to pick up the processor after your program decides to quickly end? This was point 8 in my previous post.

    And you have configured the timer at an extremely high interrupt frequency - it isn't meaningful to try to configure for a frequency higher than what the processor is fast enough to be able to service. Why don't you tell us what timer frequency you plan for - and why you think you need to run timer interrupts at such a wild frequency. Remember that all CPU time spent in an interrupt handler is CPU time lost from the main loop (assuming that your program actually had a main loop...) I covered short delay times in a different thread. Think about how many clock cycles it may take to handle one timer interrupt. Think about how many clock cycles there will be between two interrupts. That gives you an idea how much time you leave for the CPU to do other stuff.

    "//Enabling the vector"
    Enabling what vector? Why not write that it's specifically the timer 0 interrupt you are enabling?

    And you shouldn't enable the timer until _after_ you have registered the interrupt handler. Normal code is the clear the counter value and enable the timer as the last two steps - when everything else has already been prepared and ready. If you enable it early, and have a very short timer period, then it could have time to perform the match before you had the time to actually enable the interrupt in the VIC.

    Are you aware that there is no need to write a 32-bit hexadecimal number using 8 digits.

    0x00000000 is the same value as 0x00 or 0. The first form is just taking longer time for you to write.

  • Are you aware that there is no need to write a 32-bit hexadecimal number using 8 digits.

    0x00000000 is the same value as 0x00 or 0. The first form is just taking longer time for you to write.

    True, but it is certainly a habit I'm guilty of exhibiting (though guilty may not really be the right word).

    The reason I do it is simple: it emphasizes the size of those numerous SFRs etc when glancing back at the code.

  • I am using VPBCLK = CPU Clock (12Mhz) and expecting a 1 Sec delay. Means an ISR should be called after this delay.Can you please tell, how to configure the interrupt frequency?

  • So - what frequency do you get? The difference between expected and actual frequency is normally a good hint at what is incorrectly configured - debugging is all about picking up the available clues and evaluate them.

    If you have 12 MHz, then you somehow have to divide that down to 1 Hz for your expected interrupt frequency. I haven't seen you try any values that would be even close to such attempt - on the first code post you ignored the match control register despite requesting an interrupt on match. In the second post, you made a bit of a random assignment for the match control register - and arbitrary values tends to give arbitrary results.

    Wouldn't it be an idea to fix the things that have already been mentioned?

    Like making some reasonable attempt at setting a value for the match control register?

    Or making sure the program doesn't exit main() before the processor have time to produce the first interrupt?

    The processor will not ignore details, even if you do.