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.

[参考译文] LP-MSP430FR2476:I2C 仅在关闭同一端口 LED 时工作

Guru**** 2387060 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1085621/lp-msp430fr2476-i2c-only-functions-if-same-port-led-is-turned-off

部件号:LP-MSP430FR2476

您好,

我一直在使用启动板连接到 I2C 设备,使用 TI 提供的修改版 I2C 库。

我发现,如果引脚1.0上的 LED 同时亮起,则端口1的引脚2和3上的 I2C 模块将无法工作。 我在主部件的不同部分打开它后,能够验证这一点。 您可以在此处查看相关部分

while(reg!=2)
{
    i2c_master_read(0x41, 0xe0, &reg, 1);
}
reg = 1;
i2c_master_write(0x41, 0xe0, &reg, 1);

P1OUT = BIT0;

while(reg != 65)
{
    i2c_master_read(0x41, 0xe0, &reg, 1);
}

无论我在哪里说,该程序都会停止,因为 I2C 装置不再工作,并且保持在 LPM0中。

我是否缺少任何内容,或者 LED 和低功耗模式是否有某种关联? 如果 LED 亮起,则 I2C 工作所需的中断不会触发。

为此,您可以看到我正在使用的 i2c 库:

I2C_Mode i2c_master_read(uint8_t devAdd, uint8_t regAdd, uint8_t* readBuf, uint8_t count)
{
    rxComplete = 0;
    /* Initialize state machine */
    masterMode = TX_REG_ADDRESS_MODE;
    transmitRegAddr = regAdd;
    rxByteCtr = count;
    txByteCtr = 0;
    receiveIndex = 0;
    transmitIndex = 0;
    receiveBuffer = readBuf;

    /* Initialize slave address and interrupts */
    UCB0I2CSA = devAdd;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB0IE |= UCTXIE;                        // Enable TX interrupt

    UCB0CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition

    __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts

    return 0;

}

I2C_Mode i2c_master_write(uint8_t devAdd, uint8_t regAdd, const uint8_t* regData, uint8_t count)
{
    txComplete = 0;
    /* Initialize state machine */
    masterMode = TX_REG_ADDRESS_MODE;
    transmitRegAddr = regAdd;

    //Copy register data to TransmitBuffer
    transmitBuffer = regData;

    txByteCtr = count;
    rxByteCtr = 0;
    receiveIndex = 0;
    transmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB0I2CSA = devAdd;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB0IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB0IE |= UCTXIE;                        // Enable TX interrupt

    UCB0CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts

    return 0;
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB0RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
        rx_val = UCB0RXBUF;
        if (rxByteCtr)
        {
          receiveBuffer[receiveIndex++] = rx_val;
          rxByteCtr--;
        }

        if (rxByteCtr == 1)
        {
          UCB0CTLW0 |= UCTXSTP;
        }
        else if (rxByteCtr == 0)
        {
          UCB0IE &= ~UCRXIE;
          masterMode = IDLE_MODE;
          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
          P5OUT |= BIT1;
          P4OUT &= ~BIT7;
//          rxComplete = 1;
        }
        break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
        switch (masterMode)
        {
          case TX_REG_ADDRESS_MODE:
              UCB0TXBUF = transmitRegAddr;
              if (rxByteCtr)
                  masterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
              else
                  masterMode = TX_DATA_MODE;        // Continue to transmission with the data in Transmit Buffer
              break;

          case SWITCH_TO_RX_MODE:
              UCB0IE |= UCRXIE;              // Enable RX interrupt
              UCB0IE &= ~UCTXIE;             // Disable TX interrupt
              UCB0CTLW0 &= ~UCTR;            // Switch to receiver
              masterMode = RX_DATA_MODE;    // State state is to receive data
              UCB0CTLW0 |= UCTXSTT;          // Send repeated start
              if (rxByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB0CTLW0 & UCTXSTT));
                  UCB0CTLW0 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (txByteCtr)
              {
                  UCB0TXBUF = transmitBuffer[transmitIndex++];
                  txByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB0CTLW0 |= UCTXSTP;     // Send stop condition
                  masterMode = IDLE_MODE;
                  UCB0IE &= ~UCTXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
//                  txComplete = 1;
              }
              break;

          default:
              __no_operation();
              break;
        }
        break;
    default: break;
  }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看不到您在哪里配置您的(P1) PIN。 跳出来的是:

    > P1OUT = BIT0;

    设置 P1中的所有引脚。 特别是,如果磁带库已启用 P1REN 下拉菜单,这将使它们更改为下拉菜单。

    无论如何,更换您不知道的针脚是危险的。 请尝试:

    > P1OUT |= BIT0;// P1.0 (仅限)高

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    哦,谢谢你,或者肯定已经错过了某个地方。 不幸的是,我在盯着它几个小时后,没有发现什么遗漏。