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.

[参考译文] MSP430G2553:I2C 未发送确认时钟周期

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1437545/msp430g2553-i2c-not-sending-the-acknowledge-clock-cycle

器件型号:MSP430G2553

工具与软件:

您好!

我目前正在尝试编写一个代码来读取和写入 APDS-9900器件、这是一个测量传感器和物体之间距离的器件。 我尝试使用我的当前代码来执行一个简单的读取操作、仅读取芯片的 ID、以便 I2C 正常工作、即地址0x12、我期望返回值0x29。

但当我尝试运行时、它一直停留在上 while (UCB0CTL1和 UCTXSTT); 并通过我的 osciloscoop 锁定、似乎最后一个确认的时钟没有发送。

有什么想法如何解决这个问题或我在做什么错误?

我用来读取字节和字的代码函数下面。

#include <Header/i2c.h>

#include <msp430.h>
#include <stdint.h>

void I2C_Init(void) {
    // Set P1.6 and P1.7 as I2C pins
    P1SEL |= BIT6 + BIT7;
    P1SEL2 |= BIT6 + BIT7;

    // Set up USCI_B0 for I2C master mode
    UCB0CTL1 |= UCSWRST;                      // Enable software reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C master mode, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep reset
    UCB0BR0 = 12;                             // Set bit rate (assuming 1MHz SMCLK, 100kHz I2C)
    UCB0BR1 = 0;
    UCB0CTL1 &= ~UCSWRST;                     // Clear reset to enable I2C
    IFG2 &= ~(UCB0RXIFG + UCB0TXIFG); // Clear flags
    IE2 |= UCB0RXIE + UCB0TXIE;               // Enable RX and TX interrupts
}

unsigned char I2C_Read_Combined(unsigned char regAddr) {

    UCB0I2CSA = 0x39;                         // Set APDS-9900 I2C address
    UCB0CTL1 |= UCTR + UCTXSTT;               // Set as transmitter, generate START condition
    while (UCB0CTL1 & UCTXSTT);               // Wait for START condition to complete
    UCB0TXBUF = regAddr;                      // Send register address
    while (!(IFG2 & UCB0TXIFG));              // Wait for transmission to complete
    UCB0CTL1 &= ~UCTR;                        // Set as receiver
    UCB0CTL1 |= UCTXSTT;                      // Generate repeated START condition
    while (UCB0CTL1 & UCTXSTT);               // Wait for START condition to complete
    UCB0CTL1 |= UCTXSTP;                      // Generate STOP after next byte
    while (!(IFG2 & UCB0RXIFG));              // Wait for data to be received
    return UCB0RXBUF;                         // Return received data
}


unsigned int I2C_Read_Word(unsigned char regAddr) {
    unsigned int data = 0;
    UCB0I2CSA = 0x39;                         // Set APDS-9900 I2C address
    UCB0CTL1 |= UCTR + UCTXSTT;               // Set as transmitter, generate START
    while (UCB0CTL1 & UCTXSTT);               // Wait for START to complete
    UCB0TXBUF = regAddr;                      // Send register address
    while (!(IFG2 & UCB0TXIFG));              // Wait for transmission to complete
    UCB0CTL1 &= ~UCTR;                        // Set as receiver
    UCB0CTL1 |= UCTXSTT;                      // Generate repeated START
    while (UCB0CTL1 & UCTXSTT);               // Wait for START to complete
    data = UCB0RXBUF;                         // Read first byte
    data <<= 8;                               // Shift to high byte
    while (!(IFG2 & UCB0RXIFG));              // Wait for second byte
    data |= UCB0RXBUF;                        // Read second byte
    UCB0CTL1 |= UCTXSTP;                      // Generate STOP
    return data;
}

数据表中如何说明 I2C 协议必须正常工作才能与 APDS-9900通信。

使用 osciloscoop 我的结果。 蓝色是 SDA、黄色是 SCL。

如您所见、最后一个时钟信号未发送。

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

    总线暂停。 可能是因为在写入寄存器地址之前您正在等待 UCTXSTT 清零。 该位在地址被确认后清除。

    请尝试改用 TXIFG。

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

    它是哪个寄存器? 我在 MSP430G2553中找不到该信息、或者您是指寄存器 UCBxTXIFG。  

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

    我假设由于您在多个地方使用过 TXIFG、因此您可以理解 TXIFG 是 UCB0TXIFG 的简称。