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.

【求助】关于MSP430通过硬件I2C接口连接从器件ADT7420的问题

Other Parts Discussed in Thread: MSP430F5529

我将MSP430F5529作为主接收器件,ADT7420温度传感器作为从发送器件,连接在P4.1以及P4.2。在SDA以及scl上都加了上拉电阻10K。程序是例程里的,就改了一个从器件地址。问题是程序执行之后示波器根本没有SCL时钟线的波形,因为从器件也没有响应,Start位也没有变为0。求各位大牛能不能帮我解惑。

  •  #include <msp430.h>
    
        unsigned char *PRxData;                     // Pointer to RX data
        unsigned char RXByteCtr;
        volatile unsigned char RxBuffer[128];       // Allocate 128 byte of RAM
    
        int main(void)
        {
          WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
          P4SEL|=BIT1+BIT2;                             // Assign I2C pins to USCI_B1
          UCB1CTL1 |= UCSWRST;                      // Enable SW reset
          UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
          UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
          UCB1BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
          UCB1BR1 = 0;
          UCB1I2CSA = 0x49;                         // Slave Address is 048h
          UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
          UCB1IE |= UCRXIE;                         // Enable RX interrupt
    
          while (1)
          {
            PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
            RXByteCtr = 5;                          // Load RX byte counter
            while (UCB1CTL1 & UCTXSTP);             // Ensure stop condition got sent
            UCB1CTL1 |= UCTXSTT;                    // I2C start condition
    
            __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0, enable interrupts
                                                    // Remain in LPM0 until all data
                                                    // is RX'd
            __no_operation();                       // Set breakpoint >>here<< and
          }                                         // read out the RxBuffer buffer
        }
    
        //-------------------------------------------------------------------------------
        // The USCI_B0 data ISR is used to move received data from the I2C slave
        // to the MSP430 memory. It is structured such that it can be used to receive
        // any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
        //-------------------------------------------------------------------------------
        #pragma vector = USCI_B1_VECTOR
        __interrupt void USCI_B1_ISR(void)
        {
          switch(__even_in_range(UCB0IV,12))
          {
          case  0: break;                           // Vector  0: No interrupts
          case  2: break;                           // Vector  2: ALIFG
          case  4: break;                           // Vector  4: NACKIFG
          case  6: break;                           // Vector  6: STTIFG
          case  8: break;                           // Vector  8: STPIFG
          case 10:                                  // Vector 10: RXIFG
            RXByteCtr--;                            // Decrement RX byte counter
            if (RXByteCtr)
            {
              *PRxData++ = UCB1RXBUF;               // Move RX data to address PRxData
              if (RXByteCtr == 1)                   // Only one byte left?
                UCB1CTL1 |= UCTXSTP;                // Generate I2C stop condition
            }
            else
            {
              *PRxData = UCB1RXBUF;                 // Move
            }
          }
        }
    
    
  • 上拉电阻太大了一点,你改成1.5k或者2.2k试试

  • 换了电阻了,但是问题还是没有解决,依旧没有时钟信号

  • 这问题我也遇到过,你是不是上拉的电压太高或者不够?看看器件规格书,有的器件上拉电压不能高于VDDIO以上一定电压。

    还有有可能干扰问题?买个协议分析仪吧,记得买贵点的,否则杂波很多。

  • 1 SCL没有波形的话,那么电平是多少?正常应该是高,如果是低电平,由于SCL一定是Master控制的,很有可能是因为没有ACK等原因导致MCU一直在等待。

    你可以应DriverLib里面的I2C write with timeout函数在长时间没ACK的情况下释放总线,或者在发送start条件后自己价格time out检测呢?另外看一下你I2C 的NACK位有没有?

    2 你这个I2C地址有问题哦

    UCB1I2CSA = 0x49;                         // Slave Address is 048

    UCB1I2CSA定义的是7bit 的I2C 地址哦,简单来说8bit 的0x48 的I2C地址应该是0x24 ,最低一位是读写位。 确认一下你要控制的Slave地址对不对哦?

    3

       __interrupt void USCI_B1_ISR(void)
       {
         switch(__even_in_range(UCB0IV,12))
    你中断进的是B1, 判断条件是B0,要改哦。。。。