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.

[参考译文] MSP430F5659:未从DS1307 thorugh I2C协议接收正确的数据

Guru**** 2587355 points
Other Parts Discussed in Thread: MSP430F5659

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/615032/msp430f5659-not-receiving-correct-data-from-ds1307-thorugh-i2c-protocol

部件号:MSP430F5659

您好,

我正在使用msp430f5659微控制器。 我正在尝试通过I2C协议连接DS1307 RTC IC。 我使用了TI为msp430f6和F6系列提供的示例代码的i2c发送和接收函数。 我正在传输(0xD0,0x00,0x01设置秒数,0xD0,0x00,0xD1读取第二个数据)。 数据传输成功,但我正在接收0xFF,这是垃圾数据。 如果发送任何其他命令以接收分钟或小时,则始终发送0xFF。 我无法检测到代码中的问题。我的代码在这里。

void i2c_transmit (无符号char TxData)

       无符号char i=0;
       PTxData =&TxData;      
       TXByteCtr = TxData的大小;             //加载TX字节计数器
       I2C_writeinit();//       它启用TX中断标志
       对于(i=0;i<1;i++)
       {
       UCB1CTL1 || UCTR | UCTXSTT;            // I2C TX,启动条件
       __bis_sr_register( GIE);    //输入LPM0,启用中断
           while (UCB1CTL1和UCTXSTP);            //确保已发送停止条件
     }
   }

void i2c_receive()

      int i;
      I2C_readinit();//    它启用rxinterrupt标志
      PRxData = RxBuffer;                  // RX缓冲区开始
      对于(i=0;i<1;i++)
       {
         while (UCB1CTL1和UCTXSTP);            //确保已发送停止条件
         UCB1CTL1 || UCTXSTT;                   // I2C启动条件

         __bis_sr_register(LPM0_bits | GIE);    //输入LPM0,启用中断
                                                 //保留在LPM0中,直到所有数据
                                                 //为RX
       }
     UART_PUTSTRING (RxBuffer,1);       //在UART上接收0xFF
}
// USI_B1数据ISR
#if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
#pragma vector = USI_B1_Vector
__interrupt void USI_B1_ISR(void)
#Elif已定义(__GMNU__)
void __attribute__((interrupt (USI_B1_vector))) USI_B1_ISR (void)
#否则
错误编译器不受支持!
#endif

 SWITCH(__EIV_IN_RANGE(UCB1IV,12))
 {
 案例 0:中断;                          //矢量 0:无中断
 案例 2:中断;                          //矢量 2:ALIFG
 案例 4:中断;                          //矢量 4:NACKIFG
 案例 6:中断;                          //矢量 6:STTIFG
 案例 8:中断;                          //矢量 8:STPIFG
 案例10:
          RXByteCtr --;                           // Decrement RX字节计数器
          IF (RXByteCtr)
          {
            *PRxData++= UCB1RXBUF;              //将RX数据移动到PRxData地址
            如果(RXByteCtr == 1)                  //只剩下一个字节?
              UCB1CTL1 || UCTXSTP;               //生成I2C停止条件
          }
          否则
          {
            *PRxData = UCB1RXBUF;                //将最终RX数据移至PRxData
                      __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出活动CPU
          }

          中断;
 案例12:
         IF (TXByteCtr)                         //检查TX字节计数器
          {
           UCB1TXBUF =* PTxData;                  //加载TX缓冲区
                  TXByteCtr -;                         // Decrement TX字节计数器
          }
         否则
         {
                  UCB1CTL1 || UCTXSTP;                 // I2C停止条件
                  UCB1IFG &=~UCTXIFG;                 //清除USI_B0 TX int标志
                 __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
          }
           中断;
                              默认值:中断;
 }
}

在主要功能中,我正在传输 :

   I2C_Transmit (0xD0);             // RTC写模式地址
   I2C_Transmit (0x00);             // RTC第二个位置地址
   I2C_Transmit (0x01);          //要设置的RTC数据

   I2C_Transmit (0xD0);             // RTC写模式地址
     I2C_Transmit (0x00);             // RTC第二个位置地址
     I2C_Transmit (0xD1);          // RTC读取模式地址
     I2C_receive();

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

    我注意到的第一件事是,UCTR位在您的接收功能内未被清除。 您也不能仅在不重复起始位的情况下传输从属地址+读取位。 事实上,每个传输字节函数似乎都开始和停止通信,因此我怀疑您的DS1307寄存器是否设置正确。 启动条件将发送从属地址,因此您无需手动发送。 您应该使用示波器或逻辑分析器并提供屏幕截图,以验证I2C通信是否正确遵循协议。 另请查看TI提供的代码示例。

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

    您好,

    我在示波器上没有收到任何信息。 我已清除writeinit函数中的UCTR位并在接收函数中调用它。  我尝试发送数据,但在示波器上没有得到任何信息,这意味着我的传输功能不工作。 我无法找到问题所在?

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

    问题可能与您的端口和I2C初始化有关,尚未提供代码。 但是,如果是这种情况,我不希望您通过传输功能。  您是否具有合适的上拉电阻器?  应该在P8SEL寄存器中设置Bit5和BIT6,以便UCB1正常工作。 在I2C寄存器设置完毕后,UCB1应脱离其复位状态(通过清除UCSWRST位)。

    此致,
    Ryan

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

    您好,

    我在SCL和SDA线路上都有10k上拉电阻器。 我的i2c配置代码如下所示:

    void i2c_configuration()

    P8SEL || SCL+SDA;  //分别将引脚8.5 和8.6 定义为SDA和SCL引脚

    P8DIR || SCL+SDA;  //为SDZ和SCL引脚分配输出方向

    UCB1CTL1 |=UCSWRST;

      UCB1CTL0 = UCMST | UCMODE_3 | UCSYNC;  // I2C主控,I2C模式, 同步模式

      UCB1CTL1 = UCSSEL_2 | UCSSWRST;      //使用SMCLK,保持软件重置

      UCB1BR0 = 40;               // fSCL = SMCLK/40 = 4MHz/40=~100kHz

      UCB1BR1 = 0;

      UCB1I2CSA = 0x68;             //从属地址为048h

      UCB1CTL1 &=~ UCSWRST;

      UCB1IE |= UCTXIE;//+ UCRXIE ;//+ UCSTPIE + UCNACKIE;             //启用TX中断

     // __enable_interrupt ();//启用全局中断

    }

    void i2c_writeinit()

        UCB1CTL1 || UCTR;                        // UCTR = 1 =>传输模式(R/W位= 0)
        UCB1IFG &=~ UCTXIFG;
        UCB1IE &=~ UCRXIE;
        UCB1IE |= UCTXIE;
    }

    void i2c_readinit()

        UCB1CTL1 &=~ UCTR;                       // UCTR = 0 =>接收模式(R/W位= 1)
        UCB1IFG &=~ UCRXIFG;
        UCB1IE &=~ UCTXIE;
        UCB1IE |= UCRXIE;
    }

    我清除了i2c_readinit函数中的UCTR位,我在接收函数中调用了它。

    是否需要定义ack和nack函数来执行代码?

    第二种方法:

    我已经尝试了将这些引脚用作GPIO引脚的代码,并通过定义启动,停止,攻击,拦截,传输和接收功能来执行工程师车库网站上提供的代码。 我可以使用此方法传输,但始终接收0x00。 我无法找到问题所在。 下面给出了我尝试的代码,但没有使用中断功能。

    e2e.ti.com/.../New-Text-Document.txt

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

    初始化看起来正常,感谢您的分享。 您是否也尝试使用UCB0? 您是否考虑过从TI的运营示例开始并从该示例开始构建? 代码正常工作不需要ACK/NACK控制。 我无法评估您提供的代码文件,因为它的格式难以辨认。

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

    您好,

    当我在 TI提供的main函数中执行代码时,我注意到它第一次进入ISR例程,之后它进入__bis_sr_register(LPM0_bits | GIE);    //输入LPM0,启用中断并卡在这里。 我已使用断点执行代码以查看流的流。为什么无法执行__bis_sr_register(LPM0_bits | GIE)下面的行;


    unsigned char *PTxData;                    //指向TX数据的指针
    未签名的char TXByteCtr;

    const unsigned char TxData[]=             //要传输的数据表

     0x11,
     0x22,
     0x33,
     0x44,
     0x55
    };


    INT MAIN ()

        无符号int I;

        WDTCTL = WDTPW | WDTHOLD;                //停止WDT

          P3DIR=0xFF;
          P3OUT=0x00;

          P5DIR=0xFF;
          P5OUT=0xFF;

          __DELAY周期(400);//为10秒

          Clock();

        P9SEL || BIT5 + BIT6;                           //将WFP 2.0 分配给UCB0SDA,并且...
        P9DIR |= BIT5 + BIT6;                           // WFP 2.1 到UCB.S.

        UCB1CTL1 || UCSWRST;                     //启用软件重置
        UCB1CTL0 = UCMST | UCMODE_3 | UCSYNC;    // I2C主控,同步模式
        UCB1CTL1 = UCSSEL_2 | UCSWRST;           //使用SMCLK,保持SW重置
        UCB1BR0 = 40;                            // fSCL = SMCLK/40 = 4MHz/40=~100kHz
        UCB1BR1 = 0;
        UCB1I2CSA = 0x68;                        //从属地址为068h
        UCB1CTL1 &=~UCSWRST;                    //清除软件重置,恢复操作
        UCB1IE || UCTXIE;                        //启用TX中断

        同时(1)
        {
          for (i=0;i<10;i++);                     //事务之间需要延迟
          PTxData =(unsigned char *) TxData;     // TX数组起始地址
                                                  //在此处放置断点以查看每个断点
                                                  //传输操作。
          TXByteCtr = TxData的大小;             //加载TX字节计数器

          UCB1CTL1 || UCTR | UCTXSTT;            // I2C TX,启动条件
          __bis_sr_register(LPM0_bits | GIE);    //输入LPM0,启用中断
         __no_operation();                      //保留在LPM0中,直到所有数据
                                                  //已发送
          while (UCB1CTL1和UCTXSTP);            //确保已发送停止条件
        }


    }

    //------------------
    // USCIAB0TX_ISR的结构可用于传输任何
    //预加载具有字节计数的TXByteCtr的字节数。 另外,TXData
    //指向要传输的下一个字节。
    //------------------
    #if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
    #pragma vector = USI_B1_Vector
    __interrupt void USI_B1_ISR(void)
    #Elif已定义(__GMNU__)
    void __attribute__((interrupt (USI_B1_vector))) USI_B1_ISR (void)
    #否则
    错误编译器不受支持!
    #endif

     SWITCH(__EIV_IN_RANGE(UCB1IV,12))
     {
     案例 0:中断;                          //矢量 0:无中断
     案例 2:中断;                          //矢量 2:ALIFG
     案例 4:中断;                          //矢量 4:NACKIFG
     案例 6:中断;                          //矢量 6:STTIFG
     案例 8:中断;                          //矢量 8:STPIFG
     案例10:中断;                          //矢量10:RXIFG
     案例12:                                 //矢量12:TXIFG
       IF (TXByteCtr)                         //检查TX字节计数器
       {
         UCB1TXBUF =* PTxData+;              //加载TX缓冲区
         TXByteCtr -;                         // Decrement TX字节计数器
       }
       否则
       {
         UCB1CTL1 || UCTXSTP;                 // I2C停止条件
         UCB1IFG &=~UCTXIFG;                 //清除USI_B0 TX int标志
         __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
       }
     默认值:中断;
     }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,
    代码中有错误,因为端口9是USB2,所以我将其更改为B2,并在上面插入了一些延迟,需要时,现在我的传输功能正在工作。 我可以在示波器上看到所有脉冲,但我的接收功能不工作。 我观察到RXBUF寄存器中的寄存器值为0xFF。 我已将0xD0,0x00,0x10传输到写入秒,并将0xD0,0x00和0xD1传输到从RTC IC读取秒,但RXBUF中的值仍为0xFF。 我正在使用TI示例代码接收和清除UCTR位,然后再接收。 请帮助我找到解决方案。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    确保您遵循I2C协议和从设备的预期定时/顺序。 请提供您的发送和接收序列的更新代码以及I2C通信的标记示波器屏幕截图。

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

    您好,

    我正在附加我的代码文件和在示波器上查看的波形图像。Txadata用于通过提供命令(0xD0,0x00,0x01,0x04,0x05)来设置RTC IC 1307的秒,分钟和小时数。 Rxdata用于设置位置,并通过给出命令 (0xD0,0x00,0xD1)处于读取模式。

    在此代码中,我收到的秒数不正确,它总是发送0xFF。 请帮助。

    e2e.ti.com/.../0741.code.txt

    当在while循环中仅传输txdata时,此波形为txdata。

    此波形是在While循环中传输时的rxdata波形。

    此波形表示在 代码的主要功能中传输和接收的rxdata加输出。

    此波形是上述给定波形(像结构波形一样的桶)内的加号。它表示rxdata。

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

    如果已使用启动条件(UCTXSTT)自动完成此操作,代码将继续尝试手动发送从属地址。 因此,您必须实际传输的只是数据(地址和内容)。 I2C协议中的附加字节使设备在请求的地址读取位置方面感到困惑,因此返回了无效数据。 您的发送流程应遵循以下方式:

    1.使用UCB2CTL1 || UCTR | UCTXSTT的启动条件和从属地址(写入位集);
    2.4个数据字节(0x00,0x01,0x04,0x05)
    3.停止条件(UCB2CTL1 |= UCTXSTP;)
    4.另一个启动条件和从属地址写入
    5.地址字节(0x00)
    6.读取从属地址的重复启动位(UCB2CTL1 &=~UCTR;& UCB2CTL1 |= UCTXSTT;)

    然后,在发送另一个停止条件以完成事务之前,应使用USI_B2 ISR读取所需的字节数。 请查看I2C协议以验证此分析: www.robot-electronics.co.uk/i2c-tutorial

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

    您好,

    您在第5步和第6步中提到,在传输单个重复strt条件后,应该生成一个停止条件,但我的ISR在传输单个字节后将生成一个停止条件,然后在接收例程中将生成一个启动条件,因此如何停止它以生成 停止条件?  


    1.使用UCB2CTL1 || UCTR | UCTXSTT的启动条件和从属地址(写入位集);
    2.4个数据字节(0x00,0x01,0x04,0x05)
    3.停止条件(UCB2CTL1 |= UCTXSTP;)
    4.另一个启动条件和从属地址写入
    5.*** 地址字节(0x00)和停止条件    //如何更改它
    6.读取从属地址的重复启动位(UCB2CTL1 &=~UCTR;& UCB2CTL1 |= UCTXSTT;)

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

    如果不想发送停止条件,则不要设置UCB2CTL1的UCTXSTP。 但是,后面跟有起始位和从地址读取字节的停止位也是完全可以接受的。

    此致,
    Ryan