Jump to content
43oh

430 variable pulse width modulation


Recommended Posts

Hello everyone, I'm fairly new to the whole MCU thing, so I'm just trying to wet my feet with my own sample program. I'm using the launchpad and am working with the sample chip that came with it, although I don't think that will affect my problem too much. What I'm trying to do is create a pulse width modulation with the LED that varies in intensity for a given period.

 

Now it turns out this isn't too difficult, and I've gotten it to work. But to familiarize myself with the inputs as well as outputs I would like to have the button on the launchpad control the period based on two button presses (the time between the two button presses becomes the period). I have code that does most of this, but it seems to me the fact that I'm using an interrupt is screwing everything else up.

 

Eventually I gave up on the interrupts and tried to use a polling scheme but I just couldn't get that to work either. Here is the code I currently have (the interrupt routines are commented out and the poll is enabled). I understand it's sloppy code, but I only really half know what I'm doing so that makes it difficult to clean things up. Also I'm using CCS, which may affect things (not really sure)

 


#include  "msp430g2231.h"
#include 

#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 = 300;


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


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
	// Enable interrupt for TACCR0 match
 //TACCTL0 = CCIE;
	// Set TACCR0, starts timer
 //TACCR0 = 1;


 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);
	}
	//try polling for switches instead of interrupts
	poll();
}
}

void poll(){
if ((BIT3 & P1IN)) // active low switch
{//if button is not pressed
}
else{//if button is pressed
	if (lastPressTicks == 0)        // first press
      	{
      		//change this to get the amount of clock cycles
      	    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
      	}
}
}

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
}

// Timer0 ISR

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
   ticks++;
}
*/

 

if you can point me in the right direction it would be much appreciated. I think I would prefer the interrupt routine if it can easily be fixed, as that was my original goal. Thanks for your time and help.

Link to post
Share on other sites

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

 triangleWave();
}

 

may be try and comment out the _BIS_SR line? looks like u had entered into some good sleep LPM0+LPM4 and there is no one waking u up. i.e. triangleWave() may have never got executed.

 

i haven't try it, just looking that code, may or may not solve your problem.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...