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.

CCS/MSP430G2231: msp430g2231 to pwm soft stop

Part Number: MSP430G2231

Tool/software: Code Composer Studio

hi everyone

i have msp430g2231 chip and i want to software pwm signals for soft stop led light

i researched datasheet and internet but i cant make output pwm signal from its.

could you help me for this .

i use CCS texas program.

P1.1 , P1.2 P1.5 P1.6 P2.6  those pins are i can use pwm signal with Timer_A

#include <msp430g2231.h>

int IncDec_PWM = 1;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
DCOCTL = 0; // Select lowest DCOx and MODx
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation

P1DIR |= 0x06; // P1.1 and P1.2 output
P1SEL |= 0x06; // P1.1 and P1.2 TA0./1 otions

TA0CCR0 = 1000; // PWM Period/2
TA0CCTL1 = OUTMOD_7; // CCR1 toggle/set
TA0CCR1 = 1; // CCR1 PWM duty cycle
TA0CTL = TASSEL_2 + MC_1; // ACLK, up-down mode

_BIS_SR(LPM3_bits); // Enter LPM3

#pragma vector =TIMER0_A0_VECTOR
__interrupt void TIMER_A0 (void);
{
TA0CCR1 += IncDec_PWM*2; // Increase or decrease duty cycle

if( TA0CCR1 > 998 || TA0CCR1 < 2 ) // Reverse direction if it falls within values
IncDec_PWM = -IncDec_PWM;
}

  • I don't see where you enable interrupts (GIE). Try:
    > _BIS_SR(LPM3_bits|GIE); // Enter LPM3 with interrupts enabled
  • Oh, and you'll also need to enable the CCR0 interrupt:
    > TA0CCTL0 = CCIE; // Enable TIMER0_A0_VECTOR interrupt
  • Firstly, thank you for interest my problem
    I wrote other code for pwm , I took square wave and blik a led.
    but i wanto soft stop led (dim led) . could you help me for this?
    best regards

    #include <msp430g2231.h>


    void main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
    DCOCTL = CALDCO_1MHZ; //SET DCO STEP + MODULATION
    BCSCTL1 = CALBC1_1MHZ; //SET RANGE

    P1DIR |= BIT2; // P1.2 OUTPUT
    P1SEL |= BIT2; // TA0.1 ENABLE
    P1OUT |= BIT2; // P1.2 RESISTOR PULL-UP
    P1REN |= BIT2; //RESISTOR ENABLE

    TACCR0 = 1000; // PWM PERIOD
    TACCR1 = 600; // DUTY CYCLE
    TACCTL1 = OUTMOD_7; // RESET/SET
    TACTL = TASSEL_2 + MC_1 ; //SMCLK, UP MODE,


    while(1)
    {

    }

    }
  • You haven't defined what "soft stop" means, but if it means not just abruptly going to 0% duty cycle, I think you had most of that in your original code -- just stop when you get to 0 ("<2") rather than reversing direction.

    One thing I have done in the past is what might be called "soft switch": The control part of the program (presumably main()) sets a variable indicating the target duty cycle, then the CCR0 ISR steps (rather than just switching immediately) towards that target value. This is similar to what your original code did, but with a variable target (not just 0 and 1000). To switch the LED completely off ("softly") you just set the target to 0.
  • for example dimmer led

    When it is begin to stop led light not immediately stop, softly stop. for example when DC motor is stop softly. 

    Look at the graphical please. 

  • That's more or less what I guessed. Did you try any of my suggestions?
  • Hi again i used yours code but they didn't right work,
    When i started debug this messages worning to me.
    "MSP430: Can't Single Step Target Program: CPU is currently OFF and debugging capabilities will be limited."
    And #pragma vector is didnt work . How can i used Timers for led dimming so soft stop brightness.


    #include <msp430.h>
    #include <sys/types.h>
    #define LED BIT2

    volatile uint16_t count;
    volatile uint16_t pwm;

    int main(void)
    {
    count=1000, pwm=5000;
    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer

    DCOCTL = CALDCO_1MHZ; //SET DCO STEP + MODULATION
    BCSCTL1 = CALBC1_1MHZ; //SET RANGE

    P1DIR |= LED;
    P1SEL |= LED;
    P1REN = 1;
    P1OUT = 1;

    TA0CCTL0 = CCIE; // Enable TIMER0_A0_VECTOR interrupt
    TA0CCR0 = 10000; // pwm period
    TA0CCR1 = 2000; // duty cycle
    TA0CCTL1= OUTMOD_7 | OUT; // reset set mode
    TA0CTL = TASSEL_2 | MC_1 | ID_0 ; //SMCLK, UP MODE, DIVIDER/1

    __enable_interrupt();
    _BIS_SR(LPM3_bits | GIE); // Enter LPM3 with interrupts enabled

    #pragma vector=TIMER0_A1_VECTOR
    __interrupt void Timer_A1(void);
    {

    if(count)
    {
    count--;
    }
    }


    while (1)
    {
    for(pwm;pwm>0;pwm--)
    {

    TACCR1=pwm;
    __delay_cycles(1000);
    TACCR1=0;
    }

    }

    return 0;
    }
  • Also this messages worning to me too. how can i solve this.

    Description Resource Path Location Type
    #10443-D null: The ".stack" section size is required to be aligned to 4 bytes, but the specified size, 0x32, is not. The aligned size is 0x34 g2231_pwm C/C++ Problem
  • You appear to have placed your ISR in the middle of main(). Move it outside. You'll need to get rid of that semicolon (";") on the __interrupt line and change the vector= back to TIMER0_A0_VECTOR.
    -----------
    Now try adding this 

    // Add this as a global variable:
    volatile unsigned int ccr1_target; // Shared between main and ISR
    
    // then something like this in the ISR:
    if (TA0CCR1 < ccr1_target)
      TA0CCR1 += 1; // Step up towards target
    else if (TA0CCR1 > ccr1_target)
      TA0CCR1 -= 1; // Step down towards target
    else
      /*EMPTY*/; // The target has been reached; don't change TA0CCR1, and maybe notify main()
    

    Then assign ccr1_target to the duty cycle you want (maybe 0) and wait for it to get there.

    Keep in mind that this can take a while -- with this TA0CCR0 value 10ms/step -- so delaying for 1000 cycles (1ms) is much too short. I suggest you go back to a 1ms period, both for this and to avoid flicker.

  • Hi again

    Thank you so much.

**Attention** This is a public forum