MSP430FR6047: How do I limit the number of pulses for TA0 timers?

Part Number: MSP430FR6047

Tool/software:

Hello,

I'm trying to limit the number of pulse outputs to 10, but it's not working well, so I'm asking for help.

The system clock is 8 MHz, and I configured TA0 as shown below so that the two outputs are 180 degrees out of phase:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void initPulseGenerator(void)
{
··· // Stop the watchdog timer
··· WDTCTL = WDTPW | WDTHOLD;
·
··· // Disable the default high-impedance mode
··· PM5CTL0 &= ~LOCKLPM5;
·
··· // Configure P7.4 for TA0.1 and P7.7 for TA0.2
··· // (Check that these pins do not require port mapping on your board.)
··· P7DIR |= BIT4 | BIT7;····· // OUTPUT DIRECTION
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Right now, it keeps generating pulses continuously.

In the code below, I'm trying to clear the interrupt flag when it triggers and stop after 10 repetitions, but the signal just stays HIGH.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void startPulseGenerator(void)
{
··· TA0R = 0; // Reset timer counter
··· TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;
·
··· // Wait for exactly 10 pulse cycles
··· int cycles = 0;
··· while (cycles < 10)
··· {
······ while (!(TA0CCTL1 & CCIFG)); // Wait for rising edge of PWM (CCR1 match)
······ TA0CCTL1 &= ~CCIFG;········· // Clear flag
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • The system clock is 8 MHz, and I configured TA0 as shown below so that the two outputs are 180 degrees out of phase:

    1MHz is too fast for CPU to check Timer's status.

    I recommend you to use 1kHz for functional testing, then switch back to higher frequency.

  • As Helic says, trying to keep up with a 1MHz PWM is very tight timing, and you probably won't succeed. You might try (as a heuristic) counting to e.g. 9 instead.

    If you stop the PWM by halting the timer (MC__STOP), the pins will retain their last settings. You should instead change the OUTMOD. If you want the pins to go low immediately, change the CCTL-s to {OUTMOD=0,OUT=0}. If you want to finish the cycle, try {OUTMOD=5 [Reset]}.

    Once you've changed the OUTMOD-s, you then have plenty of time -- you can halt the timer at the next CCR0 event, or even leave it running for the next burst.

    [Edit: If this is a significant requirement, I think there's a DMA solution as well.]

  • Thank you for your help. It was a good starting point to solving my problem. Even though it didn't solve my problem, I'll mark this as resolved.

  • Thank you. That OUTMOD thing definitely was what I was lacking. I'm now past the threshold of turning on and off.

    Now I'm faced with another problem though it's not so critical. I wanted to limit the pulse count to 10. When the frequency was low (I tested at 1 KHz as Helic suggested), I got exactly 10 pulses. But at 1 MHz, I get 25 pulses. And then I reduced the count to 5, then I got 15 pulses.

    I tried to change the int count from going up to going down and then changed the count to 5, i.e. from 5 to 0. No change. I still got 15 pulses. 

    So I changed the count to 4, then I get 11 pulses.

    I think this is close enough. I'll mark this thread as resolved. But if you can help me to sort this thing, too, it will be very helpful.

  • Sorry, I missed the implied question here.

    The notion behind a DMA solution would be: To get N pulses, have the DMA transfer N copies of TA0CCTL1, triggered by CCR0, from an N-element array. The first (N-1) (re-)write the same value, the one you set at the beginning; then the N-th writes a TA0CCTL1 value with OUTMOD=<stop>, where <stop> is the setting you picked out above.

    The DMA can only transfer 1 word (16 bits) per trigger in Single mode, so this would probably tie up 2x DMA channels (for your 2x timer channels). That's why I referred to "significant requirement" above.

    Based on the DMA timings in User Guide (SLAU367P) Table 11-3, MCLK=8MHz is probably enough. (But try it before you rely on it.) The DMA triggers are listed in datasheet (SLASEB7C) Table 6-11.

    [Disclaimer: I haven't tried this, but I've done a few other oddball tricks with timer-based DMA, and I was rarely surprised.]

  • Thank you. 

    But I'll keep your valuable tip for use in a future. Right now it's above my level and I found the right way to achieve that, i.e. getting differential 1 MHz pulses. Only a few days back did I realize that I can use CH0_OUT and CH1_OUT as differential outputs that will be banging on either side of the transducer.

    I tried to confirm it in my EVM but somehow I got nothing out of those pins. Maybe those pins were damaged. But I'm pretty sure that if they were not, I'll get what I need. But even if I'm wrong, I'll still get half of what I need.

    Cheers!!

**Attention** This is a public forum