[求助] 搞不懂MSP430FR5739的一段IIC示范程序

青菜虫子   2013-7-24 00:14 楼主
程序如下,为IIC的master通讯程序:
   
#include
unsigned char TXData =0;                    // Pointer to TX data
unsigned char TXByteCtr;
int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;
    // Init SMCLK = MCLk = ACLK = 1MHz
    CSCTL0_H = 0xA5;
    CSCTL1 |= DCOFSEL0 + DCOFSEL1;          // Set max. DCO setting = 8MHz
    CSCTL2 = SELA_3 + SELS_3 + SELM_3;      // set ACLK = MCLK = DCO
    CSCTL3 = DIVA_3 + DIVS_3 + DIVM_3;      // set all dividers to 1MHz
    // Configure Pins for I2C
    P1SEL1 |= BIT6 + BIT7;                  // Pin init
    UCB0CTLW0 |= UCSWRST;                   // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 + UCMST + UCSSEL_2;// I2C master mode, SMCLk
    UCB0BRW = 0x8;                          // baudrate = SMCLK / 8
    UCB0I2CSA = 0x48;                       // address slave is 48hex
    UCB0CTLW0 &=~ UCSWRST;             //clear reset register
    UCB0IE |= UCTXIE0 + UCNACKIE;           //transmit and NACK interrupt enable
    while(1)
    {
    __delay_cycles(1000);                   // Delay between transmissions
    TXByteCtr = 1;                          // Load TX byte counter              
    while (UCB0CTLW0 & UCTXSTP);            // Ensure stop condition got sent
    UCB0CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
                                            // Remain in LPM0 until all data
                                            // is TX'd
    TXData++;                               // Increment data byte
    }

}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
{
  switch(__even_in_range(UCB0IV,0x1E))
  {
        case 0x00: break;                    // Vector 0: No interrupts break;
        case 0x02: break;
        case 0x04:
          UCB0CTLW0 |= UCTXSTT;             //resend start if NACK
          break;                            // Vector 4: NACKIFG break;
        case 0x18:
   if (TXByteCtr)                    // Check TX byte counter
          {
            UCB0TXBUF = TXData;             // Load TX buffer
            TXByteCtr--;                    // Decrement TX byte counter

          }
          else
          {
            UCB0CTLW0 |= UCTXSTP;           // I2C stop condition
            UCB0IFG &= ~UCTXIFG;            // Clear USCI_B0 TX int flag
            __bic_SR_register_on_exit(CPUOFF);// Exit LPM0
          }
          break;                            // Vector 26: TXIFG0 break;
        default: break;
  }
}
这个程序用IAR单步执行和连续执行的结果是不一样的,所以搞不清其语句的执行次序。有疑惑的地方为高亮标出部分,主程序中执行UCB0CTLW0 |= UCTR + UCTXSTT; 执行后UCB0模块开始发送开始信号和从机地址,这部分动作可以脱离CPU执行,同时CPU继续执行下面的__bis_SR_register(CPUOFF + GIE);语句关闭CPU并打开全局中断。按照用户手册说,当UCB0模块开始发送开始信号时就置位了UCTXIFG0,等全局中断打开后就会立刻进入中断case 0x18:执行 UCB0TXBUF = TXData;             // Load TX buffer,现在的问题是这个语句是否需要CPU执行,但这时CPU还处于休眠状态如何执行?即使这句不需要CPU动作,那么后面的TXByteCtr--;  一定需要CPU执行,这时CPU不是进入休眠了吗?如何执行?

回复评论 (3)

忘了说了,用IAR连续执行的仿真结果是正确的,好像是不需要唤醒CPU就可以执行 UCB0TXBUF = TXData;           和 TXByteCtr--;     两条语句,很迷惑为何是这种结果,请大侠指点。
点赞  2013-7-24 08:29
MCU休眠之后,是可以通过中断唤醒的,执行完中断之后继续休眠。
点赞  2013-7-24 08:44
引用: 原帖由 lcofjp 于 2013-7-24 08:44 发表
MCU休眠之后,是可以通过中断唤醒的,执行完中断之后继续休眠。

晕,把这个给忘了,多谢了!
点赞  2013-7-24 08:52
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复