This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Facing problem with P1 and Timer interrupts

Hello. First of all I wanna say thanks since now for your help.

I have here a Launchpad with G2553 and want to use the port interrupt to measure the period between the rising edge and the falling edge.

Basically is get the rising edge on the port, enter in the interrupt routine, reconfigure to falling edge and start the timer. When the falling edge comes, reconfigure again to rising edge, copy the value of the timer to a variable called x. This x is the pulse width in ms. The timer interrupt is just for count how many times I count 1ms (because I'm using timer in up mode with CCR0 = 1000d).

The problem is when I enter the timer interrupt. After that, I don't know, but the software cant't go out of this routine.

Here it is the software:

#include "IO430.h"

unsigned int x = 0;
unsigned int n = 0;


void main (void)
{

WDTCTL = WDTPW + WDTHOLD;
TA0CCR0 = 0x03e8;

P1DIR = 0x00;
P1SEL = 0x00;
P1OUT = 0x00;

P1DIR_bit.P4 = 0;
P1SEL_bit.P4 = 0;
P1IE_bit.P4 = 1;
P1IES_bit.P4 = 0;
P1IFG_bit.P4 = 0;
P1DIR_bit.P0 = 1;
P1SEL_bit.P0 = 0;
P1DIR_bit.P6 = 1;
P1SEL_bit.P6 = 0;

__enable_interrupt();


while(1){}



}


#pragma vector = PORT1_VECTOR
__interrupt void HALL (void)
{
if(P1IES_bit.P4 == 0)
{
P1IFG_bit.P4 = 0;
P1IES_bit.P4 = 1;
P1OUT_bit.P6 = 1;
TA0CTL = TASSEL_2 + MC_1 + TAIE;
}
else
{
P1IFG_bit.P4 = 0;
P1IES_bit.P4 = 0;
x = TA0R;
TA0R = 0;
P1OUT_bit.P6 = 0;
}


}

#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_0(void)
{
n++;

}

Will be great if one of you can help me.

Thanks.

 

  • In the timer ISR you need to explicitly clear the TAIFG bit (set it to zero).

    What is happening is you get the interrupt, increment n, exit, interrupt controller sees that TAIFG is set, call your ISR, (infinite loop)

  • Remember that if you are using a push-button this one bounces after pressing it, falsifying your result.

  • No. I'm using a effect hall sensor. I will check the TAIFG in a few hours.

    Thank you both.

  • Thank you guys. It works!!

  • Another way (and more precise) to do it is to use the capture function of the timer.
    Program CCR0 for capture on rising edge and CCR1 for capture on the falling edge. Enable the interrupt for CCR1.
    When the CCR interrupt comes, you can get the delay by subtracting the CCR0 capture form the CCR1 capture to get the precise number of counts between the two edges, independently of any IRQ latency.

    Two additions: you can implement a rollover count (timer overflow interrupt) for pulses longer than 65535 timer ticks. And you should check the overflow flag, in case a long IRQ latency (e.g. due to other ISRs executing) has caused you to enter the ISR after the next rising edge.
    You can also use just one CCR and program it for either both edges or (as with the port interrupt) switch the edge. This saves a pin and one CCR, but increases the software effort and the chance of missing an edge on short delays.

**Attention** This is a public forum