1

I am trying to develop a delay generator that can generate 50 "pulses" within a short amount of time and then hold for a much longer time, then repeat. I am familiar with using the MSP 430 as a constant PWM source, but I am not sure what the best approach is for Pulsing, ie, PWM for x pulses then hold.

I have attached a drawing of the problem, and I will add my code so that anyone can see my approach to the problem.

I am still new to using MSP430, most of my experience is with Arduino, so my code may not work as intended (it has a problem). I am more so interested in how to approach the problem then troubleshooting the code I attached.

Drawing of Problem statement

#include <msp430.h>
int i;

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= BIT2;                            // P1.2 output
  P1SEL = BIT2;                             // Select PWM function for P1.2
  P1REN = BIT1;                             // enable pull up resistor for button P1.1
  P1IE |= BIT1;                             // Interrupt enabled for P1.1
  P1IES |= BIT1;                            // Interrupt active on falling edge
  __bis_SR_register(GIE);                   // Global Interrupt Enable
  __no_operation();                         // For debugger
}

#pragma vector = PORT1_VECTOR
  __interrupt void PORT_1(void) {
      for (i = 50; i = 0; i--) {
          TA0CCR0 = 50000;                  // PWM Period
          TA0CTL = TASSEL_2 + MC_1;         // SMCLK, upmode
      }
      P1IFG &= ~BIT1;
  }
CL.
  • 173,858
  • 17
  • 217
  • 259
CLand
  • 11
  • 2
  • What are you trying to achieve setting the same parameters to the timer fifty times? You should set TACCR0 accordingly to the the period you desire, then in the overflow interrupt of the timer count the pulses, then on the fiftieth one change the timer parameters to do the long one. – Damiano Sep 11 '20 at 08:48
  • @Damiano, could you provide an example? I made these changes based on your comment. I want to add a snippet of the changes I made based on your comment but I cannot seem to properly formate the code or add pictures to this comment. – CLand Sep 17 '20 at 20:57

3 Answers3

1

To generate PWM, you program CCR0 and CCRx with the desired intervals, the timer in up mode, and the output mode set/reset or reset/set:

MSP430 timer up mode output example

To get fifty pulses, you have to wait until the fiftieth pulse has happened, and then stop the timer. To wait for the end of a pulse, add an interrupt handler for the interrupt that happens at the falling edge (TAIFG or TACCR0 CCIFG for reset/set mode, or TACCRx CCIFG for set/reset mode), count up, and stop if the count has reached fifty.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Probably he doesn't need to stop the timer, just update TACCR0. If the pulse is enough long respect to the system frequency, he should be able to switch from the short period to the long and backwards without gliches. – Damiano Sep 14 '20 at 06:11
0

A sample irq handler in pseudo code as requested:

Remember to program TACCR1 accordingly to your duty cycle and program the timer in output mode. You can put your cpu to sleep in the main after the timer setup.

Pseudo code:

static int counter = 0;

void timer_taccr0_irq_handler() //overflow
{
    if (counter == 49) {
        TACCR0 = <longperiod>;
        TACCTL0 &= OUTMOD_RESET_MODE;
    }
    else if (counter == 0)
    {
        TACCR0 = <short period>
        TACCTL0 |= OUTMOD_RESET_SET_MODE;
    }
    if (++counter > 49)
        counter = 0;
}
Damiano
  • 698
  • 7
  • 19
0

@Damiano I was able to generate 50 pulses with your help. However, the pin voltage value stays constant after the 50ith pulse

enter image description here

#include <msp430.h>
static int counter = 0;
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                
  P1DIR |= BIT2;                            
  TA0CCTL0 = CCIE;                           
  TA0CCR0 = 10000;                          
  TA0CTL = TASSEL_2 + MC_1 + TACLR;         

  __bis_SR_register(LPM0_bits + GIE);       
  __no_operation();                         
}

// Timer0 A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
  P1OUT ^= BIT2;                            
  ++counter;

  if (counter == 99) {
              TA0CCR0 = 20000;
              TA0CCTL0 &= OUTMOD_7;       
          }
  else if (counter == 0) {
              TA0CCR0 = 10000;
              TA0CCTL0 |= OUTMOD_7;                        
          }

  if (counter > 99) {
      counter = 0;
      P1OUT ^= BIT2;
      TA0CCTL0 = OUTMOD_7;
  }

}
CLand
  • 11
  • 2
  • I think you're switching between MODE7 and MODE0 because your clearing all 3bit of the outmod settings.... you need to toggle only the 3rd bit to change from MODE7 to MODE3 and back .... Probably you're looking for OUTMODE7 define instead OUTMODE_7. Why you are toogling P1OUT? If you want to get the right pwm you should let your timer toggle the pin. – Damiano Sep 23 '20 at 13:19
  • P.s. You should update your question instead of posting answers. – Damiano Sep 24 '20 at 09:04
  • @Damiano, I think I understand how the outmod_x works now. The last thing I am still not clear on is which pin I am assigning the output to. Do I assign it myself? is there a predetermined pin? I am under the impression that TA0CCR0 will be my pin trigger, is that correct? – CLand Sep 28 '20 at 19:14
  • Depending on micro and package there are predefined pins one or multiple for each timer. You must check the datasheet and choose the pin accordingly to your model. – Damiano Sep 29 '20 at 06:40