带“ MSP430”的PWM“脉冲”

问题描述

我正在尝试开发一种延迟生成器,它可以在短时间内生成50个“脉冲”,然后保持更长的时间,然后重复执行。我对将MSP 430用作恒定PWM源很熟悉,但是我不确定脉冲的最佳方法是什么,即,保持x脉冲的PWM不变。

我已附上问题的图纸,并将添加我的代码,以便任何人都可以看到我解决该问题的方法

我对使用MSP430还是很陌生,我的大部分经验是使用Arduino,所以我的代码可能无法按预期工作(这有问题)。我对如何解决问题然后对我附加的代码进行故障排除非常感兴趣。

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;
  }

解决方法

要生成PWM,请以所需的间隔对CCR0和CCRx进行编程,将定时器设置为递增模式,并设置/重置或重置/设置输出模式:

MSP430 timer up mode output example

要获得五十个脉冲,您必须等到第五十个脉冲发生后,再停止计时器。要等待脉冲结束,请为在下降沿发生的中断添加一个中断处理程序(对于TAIFG或TACCR0 CCIFG为复位/设置模式,对于TACCRx CCIFG为设置/复位模式),递增计数,如果数量已达到五十。

,

所请求的伪代码示例irq处理程序:

请记住,根据您的占空比对TACCR1进行编程,并在输出模式下对定时器进行编程。设置计时器后,您可以使CPU进入主睡眠状态。

伪代码:

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在您的帮助下,我能够产生50个脉冲。但是,第50个脉冲后,引脚电压值保持恒定

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;
  }

}