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.

[参考译文] MSP432P401R:I2C接口,带激光范围探测器Lidar lite v3

Guru**** 2551300 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/582337/msp432p401r-i2c-interface-with-laser-range-finder-lidar-lite-v3

部件号:MSP432P401R

我在I2C接口中遇到了一些问题,MSP432充当主传感器,激光传感器充当从传感器。 代码在重置处理程序()或以下代码行中挂起:

我想从从属设备接收2字节的数据,以厘米为单位表示距离。

void I2C_masterSendMultiByteStart (UINT32_t模块实例,uint8_t txData)

  //存储电流传输中断启用

  UINT16_t txieStatus = EUSCI_B_CMSIS (moduleInstance)-> Rie.r & UCTXIE;

  //禁用传输中断启用

  BITBAND_PERI(EUSCI_B_CMSIS (moduleInstance -->RIE.r,UCTXIE_OFS)= 0;

  //发送启动条件。

  EUSCI_B_CMSIS (moduleInstance)->rCTLW0.r |= UCTR + UCTXSTT;

  //传送中断标志轮询。

  while (!BISTAND_PERI(EUSSCI_B_CMIS(moduleInstance)->rIFG.r,UCTXIFG_OFS))

    ;

  //发送单字节数据。

  EUSCI_B_CMSIS (moduleInstance)->rTXBUF.r = txData;

  //恢复传输中断启用

  EUSCI_B_CMSIS (moduleInstance)->RIE.r |= txieStatus;

}

有时,多字节的传输是成功的,但我更经常遇到这样的问题:代码卡在上面一行,即使在论坛上转过其他帖子,我也无法找到解决方案。

下面是我设计的代码:

/*************************************************************************

*

*版权所有(C) 2013 - 2016 Texas Instruments Incorporated - http://www.ti.com/

*

*以源代码和二进制形式重新分发和使用,无论是否使用

*允许进行修改,前提是满足以下条件

满足*:

*

**重新分发源代码必须保留上述版权

* 注意,此条件列表和以下免责声明。

*

**以二进制形式重新分发必须复制上述版权

* 注意,此条件列表和中的以下免责声明

* 随提供的文档和/或其他材料

* 分发。

*

**既不是德州仪器(TI)公司的名称,也不是的名称

* 其贡献者可用于支持或推广衍生产品

* 未经事先书面许可。

*

*本软件由版权所有者和贡献者提供

*"按原样"和任何明示或暗示的担保,包括但不包括

*仅限于对适销性和适用性的暗示担保

*不承担特定目的。 在任何情况下,版权都不应享有

*所有者或贡献者对任何直接,间接,附带,

*特殊,典型或后果性损害(包括但不包括

*限于采购替代货物或服务;无法使用,

*数据或利润;或业务中断)

责任理论,无论是合同,严格责任还是侵权行为

*(包括疏忽或其他)因使用而产生的任何原因

本软件的*版本,即使已被告知可能会造成此类损坏。

*

*****************

*

* MSP432 Blink.c模板- WFP 1.0 端口切换

*

*经典编码

*

***************** /

#include "msp.h"

#include "i2c.h"

/* DriverLib定义*/

#include "driverlib.h"

/*标准定义*/

#include <stdint.h>

#include <stdbool.h>

#include <string.h>

/* I2C从属设备的从属设备地址*/

#define slaver_address   0x62

#define NUM_OF_REC_Bytes  2.

/*变量*/

Const int TXData[3]={0x00,0x04,0x8f};

//static uint8_t RXData[NUM_OF_REC_Bytes];

//static uint_least8_t RXData[NUM_OF_REC_Bytes];

//静态易失性UINT32_t xferIndex;

静态挥发性双刀头止动Sent;

静态int RXData[NUM_OF_REC_BYTED];

静态易失性UINT32_t xferIndex;

UINT16_t值;

/* I2C主配置参数*/

const eUSI_I2C_MasterConfig i2cConfig =

    EUSCI_B_I2C_CLOCKSOURCE_SMCLK,      // SMCLK时钟源

    300万,                 // SMCLK = 3MHz //300万

    EUSCI_B_I2C_SET_DATA_RATE_400KBPS   ,//所需的I2C时钟为100kHz //已更改

    0,                    //无字节计数器阈值

    EUSCI_B_I2C_NO_AUTO_STOP         //不自动停止

};

内部主(无效)

  易失性UINT32_t ii;

  UINT8_t总线;

  /*禁用监视 程序*/

  MAP_WDT_A_HoldTimer();

  /*为I2C选择端口1 -将引脚6,7设置为输入主模块功能,

   * (UCB0SIMO/UCB0SDA,UCB0SOMI/UCB.S.)。

   */

  MAP_GPIO设置外围模块功能输入引脚(GPIO_PORT_P1,

      GPIO _PIN6 | GPIO _PIN7,GPIO主要模块功能);

  stopSent =假;

  memset (RXData,0x00,NUM_OF_REC_Bytes);

  /*在100kHz的频率下将I2C主设备初始化到SMCLK,没有自动停止*/

  MAP_I2C_INITMaster (EUSCI_B0_BASE,&i2cConfig);

  /*指定从属地址*/

  MAP_I2C_setSlaveAddress (EUSCI_B0_BASE,SLAVE_ADDRESS);

  /*将主中继器设置为传输模式*/

  MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_MODE);

  /*启用I2C模块以启动操作*/

  MAP_I2C_enableModule (EUSCI_B0_BASE);

  /*启用并清除中断标志*/

  MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE,

      EUSCI_B_I2C_Transmit_INTERRUPT0 + EUSCI_B_I2C_receive _INTERRUPT0);

  MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Transmit_INTERRUPT0);

  MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0);

  MAP_Interrupt_enableSleepOnIsrExit();

  MAP_Interrupt_enableInterrupt (INT_EUSCIB0);

  MAP_Interrupt_enableMaster();

  同时(1)

  {

    /*确保最后一笔交易已全部发出*/

   //

  while (MAP_I2C_MASTOISStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending停止);

    /*发送开始和传输缓冲区的第一个字节。 我们必须发送

     *两个字节,用于清除缓冲区中以前缓冲区中的任何内容

     *发送 */

    MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE,TXData[0]);

    //bus= I2C_isBusy (EUSCI_B0_BASE);

    //themap_I2C_masterSendMultiByteNext(EUSI_B0_BASE ,TXData[0]);

    /*发送停止后启用传输中断*/

    MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0);

    /*当停止条件尚未发出时... */

    while (!stopSent)

    {

      MAP_PCM_GotoLPM0InterruptSafe ();

    }

    stopSent =假;

  }

  返回0;

}

/*******************************************************************************

 * eUSCIB0 ISR。 重复的启动和发送/接收操作会发生

 *在本ISR内。

 ***************** /

void EUSCIB0_IRQHandler (void)

  UINT_FAST16_t状态;

  易失性UINT32_t I;

  P1DIR || BIT0;

  // P2DIR |= BIT2;

  UINT8_t总线,数据;

  状态= MAP_I2C_getEnabledInterruptStatus (EUSCI_B0_BASE);

  MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE,STATUS);

  /*如果我们达到传输中断,则表示我们位于的索引1

   *传输缓冲区。 在我们到达之前反复启动时

   *最后一个字节我们需要将模式更改为接收模式,设置开始

   *条件发送位,然后将最后一个字节加载到TXBUF中。

   */

  IF (状态和EUSCI_B_I2C_Transmit_INTERRUPT0)

  {

    MAP_I2C_masterSendMultiByteNext(EUSI_B0_BASE,TXData[1];

   // bus= I2C_isBusy (EUSCI_B0_BASE);

    __DELAY周期(3000-20);

    MAP_I2C_masterSendMultiByteNext(EUSI_B0_BASE,TXData[2];

    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Transmit_INTERRUPT0);

    MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE);

    __DELAY周期(3000-20);

    MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode);

    xferIndex = 0;

    MAP_I2C_masterReceiveStart (EUSCI_B0_BASE);

    MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Receive_INTERRUPT0); //ME

    MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_receive _INTERRUPT0);

  }

  /*将字节接收到value变量中。 如果我们已收到所有字节,

   *发送停止条件*/

  IF (状态和EUSCI_B_I2C_Receive_INTERRUPT0)

  {

  值= MAP_I2C_masterReceiveMultiByteNext(EUSSCI_B0_base);

    值=值<< 8;

    value |= map_I2C_masterReceiveMultiByteNext(EUSSCI_B0_base);

     MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Receive_INTERRUPT0);

          MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_MODE);

          //xferIndex = 0;

          stopSent =真;

          MAP_Interrupt_DisableSleepOnIsrExit();

  }

}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,
    我知道您已经搜索了论坛,但您能否确认您已经使用此示例代码进行了调查,并且该示例代码对您没有帮助?

    e2e.ti.com/.../211.7452万

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

    您好,Chris:

    我在建议的帖子中查看了您提供的代码i2c_master_rw_重复 性start-master_code_eds.c,但不幸的是,我的目标是在I2C上实现与激光传感器的距离,但我没有成功。 我遇到以下问题:

    代码卡在函数中:

      while (!stopSent)

        {

          MAP_PCM_GotoLPM0InterruptSafe ();

        }

    这反过来表明它卡在以下位置:

    void cpu_wfi (void)

      //

      //等待下一个中断。

      //

      __ASM("  wfi\n");

    }

    请引导我解决这个问题,因为我发现通过I2C将传感器连接到MSP432真的很困难。 谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Asmita,
    您是否仍在处理此问题? 在提供的示例中,主有效负载是否与从机所需的内容(地址,字节数等)匹配? 如果你看I2C线路上的活动,保持时钟线路的从属设备是否低?

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

    Chris Sterzik 说:
    如果您查看I2C线路上的活动,则控制时钟线路的从属设备是否为低电平?[/QUOT]

    我面临着类似的问题,奴隶的SDA处于低位。 如果在I2C传输过程中重置MSP432主控制器,从属控制器可以达到此状态。

    在MSP432启动和I2C初始化时,它将永久阻止I2C_masterSendMultiByteStart()。

    是否有从这种情况中恢复的建议技巧? 我能想到的唯一解决方案是将I2C引脚转换为GPIO和时钟输入9位'1'以使从属设备脱离此错误状态。 我原本希望有硬件解决方案来启动此类重置/恢复,但我在TRM中找不到这方面的任何解决方案。

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

    您好,Mike:

    是的,在GPIO模式下发送9位是可能的解决方案。  您可能还需要在从属设备上创建某种超时,或使用另一个GPIO向设备发送信号以进行重置。  例如,如果从属设备是MSP432,则可以设置 UCBxCTLW0:UCSWRST以重置eUSCI通信外围设备并重新初始化从属设备。

    此致,

    Chris