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.

Pulse Train Generation using TimerA MSP430G2553

Other Parts Discussed in Thread: MSP430G2553

Hello,
My ultimate goal is to generate a finite series of 20µs pulses at a frequency of 1kHz, but I am having trouble generating the necessary pulse width. My preliminary attempts have been with pulses spaced 50µs apart, and attempting 20µs pulse width. Once I have this working properly, I believe I can easily add the pulse counting and adjust the frequency/duty cycle.

I am using a MSP430G2553 and have been referencing the Datasheet and MSP430x2xx User Guide. From the Datasheet (p43) I am trying to output my signal on P1.1 so I am setting P1DIR.1 = 1, P1SEL.1 = 1, and P1SEL2.1 = 0. I believe this is all correct because I am getting a signal on P1.1 that behaves somewhat as expected.

My project is based on p372 of the User Guide. I am trying to user Timer A in Up mode to raise the pin high after counting up to TACCR1 and then resetting the pin when reaching TACCR0. For this I am using Output Mode 3 (Set/Reset). To make things easier to see on a oscilloscope, I have been setting TACCR0 = 50 and TACCR1 = 30. If I understand the diagram, when the clock is started it will count to TACCR1 (30), set the pin high, continue counting to TACCR0 (50), then reset the pin. This should result in a pulse width of 20 counts (equivalent to µs for my clock settings). While I am seeing a 50µs period, the pulse width is only 1µs (1 clock cycle). Additionally, changing the value of TACCR1 does not affect the output in any way. This is leading me to believe that I have forgotten to enable something.

My code and scope capture of the output is below. Any help is much appreciated.


#include <msp430g2553.h>

#define TIMER_OUT BIT1

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

    P1DIR |= TIMER_OUT; // set P1.1 to output direction
    P1SEL |= TIMER_OUT; // set P1.1 function to TA0.0
    TACCTL0 |= OUTMOD_3; // set output mode to Set/reset
    TACCTL1 |= OUTMOD_3; // set output mode to Set/reset
    TACCR0 = 50; // (µs)
    TACCR1 = 30; // (µs)

    TACTL = TASSEL_2 + MC_1; // set Timer_A source to SMCLK and start timer in UP mode

    _BIS_SR(CPUOFF);
}

Best,
Anthony

  • You don't generate PWM using CCR0, so don't look signal on CCR0 output, it's on CCR1 output pin :) Try this:

    #include <msp430g2553.h>
    
    #define TIMER_OUT BIT2
    
    int main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
      if (CALBC1_1MHZ==0xFF)		// If calibration constant erased
      {											
        while(1);                               // do not load, trap CPU!!	
      } 
      DCOCTL = 0;                               // Select lowest DCOx and MODx settings
      BCSCTL1 = CALBC1_1MHZ;                    // Set range
      DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */
    
      P1DIR |= TIMER_OUT; 
      P1SEL |= TIMER_OUT;
      TACCR0 = 50-1; // PWM Period 50us (substract 1 because it's 0-based)
      TACCTL1 = OUTMOD_3;
      TACCR1 = 20; // CCR1 PWM duty cycle
      TACTL = TASSEL_2 + MC_1; // SMCLK, up mode
      _BIS_SR(CPUOFF); // Enter LPM0
    }

  • Ilmars,
    Thank you very, very much!

    Can you explain your code a little bit for me so I understand it?
    First, when I was using P1.1 as an output, was it actually functioning correctly, only I wasn't probing the correct pin so it looked incorrect? I'm assuming if I was only using CCR0 I would use P1.1 as an output, or similarly if I was using all 3 registers I would use P3 pins.

    Second, is the code from the if statement to the P1DIR line clock calibration? I have not seen this before, can you explain it briefly?

    Again, thank you for your help

    Best,
    Anthony

  • Anthony Mucciolo said:
    First, when I was using P1.1 as an output, was it actually functioning correctly

    Yes, indeed it was functioning correctly but not as you intended. When you use CCR0 as timer period register, timer resets to 0 when it's counter reaches CCR0 value (refer to 2xx series User's Guide. If you configure CCR0 output for PWM generation for timer in up mode you will see what you did see - pulse which length is one timer clock period.

    Anthony Mucciolo said:
    only I wasn't probing the correct pin so it looked incorrect?

    You configured CCR1 for PWM kinda correctly, but did not configure it's output pin and yes, did not probe it's output either. Notice that I changed TIMER_OUT definition to BIT2.

    Anthony Mucciolo said:
    line clock calibration?

    Lines 

    BCSCTL1 = CALBC1_1MHZ;                    // Set range
    DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */
    loads factory calibration constants for 1MHz DCO. So supposedly you are getting clock much closer to 1MHz than using default DCO frequency. Default clock frequency (w/o factory cal) is "somewhere around 1MHz" to say least.
    Comparison of flash calibration value with 0xFF and program execution "trap" using while(1); if equal is just precaution against careless msp430 user/programmer who for some reason did erase INFO flash segment containing calibration values thus losing them.
  • Thank you very much Ilmars

    -Anthony

  • Did my code work? Did you get expected PWM results?

  • Yes it did. Thank you very much. I am now expanding upon my project now that the basic functionality works properly.

    -Anthony

**Attention** This is a public forum