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.

[参考译文] MSP430F2471:具有 MSP430F24X1的内部 I2C

Guru**** 2392905 points
Other Parts Discussed in Thread: TMP100, MSP430F249, MSP430F2471

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/652795/msp430f2471-internal-i2c-with-msp430f24x1

器件型号:MSP430F2471
主题中讨论的其他器件:TMP100MSP430F249

大家好、我正在使用湿度传感器 HYT271。 它可以使用 I2C (我使用了 MSP430的 I/O 线路)和外部上拉电阻器进行位拆裂。 但是、为了高效工作、我希望使用内部 i2c。 IDE 是 Code Composer Studio。 为 i2c 提供了代码示例、但一开始我很困惑。

是否有人可以帮助我准确地使用内部 i2c? 并为任何传感器提供示例代码。

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

    您好!

    I2C 示例只能如此具体、因为每个 I2C 实现都不同。 您最好的资源是使用 用户指南 以及此串行通信 应用报告 来了解特定传感器如何与 MSP430 I2C 外设集成。

    此致、

    Matt Calvo

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

    Matthew、感谢您的快速回复。 我已经介绍了 MSP430的数据表和应用示例。

    这是我用于 HYT 湿度传感器的代码。

    (二

    MSP430x24x 演示- USCI_B0 I2C 主设备至 TMP100、如果温度> 28C、则设置 P1.0
    //
    //说明:9位模式下连接 TMP100温度传感器的 I2C 接口。
    // Timer_A CCR0中断用于唤醒和读取的两个字节
    // TMP100温度寄存器每62ms 执行一次。 温度越高
    //高于28C、P1.0被置位、否则复位。 CPU 在 LPM0中运行。 I2C 速度
    //为~100kHz。
    // ACLK = n/a、MCLK = SMCLK = TACLK = BRCLK =默认 DCO =~1.045Mhz
    //
    ///|\/|\/|\
    //| TMP100 10k 10k MSP430F249
    //|--- |||----
    //+-|Vcc SDA|<-|-+->|P3.1/UCB0SDA XIN|-
    //||||| |
    //+-|A1、A0 ||| XOUT|-
    //|||||
    //+-|VSS SCL|<----- |P3.2/UCB.S. P1.0|--> LED
    //\|/---- ||

    (三

     我已经为我的传感器(从器件地址为0x28)和 MSP430F2471进行了更改

     MSP430F2471的引脚:

    1. 在我的配置中选择的端口5

      45 -SCL (端口5.1)  

      46 -SDA (端口5.2)  

      P5SEL |= 0x06;    

    2.将 USCI 模块寄存器从0更改为1

       将 UCB1CTL0更改为  UCB1CTL1  

    3. 将  UCB0CTL0更改为  UCB1CTL0

      UCB0BR0更改为   UCB1BR0

    将   UCB0BR1更改为   UCB1BR1

    6. UCB0I2CSA 至 UCB1I2CSA

    7.将从机地址设置为0x28

    8. UCB0RXIE 更改为 UCB1RXIE  //使能接收器中断  

    9. UCB0RXBUF 至  UCB1RXBUF

    10.USCIAB0TX_ISR 更改为 USCIAB1TX_ISR

     

     

     


    #include

    unsigned int RxByteCtr;
    unsigned int RxWord;

    int main (空)

    WDTCTL = WDTPW + WDTHOLD;//停止 WDT
    P1OUT = 0;
    P1DIR |= 0x01;               // P1.0输出
    P5SEL |= 0x06;               //将 I2C 引脚分配给 USCI_B0
    UCB1CTL1 |= UCSWRST;//启用 SW 复位
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
    UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
    UCB1BR0 = 12;// fSCL = SMCLK/12 =~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = 0x28;//设置从器件地址
    UCB1CTL1 &=~UCSWRST;//清除 SW 复位,恢复运行
    IE2 |= UCB1RXIE;//启用 RX 中断
    TACTL = tassel_2 + MC_2;// SMCLK、contmode

    while (1)

    RxByteCtr = 2;//加载 RX 字节计数器
    UCB1CTL1 |= UCTXSTT;// I2C 启动条件
    _bis_SR_register (CPUOFF + GIE);//输入 LPM0、启用中断
    //保持在 LPM0中直到所有数据
    //是 RX

    如果(RxWord < 0x1d00)//>28C?
    P1OUT &=~0x01;//否、P1.0 = 0
    其他
    P1OUT |= 0x01;//是、P1.0 = 1

    _disable_interrupt ();
    TACCTL0 |= CCIE;//启用 TACCR0中断
    _bis_SR_register (CPUOFF + GIE);//输入 LPM0、启用中断
    //保持在 LPM0中直到 TACCR0
    //中断发生
    TACCTL0 &=~CCIE;// TACCR0中断被禁用

    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector = TIMERA0_vector
    _interrupt void TA0_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((interrupt (TIMERA0_vector)) TA0_ISR (void)
    其他
    错误编译器不受支持!
    #endif

    _BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0

    // USCIAB0TX_ISR 的结构使其可用于接收任何
    //通过预加载带字节计数的 RxByteCtr 来获得2+字节数。
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector = USCIAB0TX_vector
    _interrupt void USCIAB1TX_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((interrupt (USCIAB1TX_vector)) USCIAB1TX_ISR (void)
    其他
    错误编译器不受支持!
    #endif

    RxByteCtr --;//递减 RX 字节计数器

    IF (RxByteCtr)

    RxWord =(无符号 int) UCB0RXBUF << 8;//获取接收到的字节
    如果(RxByteCtr = 1)//只剩下一个字节?
    UCB1CTL1 |= UCTXSTP;//生成 I2C 停止条件

    其他

    RxWord |= UCB1RXBUF;//获取最终接收到的字节、
    //组合 MSB 和 LSB
    _BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0

    使用 CRO 进行调试时注意到的事项:

    SCL 没有产生任何时钟。


    如果需要对代码进行任何修改以生成时钟、启动和停止条件、请告诉我。

    正在查找您的回复

     

     

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >IE2 |= UCB1RXIE;//启用 RX 中断
    UCB1RXIE 在 UC1IE 中、而不是 IE2中。 (参考 SLAU144J 第17.4.13节)这只是一个半理论、因为我不知道(在这个程序中)会导致 UCB0RXIFG 触发什么。 无论如何、您可能需要修复它。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我必须读取4字节的湿度数据。 为此、我需要生成未发生的时钟、启动和停止。
    我的代码中是否存在生成这些条件的错误。 请告诉我所需的寄存器配置、
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    除了 IE 之外、我没有看到任何明显的错误。

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

    由于外部3.3K 上拉电阻、SDA 和 SCL 在上电时处于高电平。 那么、IE 有什么问题。

    您能为其建议正确的配置吗?

    我首先要做 的是生成时钟、启动条件并等待传感器确认。

    然后、我将考虑读取传感器数据。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >IE2 |= UCB1RXIE;//启用 RX 中断
    应该是
    > UC1IE |= UCB1RXIE;//启用 RX 中断

    也是如此
    >#pragma vector = USCIAB0TX_vector
    应该是
    >#pragma vector = USCIAB1TX_vector

    > RxWord =(无符号整型) UCB0RXBUF << 8;//获取接收到的字节
    应该是
    > RxWord =(无符号整型) UCB1RXBUF << 8;//获取接收到的字节

    所有这些最终都将导致麻烦,但任何一个都不应阻止 SCL/SDA 上的活动--至少你应该得到地址字节。

    调试器说什么? 此外、这是什么类型的电路板?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 Bruce 先生的建议。
    我会尝试一下、然后返回给您。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我终于通过浏览数据表和应用报告从传感器获得了 SCL 和 SDA 输出。 但我仍然有一些问题。

    我为生成时钟和数据所做的工作:

    (三

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

     UCB1BR1 = 0;

     UCB1I2CSA = 0x51;                  // 传感器数据表中给出的默认从地址(0x28)

     ***** 从机启动、停止和写入地址的连续循环

     while (1)

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

    UCB1CTL1 |= UCTXSTP;            //生成 I2C 停止条件

    除上述内容外、我还为 USCI 模块设置了必要的配置。

    根据 I2C 协议和数据表、我的问题给出了开始序列、7位从器件地址和写入位从器件写入地址0x28的计算字节为0x51。

    因此、我已设置 UCB1I2CSA = 0x51。

    因此、在发送开始信号后、从器件写入地址必须通过使 SDA 线路为低电平来确认未发生的情况、从而在第9个时钟脉冲中从传感器发出确认信号。

    产生的时钟脉冲就像尖峰。 它们是否正确? 时钟脉冲是否需要任何东西。

    有人可以帮助我分析这种情况吗? 我看到了 CRO 的这种响应。

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

    在您的代码中注意到一件事:

    UCB1I2CSA = 0x51; //传感器数据表中给出的默认从地址(0x28)

    从机地址看起来是0x28、而不是0x51。 您可能选择了0x51、因为您认为需要向左移动7位地址以腾出可供使用的 R/W 位、但情况并非如此。 您应该改为将从器件地址写入此寄存器、即0x28。

    至于 SCL 和 SDA 线路的缓慢上升时间、这可能是由多种因素造成的。 这可能是由线路上的电容过高或上拉电阻过大造成的。 这将有效地增加数据和时钟线路上的 RC 时间常数、并导致上升时间更慢。 这种情况的一种可能解决方案是降低线路上的电阻器值、从而实现更强的上拉电阻器。

    如果这些可能的解决方案仍然无法解决您遇到的问题、则可能是时候发送您的源代码、以便我们可以看到问题是什么。

    此致、

    Matt Calvo
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Swaroop 正在打造一个广阔的网络: e2e.ti.com/.../653403

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

    Swaroop、

    我将仅为占位符打开此主题、但将在另一个 e2e 帖子(https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/653403)中继续关注您的同一问题。

    此致、

    Matt Calvo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于上升时间较慢、您的时钟脉冲就像尖峰一样。 上升时间由上拉电阻器决定。 这是因为您的上拉电阻器没有足够快地将总线上拉至 VDD (器件会在线路上出现延迟、看起来不错)。 因此您可以减小电阻。 或者、您的总线上是否有大量电容? 此外、您还可以降低内部时钟的频率。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好!

    从上述解决方案中、我尝试通过使用 以下代码将 I2C1SA=0X28设置为某个值。 让我们来看一下。

    在注释这两行时、以下代码正常工作。

     更改1.

     //_bis_SR_register (CPUOFF + GIE);  

     更改2.  

    // __BIC_SR_REGISTER_ON_EXIT (CPUOFF);   //退出 LPM0   

    当我取消注释 2行以上时、我不知道为什么没有 SCL 和 SDA 的迹线。

    我使用这行代码来启用中断。

    更改3.

    _bis_SR_register (GIE);

    更改4:

    RXByteCtr = 2

    下面是示波器上的以下代码的屏幕截图。

    // //

    #include "msp430x24x.h"

    #include "stdio.h"

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

    unsigned char RXByteCtr;

    volatile unsigned char RxBuffer[128];   //分配128字节的 RAM

    int main (空)

     WDTCTL = WDTPW + WDTHOLD;         //停止 WDT

     BCSCTL1 &=~XT2OFF;   //激活 XT2高频率 xtal

     BCSCTL2 =0x88;  

     P5SEL |= 0x06;               //将 I2C 引脚分配给 USCI_B0

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

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

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

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

     UCB1BR1 = 0;

     UCB1I2CSA = 0x28;             //从机地址为0x28

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

     UC1IE |= UCB1RXIE;              //启用 RX 中断

     _bis_SR_register (GIE);

     while (1)

     {

      PRxData =(unsigned char *) RxBuffer;  // RX 缓冲区开始

      RXByteCtr = 2;              //加载 RX 字节计数器

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

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

     //_bis_SR_register (CPUOFF + GIE);    //输入 LPM0、带中断

                          //保持在 LPM0中直到所有数据

                          //是 RX

      __no_operation();            //在此处设置断点<<和

     }                     //读取 RxBuffer 缓冲区

    ///----------------------------------

    // USCI_B0数据 ISR 用于移动从 I2C 从设备接收到的数据

    //到 MSP430内存。 它的结构使其可用于接收

    //通过预加载 RXByteCtr 并进行字节计数,可获得任意2+个字节。

    ///----------------------------------

    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)

    #pragma vector = USCIAB1TX_vector

    _interrupt void USCIAB1TX_ISR (void)

    #Elif defined (_GNU_)

    void __attribute__((interrupt (USCIAB1TX_vector)) USCIAB1TX_ISR (void)

    其他

    错误编译器不受支持!

    #endif

     RXByteCtr---;                //递减 RX 字节计数器

     IF (RXByteCtr)

     {

      * PRxData++= UCB1RXBUF;         //将 RX 数据移动到地址 PRxData

      IF (RXByteCtr = 1)           //只剩下一个字节?

       UCB1CTL1 |= UCTXSTP;          //生成 I2C 停止条件

     }

     其他

     {

      * PRxData = UCB1RXBUF;          //将最终 RX 数据移动到 PRxData

     // __BIC_SR_REGISTER_ON_EXIT (CPUOFF);   //退出 LPM0   

     }

    我的问题:

    1.要加载到  RXByteCtr 中的值是什么、如何选择该值、我的值2是正确的?

    2.对于上述代码、我是否从传感器获取了2字节湿度数据? 如果不是如何使用 UCTR 位读取、建议使用 UCTR 读取代码样本

    3.如何在  调试模式下查看 UCB1RXBUF 数据当我设置断点时、我无法在寄存器中看到任何值。 我在上面的代码中没有提到任何 UART 代码。

      但我已经 使用 UART 将 UCB1RXBUF 发送到超级终端、观察到的十六进制值大约为00 8.

    帮我解决这个问题。

    此致、

    Swaroop。

     

     

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

    Swaroop、

    如上所述,请在您最新的 e2e 线程( https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/653403 )上发布并允许我们支持此问题 ,因为它的进展比此线程更进一步。 Ryan 和我都将能够为您提供帮助。 如果通信集中在单个线程上、则最容易跟踪并遵循解决方案、因此请将您之前的帖子复制到新线程、以便我们可以继续支持您的问题。

    此致、

    Matt Calvo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt 回答正确、您需要停止在讨论之间进行跳跃。

    1) 1) 2是用于检索湿度的正确 RXByteCtr 值(仅限-无温度)。
    2) 2)由于尚未设置 UCTR = 0、因此您正在执行读取(数据提取)。 要执行写操作、请在发出 UCTXSTT 之前/期间设置 UCTR=1。 您需要将一些传输代码放入 ISR 中。
    3) 3)我希望您读取的第一个字节设置为0x40位("过期")、因为您尚未执行测量请求。 (我可以说的是、MR 只是一个没有数据的写操作。) AHHYTM_E 不会说"过时"读数中的其他位是什么样子的。 当您对 I2C 进行位拆裂时、您得到了什么数据?

    该跟踪看起来像一个片段:(1)它的起始和结束为低电平(2)它有19个时钟、这些时钟太少或太多。 如果是 I squared、我可以看到地址字节0x51+ack、然后是0x5_、它具有"过时"位、但被截断。

    您的调试器说什么? 尝试在 main 中的第二条语句上设置断点(调试器可能会使第一条语句混乱)、并查看是否意外地在那里打开。

    另外、在发出另一个 UCTXSTT 之前、您实际上应该等待事务完成。 如果 CPUOFF 不能正常工作(我不知道这是什么)、请尝试仅旋转、直到 RXByteCtr = 0、此时应设置 UCTXSTP。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Bruce 和 Matt:
    感谢您至今提供的支持。 我已经完成了提到的所有事情。 从先前的讨论中可以看到、
    我已设置 I2C1SA=0X28、但我是否需要将写入和读取地址发送到湿度传感器、而不是正常地址。

    请澄清。 正在等待您的回复。

    平路机、
    Swaroop。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    >在对 I2C 进行位拆裂时,您得到了什么数据?
    >您的调试器说什么?

    我没有您的设备、您的观察结果与我在 F2 I2C 上的体验(本地和位拆裂)非常不一致。 没有线索、我就猜。

    我越来越怀疑某些电气问题:(a) SCL 布线与 SDA 布线相比"差"(b)您的示波器碎片建议随机(甚至依赖于数据) MCU 复位。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Swaroop、

    您是否有机会考虑回复 Bruce? 我们希望能帮助您找到解决您遇到的这个 I2C 问题的方法。

    此致、

    Matt Calvo

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

    我们从你们那里听到过,已经有一段时间了。 是否存在任何未决问题? 如果没有、我将关闭该线程并将其记录以进行跟踪。 感谢您的支持!

    此致、

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

    由于对该线程的支持似乎已经完成、我将继续关闭该线程。 如果您遇到其他问题、请随时发布另一个 E2E 帖子以解决您的问题。

    此致、

    Matt Calvo