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;
}