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.

MSP430G2452: Generate Pulse

Part Number: MSP430G2452


Hi,

I am using a code(as below) to generate pulse train (20mSec repetition rate and 7 pulses of 500Hz). Now i want to modify it such that 1st pulse of the pulse train has frequency of 1kHz and rest 7 pulse can be 500Hz with repetation of 20mSec. 

Required waveform is attached.

I tried to modify it by changing TA0CCR0 & TA0CCR1 for the first count of the pulse but it's not working. Can anybody help me out? Thanks in advance. :)

#include <msp430.h>

#include <stdint.h>

 

// Set-able (within some limits)

// These settings produce a visible output at P1.2.

#define LONG_HZ     50UL           // Long cycle repeats at 50Hz

#define SHORT_PERIOD 2000UL       // Short (PWM) period: 2000 timer ticks = 2ms

#define SHORT_CNT   7U           // 7 Short pulses in each Long period

 

// Derived

#define TIMER_HZ     1000000UL     // Timer ticks at 1MHz (SMCLK/8 [ID=3])

#define LONG_PERIOD (TIMER_HZ/LONG_HZ)     // Timer ticks in a Long period

#define LONG_CNT     (LONG_PERIOD/SHORT_PERIOD) // PWM cycles in a Long period

 

// Count from 1 to LCNT, to keep track of Long period.

uint16_t short_cycles;

 

// OUTMOD=7 provides non-inverted PWM (high, then low), which is what people expect.

// It is also low in the second half, so we can switch to OUT=0 without glitching.

#define CCTL_OUTMOD (OUTMOD_7)

#define CCTL_OUT   (0*OUT)

 

// pulse_isr()

// Interrupts every SHORT_PERIOD timer ticks, but the deadline is SHORT_PERIOD/2, so don't dawdle.

 

#pragma vector=TIMER0_A1_VECTOR

__interrupt void

pulse_isr(void)

{

   TA0CCTL1 &= ~CCIFG;     // We really should look at TA0IV, but we only enable CCTL1:CCIE

 

   ++short_cycles;         // Count up (Short) PWM cycles

 

   // For the first SHORT_CNT PWM cycles, just let the PWM run

   if (short_cycles < SHORT_CNT)

   {

       /*EMPTY*/

   }

   // For the next (LONG_CNT-SHORT_CNT) cycles, hold it low using OUT=0

   else if (short_cycles < LONG_CNT)

   {

       // Force it low using OUTMOD=0, OUT=0

       // We do this repeatedly, but that's cheaper than checking.

       TA0CCTL1 &= ~OUTMOD_7;     // OUTMOD=0 (OUT). We set OUT(=0) earlier.

   }

   // After LONG_CNT short (PWM) cycles, restart the long cycle

   else

   {

       // Restart PWM. The output won't change until the second half-cycle ends.

       TA0CCTL1 |= CCTL_OUTMOD;   // Back to reset/set

       short_cycles = 0;

   }

   return;

}

 

//

// main()

//

int

main(void)

{

   WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

 

   // The request was for 50us (short period) pulses, which is not long

   // enough to reliably get through the ISR at 1MHz.

   // The next higher calibrated speed is 8MHz, so we use that.

   DCOCTL = CALDCO_8MHZ;

   BCSCTL1 = CALBC1_8MHZ;

 

   // Timer: PWM (50% duty, period SHORT_PERIOD) on P1.6=TA0.1

   // SMCLK=8MHz, so divide by /8 to get TIMER_HZ=1MHz

   short_cycles = 0;

   P1SEL |= BIT2;             // P1SEL.6=1 sets P1.6=TA0.1 [Ref SLAS735J Table 19]

   P1DIR |= BIT2;             // Set it to output since timer won't [Also Table 19]

   TA0CCR0 = SHORT_PERIOD-1;   // Short cycle time (1MHz ticks)

   TA0CCR1 = SHORT_PERIOD/2-1; // 50% duty, for no particular reason

   TA0CCTL1 = CCTL_OUTMOD|CCTL_OUT|CCIE;   // OUTMOD_7, OUT=0, IE

   TA0CTL = TASSEL_2 | ID_3 | MC_1 | TACLR; // SMCLK, /8, Up (,Clear)

 

   _EINT();                   // Enable the ISR

   while (1)

   {

       LPM0;                   // Nothing much to do here

   }

   /*NOTREACHED*/

   return 0;

}

  • Hi

    Due to your pules is fixed and the number is small you can just use the   __delay_cycles(); to make the delay and directly to toggle GPIO to generate that pulses maybe more easy.

    Gary

  • I don't see where you're changing CCR0/1.

    I suspect you could do something with setting CCR0/1 to the shorter period when (short_cycles==LONG_CNT-1) and to the longer period when (short_cycles==1). The long cycle will be shortened by half a (short) cycle; I don't know how important that is to you.

**Attention** This is a public forum