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.

Compiler: MSP430F149 capture mode Timer B

Other Parts Discussed in Thread: MSP430F149

Tool/software: TI C/C++ Compiler

Dear all!


Who can help me with the issue with interrupt:

void main(void)
{

P4SEL=BIT0;

P1DIR |= BIT0;

P1SEL &= ~ BIT0;
P1SEL|=BIT0;
P1DIR &= ~BIT0;
timerB_init();
_BIS_SR(LPM0_bits+GIE);
}

void timerB_init()
{
TBCTL=MC_2+TBSSEL_1+TBCLR+TBIFG;
TBCCTL0=CM_1+SCS+CCIS_1+CAP+CCIE;
}
#pragma vector = TIMERB0_VECTOR
__interrupt void TIMERB0_VECTOR_ISR (void)
{
P1OUT &= ~0x01;

}

It doesn't work. I tried to go into the interrupt part, but it doesn't happen. Please could you explain me, what the reason? 

  • Hi Nastya,

    First I don't think you've properly setup your TBCTL register. You shouldn't be setting the TBIFG bit. I also expect that you were trying to set the TBIE bit which is also unnecessary when using TBCCR0 in capture mode.

    Next, you've selected a rising edge on CCI0B to trigger the capture and subsequently cause an interrupt to occur.  On the MSP430F149 this is P2.2. This pin needs to be properly setup as input so the timer can detect the rising edge. Then you also need to apply a rising edge to cause a capture.

    Finally, please take a look at MSP430x13x, MSP430F14x, MSP430F15x, MSP430F16x Code Examples (Rev. S). These code examples show how to properly use TimerA in capture mode which will be very similar to how you would use TimerB.

    Best regards, 
    Caleb Overbay

  • Dear Caleb,

    Thank you for your response!
    "Next, you've selected a rising edge on CCI0B to trigger the capture and subsequently cause an interrupt to occur. On the MSP430F149 this is P2.2. This pin needs to be properly setup as input so the timer can detect the rising edge. Then you also need to apply a rising edge to cause a capture."
    In the datasheet I've found this one:
    "P4.0/TB0 General-purpose digital I/O pin/Timer_B, capture: CCI0A or CCI0B input, compare: Out0 output" - Does it mean that I can use this pin and CCI0B or CCI0A for capture mode?

    In slac - ta_22 I've found the exaple of the capture mode, but in this exaple I couldn't find the interrupt.
  • And, please, could you explain to me why I need to use TBIV?
    If I need to use TBCCR0 interrupt.
    Unfortunately, I didn't find the correct example of the capture mode.
  • Hi Nastya,

    The example showing how to accomplish this with TimerA can be found in the previous link. The file name is fet140_ta_22.c

    "P4.0/TB0 General-purpose digital I/O pin/Timer_B, capture: CCI0A or CCI0B input, compare: Out0 output" - Does it mean that I can use this pin and CCI0B or CCI0A for capture mode?
    A: If you're using TimerB you should use P4.0 for CCI0B. If you're using TimerA you should use P2.2 for CCI0B. This can be seen in the "timer_A3" and "timer_B7" sections of the datasheet.

    And, please, could you explain to me why I need to use TBIV?
    A: You do not need to use TBIV when using TBCCR0 because it has it's own dedicated interrupt vector.

    Best regards,
    Caleb Overbay
  • Unfortunately, but it doesn't work
    I've made the changes in the code.
    But it's still not working. What the reason?

    void main(void)
    {

    P4SEL=BIT0;

    P1DIR |= BIT0;

    P1SEL &= ~ BIT0;
    P1SEL|=BIT0;
    P1DIR &= ~BIT0;
    timerB_init();
    _BIS_SR(LPM0_bits+GIE);
    }

    void timerB_init()
    {
    TBCTL=MC_2+TBSSEL_2+TBIE;
    TBCCTL0=CM_1+SCS+CCIS_2+CAP+CCIE;
    }
    #pragma vector = TIMERB0_VECTOR
    __interrupt void TIMERB0_VECTOR_ISR (void)
    {
    P1OUT &= ~0x01;

    }
  • Hi Nastya,

    You're still not properly setting up the pin for CCI0B input. And you've made almost no changes to your original code. Also you don't need to use TBIE.

    As previously stated:
    If you're using TimerB you should use P4.0 for CCI0B. If you're using TimerA you should use P2.2 for CCI0B. This can be seen in the "timer_A3" and "timer_B7" sections of the datasheet.

    Also don't forget that you need to have a rising edge on that pin to trigger the capture.

    Finally, what is your end goal for this project? Are you just trying to toggle a GPIO at a certain rate? If so capture mode is not the appropriate way to use a Timer to accomplish this.

    Best regards,
    Caleb Overbay
  • What do you mean: "You're still not properly setting up the pin for CCI0B input. And you've made almost no changes to your original code. Also you don't need to use TBIE."?

    In the example I've set up - P4SEL=BIT0; or I need to add P4DIR|=BIT0?

    About TBIE: in previous your response you said that :"I also expect that you were trying to set the TBIE bit which is also unnecessary when using TBCCR0 in capture mode" - ok, i understood you. I'll change it.

    "Finally, what is your end goal for this project? Are you just trying to toggle a GPIO at a certain rate? If so capture mode is not the appropriate way to use a Timer to accomplish this. " - I need to catch input signals, that are coming from ultrasonic sensor and then to measure the time between the send and receive signal. But in this example I'm trying to light the LED if capture happens.

    void main(void)
    {

    P4SEL=BIT0;

    P1DIR |= BIT0;

    P1SEL &= ~ BIT0;
    P1SEL|=BIT0;
    P1DIR &= ~BIT0;
    timerB_init();
    _BIS_SR(LPM0_bits+GIE);
    }

    void timerB_init()
    {
    TBCTL=MC_2+TBSSEL_2;
    TBCCTL0=CM_1+SCS+CCIS_2+CAP+CCIE;
    }
    #pragma vector = TIMERB0_VECTOR
    __interrupt void TIMERB0_VECTOR_ISR (void)
    {
    P1OUT &= ~0x01;

    }
  • Hi Nastya, 

    I'e attached code that I was able to make successfully enter the TimerB interrupt with a rising edge on P4.0.

    I noticed two main problems with your code:

    1. You weren't disabling the WDT at the beginning of execution
      1. The part was most likely resetting constantly because of this
    2. You were setting the TimerB capture input to GND instead of CCI0B
      1. Original code was: TBCCTL0=CM_1+SCS+CCIS_2+CAP+CCIE;
      2. Changed to: TBCCTL0=CM_1+SCS+CCIS_1+CAP+CCIE;

    This is some generic code I was able to get executing properly. Note that I ensured both P4DIR and P4SEL were setup properly as well as disabling the WDT. Please test it out and let me know what you think:

    void main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    
        P4DIR &= ~BIT0;
        P4SEL |=  BIT0;
    
        timerB_init();
        __bis_SR_register(LPM0_bits + GIE);       // LPM0 + Enable global ints
    }
    
    void timerB_init()
    {
        TBCCTL0=CM_1+SCS+CCIS_1+CAP+CCIE;
        TBCTL=MC_2+TBSSEL_2;
    }
    
    #pragma vector = TIMERB0_VECTOR
    __interrupt void TIMERB0_VECTOR_ISR (void)
    {
        __no_operation();
    }

    Best regards, 

    Caleb Overbay

  • Dear Caleb,

    Thank you for your prompt reply.

    I've tried your example, but it still not going over vector interrupt.

    Please could you explain to me, why if I try to  initialize TBCCTL0 in the register:

    In  TBCCTL0 - cap = 1, but CCIFG = 0 and  TBCCTL4 - cap=0 and CCIFG = 1?

  • Hi Nastya,

    I'm not sure why that interrupt flag would be set. As an experiment, could you try setting up this functionality with TimerA instead of TimerB?

    Best regards,
    Caleb Overbay
  • Dear, Caleb

    I've tried to change Timer and nothing changed.

    void timerB_init()
    {
    TACCTL0=CM_1+SCS+CCIS_1+CAP+CCIE;
    TACTL=MC_2+TASSEL_2;
    }

    #pragma vector = TIMERA0_VECTOR
    __interrupt void TIMERA0_VECTOR_ISR (void)
    {
    //P1OUT ^= 0x01;
    __no_operation();
    }

    void main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    //Timer A

    P1DIR &= ~BIT6;
    P1SEL |= BIT6;

    //LED

    P1DIR |= BIT0;
    P1SEL &= ~BIT0;
    P1OUT |=BIT0;
    P1OUT &= ~BIT0;

    timerB_init();
    __bis_SR_register(LPM0_bits + GIE); // LPM0 + Enable global ints
    }

  • Hi Nastya,

    You need to use P2.2 for TimerA CCI0B input, not P1.6.

    Best regards,
    Caleb Overbay
  • Dear Caleb,

    Something has occurred. Please find the picture below:

    Please could you explain to me about this issue and how I can resolve it?
    In the register the same picture like with Timer B

    #include "msp430f149.h"

    #include "stdio.h"

    void timerB_init()
    {
    TACCTL0=CM_1+SCS+CCIS_1+CAP+CCIE;
    TACTL=MC_2+TASSEL_2;
    }

    #pragma vector = TIMERA0_VECTOR
    __interrupt void TIMERA0_VECTOR_ISR (void)
    {
    P1OUT ^= 0x01;
    //__no_operation();
    }

    void main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    P2DIR &= ~BIT2;
    P2SEL |= BIT2;

    //P4DIR &= ~BIT0;
    //P4SEL |= BIT0;

    P1DIR |= BIT0;
    P1SEL &= ~BIT0;
    //P1DIR &= ~BIT0;
    P1OUT |=BIT0;
    P1OUT &= ~BIT0;

    timerB_init();
    __bis_SR_register(LPM0_bits + GIE); // LPM0 + Enable global ints
    }

  • Dear Caleb,

    I've tried to debug your example with Timer B, but it's not working now too.
    What happen? How to resolve this issue?
  • Hi Nastya,

    I'm not sure what is wrong. I've tested the code I've provided you and verified it is working correctly. I think you should go back to the fet140_t1_22.c example I provided and test that on your setup. That is another example that has been verified to work correctly. Test this out and let me know the results. If it does not work, we'll need to take a closer look at your testing procedure.

    Best regards,
    Caleb Overbay
  • Hi Nastya,

    Have you been able to solve this issue? Do you have anymore unanswered questions?

    Best regards,
    Caleb Overbay

**Attention** This is a public forum