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.

simple MSP430 PWM problem....

Other Parts Discussed in Thread: MSP430G2231


#include "msp430G2231.h"
#define BUTTON BIT3
unsigned int duty = 900;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P1DIR |= BIT0; // P1.0 to output
P1SEL |= BIT0; // P1.0to TA0.1
P1IE |= BUTTON;
__enable_interrupt();
CCR0 = 1000-1; // PWM Period
CCTL1 = OUTMOD_7; // CCR1 reset/set
CCR1 = duty; // CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode

_BIS_SR(LPM0_bits); // Enter LPM0
}

#pragma vector=PORT1_VECTOR

__interrupt void Port_1(void)
{
    duty = duty + 20;
    P1IFG &=~BUTTON;
}

Hello everyone, I am trying to learn MSP430 on my own and I am trying to combine the pwm example with the push button interrupt. However, my code does not work and I don't under stand why....

  • ** problem: I tried to change the duty cycle to 0 by set duty =0; but my led is still on and it seems that no matter how high the duty cycle is the led is at a constant brightness.

  • I'm assuming you intend to increase the duty cycle of the PWM output every time you press the button, correct?

    It would be good to verify some basic functionality first.

    Are you observing an actual PWM output on P1.0 with the duty cycle of the initial condition?

    Are you getting into the Port_1 interrupt service routine when pressing the button?

    Assuming yes to both of those, within the Port_1 interrupt service routine you are updating the duty variable.  However, the Timer0 CCR1 is never updated with the new duty cycle.  I would recommend you add another interrupt service routine for the Timer0 CCR0 interrupt.  Within this interrupt service routine, assign CCR1 = duty.

    // Timer A0 interrupt service routine
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      CCR1 = duty; // update CCR1 PWM duty cycle
    }

    You will also need to enable the Timer0 CCR0 interrupt in the main() function.

      CCTL0 = CCIE;                             // CCR0 interrupt enabled
     

  • Thanks for the response, it seems that in the example it uses pin 1.2 and I can see pwm signal on the scope but when I switch to p1.0 or p1.6 the pwm doesnt work anymore.

  • You are correct, it needs to be P1.2 to see the Timer0 CCR1 output.  Therefore your initialization needs to be as follows:

    P1DIR |= BIT2; // P1.2 to output
    P1SEL |= BIT2; // P1.2 to TA0.1

  • P1.6 can be used too.

    A LED of a different color.

**Attention** This is a public forum