# MSP430 Launchpad varying PWM period

#### lukasoft

Joined May 23, 2011
9
Hello everyone. I'm fairly new to microcontrollers, but not very new to circuits in general. I'm working with the MSP430 by TI, and am trying to get a demo of varying period PWM as well as varying duty cycle. The duty cycle currently just increases and decreases in a triangle-wave form, so that the output LED pulsates. I am attempting to get the period of oscillation to be controlled through the time between two button presses on the development board, so this is not a PWM problem as much as it is a timing problem. My code may be sloppy, as I am new to programming microcontrollers (not used to all these defines, they're all over the place), so please bear with me. I am trying to use the port 1 interrupt to catch the button press, although it seems that nothing is happening when I press the button multiple consecutive times. Any guidance on this would be appreciated, as I have been trying to get this to work for a while, and can't seem to find a good resource for examples of programs that do more than just one function (such as only pwm or only interrupt on button press). Thank you.

Rich (BB code):
#include  "msp430g2231.h"
#include <signal.h>

#define     LED_BIT               (BIT0 | BIT6) // both LEDs
#define     LED_DIR               P1DIR
#define     LED_OUT               P1OUT

#define     SWITCH_BIT            BIT3
#define     SWITCH_DIR            P1DIR
#define     SWITCH_IE             P1IE      // interrupt enable
#define     SWITCH_ES             P1IES     // interrupt edge select

static volatile int ticks = 0;             // tick counter
static volatile int lastPressTicks = 0;    // tick count of last button press
static volatile int ledPeriodTicks = 0;    // number of ticks between LED flashes
static volatile int ledTimer = 0;          // LED flash downcounter (ledPeriodTicks to 0)
static volatile int period = 500;

void triangleWave();
void delay ( unsigned int );

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

P1DIR |= BIT6;                            // Set P1.6 to output direction
P1SEL |= BIT6;							// P1.6 to TA0.1

CCR0 = period-1;             				// PWM Period
CCTL1 = OUTMOD_7;          				// CCR1 reset/set
CCR1 = 0;                					// CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_1;   				// SMCLK, up mode

P1IE |= BIT3;                             // P1.3 interrupt enabled
P1IES |= BIT3;                            // P1.3 Hi/lo edge
P1IFG &= ~BIT3;                           // P1.3 IFG cleared

_BIS_SR(LPM0_bits + LPM4_bits + GIE);     // Enter LPM4 w/interrupt

triangleWave();
}

void triangleWave(){
int upDown = 1;
while(1){
CCR0 = period-1;
if (upDown == 1){
CCR1 = (CCR1 + 1) % period;
if (CCR1 == period-1) {
upDown = 0;
}
delay(1);
}
else {
CCR1 = (CCR1 - 1) % period;
if (CCR1 == 0) {
upDown = 1;
}
delay(1);
}
}
}

void delay(unsigned int ms)
{
while (ms--)
{
__delay_cycles(1000); // set for 16Mhz change it to 1000 for 1 Mhz
}
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if((P1IFG & BIT3) == SWITCH_BIT)    // switch pressed
{
if (lastPressTicks == 0)        // first press
{
lastPressTicks = ticks;
//LED_OUT |= LED_BIT;         // Turn on LED
}
else
{
ledPeriodTicks = (ticks - lastPressTicks);
ledTimer = ledPeriodTicks;
period = ledPeriodTicks;
lastPressTicks = 0;
//LED_OUT &= ~LED_BIT;        // Turn off LED
}
}

P1IFG = 0x00;   // clear interrupt flags
}

#### lukasoft

Joined May 23, 2011
9
I have also tried including the code:

Rich (BB code):
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
ticks++;
}
at the end, however I think it is eating up all of the processing time and not allowing anything else to run. I'm not sure how to avoid this.