This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2xx3 Demo - USCI_B0 I2C Master to TMP100如何理解

1.    UCB0CTL1 |= UCTXSTT;                    // I2C start condition
这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?

2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗

#include <msp430.h>

unsigned int RxByteCtr;
unsigned int RxWord;

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= BIT0;                            // P1.0 output
  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = 0x4e;                         // Set slave address
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  IE2 |= UCB0RXIE;                          // Enable RX interrupt
  TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

  while (1)
  {
    RxByteCtr = 2;                          // Load RX byte counter
    UCB0CTL1 |= UCTXSTT;                    // I2C start condition
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                            // Remain in LPM0 until all data
                                            // is RX'd

    if (RxWord < 0x1d00)                    // >28C?
      P1OUT &= ~0x01;                       // No, P1.0 = 0
    else
      P1OUT |= 0x01;                        // Yes, P1.0 = 1

    __disable_interrupt();
    TACCTL0 |= CCIE;                        // TACCR0 interrupt enabled
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                            // Remain in LPM0 until TACCR0
                                            // interrupt occurs
    TACCTL0 &= ~CCIE;                       // TACCR0 interrupt disabled
  }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TA0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
}

// The USCIAB0TX_ISR is structured such that it can be used to receive any
// 2+ number of bytes by pre-loading RxByteCtr with the byte count.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
#else
#error Compiler not supported!
#endif
{
  RxByteCtr--;                              // Decrement RX byte counter

  if (RxByteCtr)
  {
    RxWord = (unsigned int)UCB0RXBUF << 8;  // Get received byte
    if (RxByteCtr == 1)                     // Only one byte left?
      UCB0CTL1 |= UCTXSTP;                  // Generate I2C stop condition
  }
  else
  {
    RxWord |= UCB0RXBUF;                    // Get final received byte,
                                            // Combine MSB and LSB
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
  }
}

  • 这个是TI 的IIC第一个例子程序,看不懂,能解释一下吗?

  • 求先知们解答一下

  • mike2 说:

    1.    UCB0CTL1 |= UCTXSTT;                    // I2C start condition
    这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?

    这条只是启动I2C,进入中断取决于I2C中断标志的产生。

    2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗

    发送数据,你只需要将发送数据放入UCB0TXBUF中,硬件模块自动会发送数据出去,如果使能发送完成中断,在数据发送完成后会有中断产生。

     代码例程中中断时接收数据的,所以去读取UCB0RXBUF 的数值。

    #include <msp430.h>

    unsigned int RxByteCtr;
    unsigned int RxWord;

    int main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      P1DIR |= BIT0;                            // P1.0 output
      P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
      P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
      UCB0CTL1 |= UCSWRST;                      // Enable SW reset
      UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
      UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
      UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB0BR1 = 0;
      UCB0I2CSA = 0x4e;                         // Set slave address
      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
      IE2 |= UCB0RXIE;                          // Enable RX interrupt
      TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

      while (1)
      {
        RxByteCtr = 2;                          // Load RX byte counter
        UCB0CTL1 |= UCTXSTT;                    // I2C start condition
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                                // Remain in LPM0 until all data
                                                // is RX'd

        if (RxWord < 0x1d00)                    // >28C?
          P1OUT &= ~0x01;                       // No, P1.0 = 0
        else
          P1OUT |= 0x01;                        // Yes, P1.0 = 1

        __disable_interrupt();
        TACCTL0 |= CCIE;                        // TACCR0 interrupt enabled
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                                // Remain in LPM0 until TACCR0
                                                // interrupt occurs
        TACCTL0 &= ~CCIE;                       // TACCR0 interrupt disabled
      }
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TA0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
    }

    // The USCIAB0TX_ISR is structured such that it can be used to receive any
    // 2+ number of bytes by pre-loading RxByteCtr with the byte count.
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      RxByteCtr--;                              // Decrement RX byte counter

      if (RxByteCtr)
      {
        RxWord = (unsigned int)UCB0RXBUF << 8;  // Get received byte
        if (RxByteCtr == 1)                     // Only one byte left?
          UCB0CTL1 |= UCTXSTP;                  // Generate I2C stop condition
      }
      else
      {
        RxWord |= UCB0RXBUF;                    // Get final received byte,
                                                // Combine MSB and LSB
        __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
      }
    }

  • Maka 说:

    1.    UCB0CTL1 |= UCTXSTT;                    // I2C start condition
    这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?

    这条只是启动I2C,进入中断取决于I2C中断标志的产生。

    非常感谢回复,本例中如果一切硬件正常,启动i2c开始后,立刻会进入后面的iic中断处理程序吗?这样在iic中断处理完成后才运行下面一句进入低功耗?还是先进入低功耗,后来定时器中断中打开全局中断允许,待传感器返回应答才进入iic中断处理程序?

    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts

    2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗

    发送数据,你只需要将发送数据放入UCB0TXBUF中,硬件模块自动会发送数据出去,如果使能发送完成中断,在数据发送完成后会有中断产生。

     代码例程中中断时接收数据的,所以去读取UCB0RXBUF 的数值。

    我意思是本例是单片机读取数据,为什么中断程序是interrupt(USCIAB0TX_VECTOR),这个是发送的中断吧?请原谅初学者的简单问题



    #include <msp430.h>

    unsigned int RxByteCtr;
    unsigned int RxWord;

    int main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      P1DIR |= BIT0;                            // P1.0 output
      P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
      P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
      UCB0CTL1 |= UCSWRST;                      // Enable SW reset
      UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
      UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
      UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB0BR1 = 0;
      UCB0I2CSA = 0x4e;                         // Set slave address
      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
      IE2 |= UCB0RXIE;                          // Enable RX interrupt
      TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

      while (1)
      {
        RxByteCtr = 2;                          // Load RX byte counter
        UCB0CTL1 |= UCTXSTT;                    // I2C start condition
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                                // Remain in LPM0 until all data
                                                // is RX'd

        if (RxWord < 0x1d00)                    // >28C?
          P1OUT &= ~0x01;                       // No, P1.0 = 0
        else
          P1OUT |= 0x01;                        // Yes, P1.0 = 1

        __disable_interrupt();
        TACCTL0 |= CCIE;                        // TACCR0 interrupt enabled
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                                // Remain in LPM0 until TACCR0
                                                // interrupt occurs
        TACCTL0 &= ~CCIE;                       // TACCR0 interrupt disabled
      }
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TA0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
    }

    // The USCIAB0TX_ISR is structured such that it can be used to receive any
    // 2+ number of bytes by pre-loading RxByteCtr with the byte count.
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      RxByteCtr--;                              // Decrement RX byte counter

      if (RxByteCtr)
      {
        RxWord = (unsigned int)UCB0RXBUF << 8;  // Get received byte
        if (RxByteCtr == 1)                     // Only one byte left?
          UCB0CTL1 |= UCTXSTP;                  // Generate I2C stop condition
      }
      else
      {
        RxWord |= UCB0RXBUF;                    // Get final received byte,
                                                // Combine MSB and LSB
        __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
      }
    }

    [/quote]