C Program Pulse Width Modulation

How to write a C Program Pulse Width Modulation in C Programming Language ?


This C Program Pulse Width Modulation.

Description: This code controls a servo using PWM via Timer A.  Three external buttons are used to change the servo's position.  Button 0 rotates the servo CCW in 5ms increments.  Button 1 rotates the servo to its center position.  Button 2 rotates the servo CW in 5ms increments.

Solution:

  1. #include <msp430.h>
  2. /*
  3.  * main.c
  4.  *Pulse Width Modulation
  5.  *
  6.  * Description:
  7.  * This code controls a servo using PWM via Timer A.  Three external buttons are used to change
  8.  * the servo's position.  Button 0 rotates the servo CCW in 5ms increments.  Button 1 rotates
  9.  * the servo to its center position.  Button 2 rotates the servo CW in 5ms increments.
  10.  *
  11.  */
  12. #define ms_20        655   // 20.0 ms
  13. int PositionIndex = 6;
  14. int main(void)
  15. {
  16.   WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  17.   P1DIR |= BIT2;                            // P1.2 output
  18.   P2IE |= BIT0 + BIT1 + BIT2;               // Interrupt enabled for external buttons
  19.   P2IES &= ~(BIT0 + BIT1 + BIT2);           // Interrupt low to high enable
  20.   P2IFG &= ~(BIT0 + BIT1 + BIT2);           // IFG clear
  21.   // Using P1.2 for hardware set/reset as when TAR hits CCRO and CCR1 values.
  22.   // This allows P1.2 to toggle outside of software control.  Note that Timer A
  23.   // is running compare mode but interrupts are not being utilized.
  24.   // Note that this feature of toggling port bits outside of software control
  25.   // may be utilized while cpu is in low power mode.
  26.   P1SEL |= BIT2;                            // P1.2 TA1/2 options
  27.   // Setting CCR0 for a 20 ms period with CCTL1 determining pulse width (duty
  28.   // cycle) as determined by OUTMOD_7.
  29.   CCR0 = ms_20 - 1;                         // PWM Period of 20 ms
  30.   CCTL1 = OUTMOD_7;                         // CCR1 reset/set
  31.   TACTL = TASSEL_1 + MC_1;                  // ACLK, up mode
  32.   _enable_interrupt();
  33.   while(1);
  34. }
  35. #pragma vector=PORT2_VECTOR
  36. __interrupt void Port_2(void)
  37. {
  38.     // if statement determines when rotated to the max position (CW or CCW)
  39.     if(PositionIndex > 11){
  40.         PositionIndex = 11;
  41.     }
  42.     else if(PositionIndex < 1){
  43.         PositionIndex = 1;
  44.     }
  45.     else{
  46.     }
  47.     // if statement controls the servo based on button press
  48.     if((P2IFG & BIT0) == BIT0){
  49.            PositionIndex--;
  50.            P2IFG &= ~BIT0;
  51.         }
  52.     else if((P2IFG & BIT2) == BIT2){
  53.         PositionIndex++;
  54.         P2IFG &= ~BIT2;
  55.     }
  56.     else{
  57.         PositionIndex = 6;
  58.         P2IFG &= ~BIT1;
  59.     }
  60.     CCR1 = (PositionIndex*5) + 20; // update servo's position based on PositionIndex value
  61. }


Learn More :