MSP430 Launchpad varying PWM period

Discussion in 'Embedded Systems and Microcontrollers' started by lukasoft, Oct 17, 2011.

  1. lukasoft

    Thread Starter New Member

    May 23, 2011
    9
    1
    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.

    Code ( (Unknown Language)):
    1.  
    2. #include  "msp430g2231.h"
    3. #include <signal.h>
    4.  
    5. #define     LED_BIT               (BIT0 | BIT6) // both LEDs
    6. #define     LED_DIR               P1DIR
    7. #define     LED_OUT               P1OUT
    8.  
    9. #define     SWITCH_BIT            BIT3
    10. #define     SWITCH_DIR            P1DIR
    11. #define     SWITCH_IE             P1IE      // interrupt enable
    12. #define     SWITCH_ES             P1IES     // interrupt edge select
    13.  
    14. static volatile int ticks = 0;             // tick counter
    15. static volatile int lastPressTicks = 0;    // tick count of last button press
    16. static volatile int ledPeriodTicks = 0;    // number of ticks between LED flashes
    17. static volatile int ledTimer = 0;          // LED flash downcounter (ledPeriodTicks to 0)
    18. static volatile int period = 500;
    19.  
    20.  
    21. void triangleWave();
    22. void delay ( unsigned int );
    23.  
    24.  
    25. void main(void)
    26. {
    27.   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    28.  
    29.   P1DIR |= BIT6;                            // Set P1.6 to output direction
    30.   P1SEL |= BIT6;                            // P1.6 to TA0.1
    31.  
    32.   CCR0 = period-1;                          // PWM Period
    33.   CCTL1 = OUTMOD_7;                         // CCR1 reset/set
    34.   CCR1 = 0;                                 // CCR1 PWM duty cycle
    35.   TACTL = TASSEL_2 + MC_1;                  // SMCLK, up mode
    36.  
    37.   P1IE |= BIT3;                             // P1.3 interrupt enabled
    38.   P1IES |= BIT3;                            // P1.3 Hi/lo edge
    39.   P1IFG &= ~BIT3;                           // P1.3 IFG cleared
    40.  
    41.   _BIS_SR(LPM0_bits + LPM4_bits + GIE);     // Enter LPM4 w/interrupt
    42.  
    43.   triangleWave();
    44. }
    45.  
    46. void triangleWave(){
    47.     int upDown = 1;
    48.     while(1){
    49.         CCR0 = period-1;
    50.         if (upDown == 1){
    51.             CCR1 = (CCR1 + 1) % period;
    52.             if (CCR1 == period-1) {
    53.                 upDown = 0;
    54.             }
    55.             delay(1);
    56.         }
    57.         else {
    58.             CCR1 = (CCR1 - 1) % period;
    59.             if (CCR1 == 0) {
    60.                 upDown = 1;
    61.             }
    62.             delay(1);
    63.         }
    64.     }
    65. }
    66.  
    67. void delay(unsigned int ms)
    68. {
    69.  while (ms--)
    70.     {
    71.         __delay_cycles(1000); // set for 16Mhz change it to 1000 for 1 Mhz
    72.     }
    73. }
    74.  
    75. // Port 1 interrupt service routine
    76. #pragma vector=PORT1_VECTOR
    77. __interrupt void Port_1(void)
    78. {
    79.     if((P1IFG & BIT3) == SWITCH_BIT)    // switch pressed
    80.     {
    81.         if (lastPressTicks == 0)        // first press
    82.         {
    83.             lastPressTicks = ticks;
    84.             //LED_OUT |= LED_BIT;         // Turn on LED
    85.         }
    86.         else
    87.         {
    88.             ledPeriodTicks = (ticks - lastPressTicks);
    89.             ledTimer = ledPeriodTicks;
    90.             period = ledPeriodTicks;
    91.             lastPressTicks = 0;
    92.             //LED_OUT &= ~LED_BIT;        // Turn off LED
    93.         }
    94.     }
    95.  
    96.     P1IFG = 0x00;   // clear interrupt flags
    97. }
     
  2. lukasoft

    Thread Starter New Member

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

    Code ( (Unknown Language)):
    1. #pragma vector=TIMERA0_VECTOR
    2. __interrupt void Timer_A (void)
    3. {
    4.     ticks++;
    5. }
    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.
     
Loading...