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**** 2553420 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/594059/msp430g2553-i2c-slave-not-acknowledging-consistently

器件型号:MSP430G2553

我目前正在连接 msp430g2553和 ds1307。 当 RTC 应答时、读取写入操作执行正确、它在下一次运行时停止应答。 有什么建议吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的代码有问题(您尚未显示)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    int main (空)

    WDTCTL = WDTPW + WDTHOLD; //停止 WDT
    P1SEL |= BIT6 + BIT7; //将 I2C 引脚分配给 USCI_B0
    P1SEL2|= BIT6 + BIT7; //将 I2C 引脚分配给 USCI_B0
    init_i2C();
    pTxData =(unsigned char *) TxData;
    pRxData =(unsigned char *) RxData;
    while (1)

    Transmit ();
    set_pointer();
    receive();



    void init_I2C (void){

    IE2 |= UCB0RXIE; //启用 RX 中断
    IE2 |= UCB0TXIE; //启用 TX 中断
    while (UCB0CTL1 & UCTXSTP); //确保发送了停止条件
    UCB0CTL1 |= UCSWRST; //启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
    UCB0BR0 = 12; // fSCL = SMCLK/12 =~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x68; //从地址为068h
    UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作



    void transmit (void)(空)

    while (UCB0CTL1 & UCTXSTP); //确保发送了停止条件
    UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件
    for (i=0;i<9;i++) //检查 TX 字节计数器
    {UCB0TXBUF =* pTxData++; //加载 TX 缓冲区



    void set_pointer (void)
    {while (UCB0CTL1 & UCTXSTP); //确保发送了停止条件
    UCB0CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件
    UCB0TXBUF = 0x00; //加载 TX 缓冲区



    接收无效(无效)

    UCB0CTL1 &=~UCTR; //清除 UCTR
    while (UCB0CTL1 & UCTXSTP);
    UCB0CTL1 |= UCTXSTT; // I2C 启动条件
    for (i=0;i<7;i++) //检查 TX 字节计数器

    *pRxData++= UCB0RXBUF; //加载 TX 缓冲区

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您正在设置中断使能位、但不使用中断。
    只有当 TXIFG 被置位时、才必须写入 TXBUF。
    只有当 RXIFG 被置位时、才必须从 RXBUF 中读取。
    您永远不会发送停止条件。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Ladisch 先生

    我禁用了中断。
    在 UCB0CTL1 |= UCTR + UCTXSTT 之后、TXIFG 被置位。 只有在这之后、TXBUF 才会填充要发送的数据。
    3.我已经给出了一个停止条件。

    问题仍然存在
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    每次访问时必须检查 TXIFG/RXIFG 位。 您的新代码可能是错误的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Ladisch 先生

    在 UCB0CTL1 |= UCTR + UCTXSTT 之后、UCTXSTT 和 TXIFG 被置位。 在 TXBUF 发送数据后、UCTXSTT 保持为1、而不是0。 从器件不会确认发送更多数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 th133 (4983875),

    我看不到 TxData 和 RxData 的定义、您能发布整个代码吗? 请使用按钮输入代码、以便正确设置格式"使用丰富的格式、</>按钮"

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

    #include

    unsigned char i;

    unsigned char *pTxData;           //指向 TX 数据的指针

    unsigned char *pRxData;           //指向 RX 数据的指针

    const unsigned char TxData[]={0x00、0x01、0x01、0x01、0x01、0x01、0x01、0x01、0x01};      //要发送的数据

    const unsigned char RxData[];

    void init_I2C (void);

    void transmit (void);

    void set_pointer (void);

    接收无效(无效);

    int main (空)

     WDTCTL = WDTPW + WDTHOLD;         //停止 WDT

     P1SEL |= BIT6 + BIT7;           //将 I2C 引脚分配给 USCI_B0

     P1SEL2|= BIT6 + BIT7;           //将 I2C 引脚分配给 USCI_B0

     init_i2C();

     pTxData =(unsigned char *) TxData;

      pRxData =(unsigned char *) RxData;

     while (1){

     Transmit ();

     set_pointer();

     receive();

     }

    void init_I2C (void){

     UCB0CTL1 |= UCSWRST;            //启用 SW 复位

     UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;  // I2C 主器件、同步模式

     UCB0CTL1 = UCSSEL_2 + UCSWRST;       //使用 SMCLK、保持软件复位

     UCB0BR0 = 12;               // fSCL = SMCLK/12 =~100kHz

     UCB0BR1 = 0;

     UCB0I2CSA = 0x68;             //从地址为068h

     UCB0CTL1 &=~UCSWRST;           //清除 SW 复位,恢复操作

    void transmit (void){

      while (UCB0CTL1 & UCTXSTP);       //确保发送了停止条件

      UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件

      for (i=0;i<8;i++)          //检查 TX 字节计数器

       {

       UCB0TXBUF =* pTxData++;         //加载 TX 缓冲区

                 }

         UCB0CTL1 |= UCTXSTP;

    void set_pointer (void)

    {  while (UCB0CTL1 & UCTXSTP);       //确保发送了停止条件

      UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件

      UCB0TXBUF = 0x00;         //加载 TX 缓冲区

      UCB0CTL1 |= UCTXSTP;  }

    void receive (void){

     UCB0CTL1 &=~UCTR;          //清除 UCTR

     while (UCB0CTL1 & UCTXSTP);

     UCB0CTL1 |= UCTXSTT;           // I2C 启动条件

      while (UCB0CTL1 & UCTXSTT);

      for (i=0;i<7;i++)          //检查 TX 字节计数器

         {

      *pRxData++= UCB0RXBUF;    //加载 TX 缓冲器

          }

      UCB0CTL1 |= UCTXSTP;           // I2C 停止条件

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    SCL 和 SDA 线路均通过10k 电阻器上拉至 MSP 的 VCC。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在这里看到了几个问题:

    1.您的接收数据变量(const unsigned char RxData[];)没有大小。 这是一个空数组、它将有效地归结为指针。 如果要在其中存储多个字节、则需要为其分配大小。
    2.传输变量定义正确,但我认为这不是您要写入的数据。 您正在将0x1有效地写入每个寄存器。 请查看数据表中的图4。 您需要的是写入地址0、然后再写入一个字节以清除 CH 字段、并启用振荡器(如果需要、设置秒数)。
    4.您的发送和接收环路不正确。 首先、您无需等待器件完成传输或接收、只需对寄存器进行读写操作。 在发送过程中、必须等待 UCB0TXIFG 置位、然后再将数据写入该寄存器。 在接收端、必须等待 UCB0RXIFG 置位、然后才能从该寄存器读取数据。

    从那开始、看看情况如何。