TI MSP430的低功耗模式

时间:2014-02-12 11:11:03

标签: performance timer embedded interrupt-handling msp430

我正在使用MSP430F2274并尝试更好地了解低功耗模式的使用。

在我的程序中,我也使用SimplicTi API,以便两个设备(一个是 AP ,由另一个连接, ED )进行通信。

AP - 接入点,通过 UART 连接到PC,以便从用户那里收回字符串。

ED - 终端设备,只需连接到AP(使用SimplicTi协议)并等待来自它的消息。

我想确定我了解低功耗模式的用途,并了解它是如何与“SimplicTi API”结合使用的。

AP的“流程”如下(在与ED“链接”之后,请参阅下面的代码):

#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
   // **A)** extract the "RXed" character (8 bits received from user) , use the while 
   // in order to be sure all the 8 bits are "desirialized" into a byte  
   while (!(IFG2 & UCA0RXIFG));   
   input_char = UCA0RXBUF;     // input_char is global variable.

   // **B)** if we received the "Enter" character , which indicates the 
   //    end of the string 
   if(input_char == '\r' && input_count > 0)      
   {

      TACCR0 = 10;   // **F)**
      TACTL = TASSEL_1 + MC_1; // ACLK, up mode
      // **E)** Enter LPM3, interrupts enabled !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      __bis_SR_register(LPM3_bits + GIE); 

    }//end if Enter


    // **C)** Any other char of the user's string when we 
   //    have not got more than the maximum amount of bytes(chars)
    else if (((FIRST_CHAR <= input_char && input_char <= LAST_CHAR) || ('a' <=  input_char && input_char <= 'z')) && (input_count < INPUT_MAX_LENGTH)) 
    {
        input[input_count++] = input_char;
    }


}  //end of UART RX INTERRUPT

TIMERA0中断处理程序是以下代码:

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
    if (i == strlen(morse))      // **D)** morse is a global array of chars  who holds the string that we wish to send 
    {
        SMPL_Send(sLID[0], (uint8_t*)EOT, 1);             // EOT is the last char to send 
        TACTL = MC_0;                         //disable  TimerA0 
    }


    else if (!letterSpace)
    {
       char ch = morse[i++];  
       SMPL_Send(sLID[0], (char*)ch, 1); 

       switch(ch)
       {
         case '.':
           {
             TACCR0 = INTERVAL * 3;
             letterSpace = 1;
             break;
           }

          case '-':
           {
              TACCR0 = INTERVAL * 3 * 3;
              letterSpace = 1;
               break;
            }
       } // switch 

   }  // else if 

}  //end TIMERA0 interrupt handler 

事情就是这样:

我使用TIMERA0处理程序,以便在不同类型的数据后发送每个字节,无论char是转换为“ - ”还是“。”。

为此,我将计时器设置为不同的值(“ - ”为3倍)。

Finnaly当我完成传输整个字符串( D )时,我禁用了计时器。

注意:在AP代码开头执行以下方法以配置UART:

void UARTinit()
{
    P3SEL = 0x30;           // P3.4 and P3.5 as the UART  TX/RX pins: P3SEL |= BIT4 + BIT5;                
    UCA0CTL1 |= UCSSEL_2;  // SMCLK    

    // pre scale  1MHz/9600 =~ 104. 
    UCA0BR0 = 104;         
    UCA0BR1 = 0;     

    // 8-bit character and Modulation UCBRSx = 1
    UCTL0 |= CHAR;  
    UCA0MCTL = UCBRS0;  

    UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;                          // Enable UART INPUT interrupt

}  // end of UARTinit

所以我的问题是:

1)只是确定,在 A)我在哪里“轮询”UART的Rx缓冲区,这是不必要的还是“任何情况下”的好习惯,导致AFAIK一旦UART模块重新获得整个 BYTE (我配置它),UART 处理程序就会被调用

2)在AP的主程序中,最后一条指令是将其“放入”LPM0,中断使能:__bis_SR_register(LPM0_bits + GIE);

对于LPM0:

  • CPU已禁用
  • ACLK和SMCLK保持活动状态
  • MCLK已停用

对于LPM3:

  • CPU已禁用
  • MCLK和SMCLK已停用
  • ACLK保持活动状态

在我看来,我无法进入LPM3因为AP需要SMCLK时钟不能禁用? (因为UART使用它) 那是对的吗?

3)在 F)中,是否是调用TIMERA0处理程序的正确方法?我执行TACRR0 = 10,因为它是一个很小的值,计时器将立即“到达”,这样它就会进入TIMERA0处理程序来执行发送字符串字节的任务。

4)对于AP中的“回滚”:正如我所看到的,“流程”就是这样:

进入LPM0(主要) - &gt; UART得到了相互比较 - &gt;退出LPM0并转到UART处理程序 - &gt;当它完成恢复字节(通常为5)时,它进入LPM3 - &gt;计时器完成计数到TACRR0值(即10) - &gt;调用TIMERA0处理程序 - &gt;当TIMERA0处理程序完成发送最后一个字节时,它会禁用定时器(TACTL0 = MC_0;) - &gt;我们“回滚”到UART处理程序中将我们带到LPM3的指令 - &gt;的 ...

现在, ?? 是否“回滚”到主程序中将我们带到LPM0的指令,或者我们“留在这里”(在我们进入LPM3的指令中) UART处理程序 E)? 如果我们确实留在 E),我是否需要将其更改为LPM0,因为UART再次使用在LPM3中未激活但在LPM0中确实有效的SMCLK?

5)任何其他评论都会超级!!

谢谢分配, 盖伊。

1 个答案:

答案 0 :(得分:1)

1)这将有效

2)配置时:

UCA0CTL1 |= UCSSEL_2;  // SMCLK

这意味着 UART 使用SMCLK,当您将MCU转向LPM3时,SMCLK将停止;因此 UART不起作用,你应该配置UART使用ACLK,这将使UART工作在LPM3模式。

3)...

4)...

5)见2

我希望这会对你有所帮助