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.

[参考译文] CC2650:无法使用 I2C、I2C_transfer 永远不会返回

Guru**** 2579325 points
Other Parts Discussed in Thread: CC2650

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/591475/cc2650-unable-to-use-i2c-i2c_transfer-does-never-return

器件型号:CC2650

大家好、我一直在尝试使用 Pololu AltIMU-10 v5 (陀螺仪、加速计、指南针和高度计连在一起、所有这些都可以访问 vía I2C)。

我已成功将 AltIMU 与其他器件配合使用、但使用 CC2650-LAUNCHPADXL 时遇到问题、我已将 I2C 代码添加到 simpleBLEPeripheral 应用程序、但调用 I2C_transfer 后从未返回。 我已经尝试调试代码、它被卡在一个信标中(下面的第82行):

bool I2CCC26XX_transfer (I2C_Handle handle、
I2C_Transaction *事务)
{
布尔 RET = false;
通用 密钥;
I2CCC26XX_Object *对象;
I2CCC26XX_HWAttrsV1 const *hwAttrs;
内部 状态;

/*获取对象和 hwAttrs 的指针*/
对象=句柄->对象;
hwAttrs = handle->hwAttrs;

/*检查是否需要写入或读取任何内容*/
如果(!事务->writeCount)&&(!事务->ReadCount)){
/*没有要写入或读取的内容*/
返回(RET);
}

if (object->transferMode = I2C_MODE_CALLACK){
/*检查传输是否正在进行中*/
KEY = Hwi_disable();
if (object->headPtr){
/*正在传输*/

/*
*更新由 tailPtr 指向的消息以指向下一个
队列中的*消息
*
object->tailPtr ->nextPtr =事务;

/*更新 tailPtr 以指向最后一条消息*/
object->tailPtr =事务;

/*仍在使用 I2C */
Hwi_restore (key);
返回(true);
}
否则{
/*存储指示 I2C 正在使用的 HeadPtr */
object->headPtr =事务;
object->tailPtr =事务;
}
Hwi_restore (key);
}

/*设置待机禁止约束。 *
power_setConstraint (PowerCC26XX_SB_disallow);

/*获取此特定 I2C 句柄的锁*/
Semaphore_pend (Semaphore_handle (&(object->mutex)))、BIOS_wait_forever);

/*
* I2CCC26XX_primeTransfer 是一个更长的过程
*需要对 I2C 中断进行保护
*

hwi_disableInterrupt (hwAttrs->intNum);
状态= I2CCC26XX_primeTransfer (handle、transaction);
hwi_enableInterrupt (hwAttrs->intNum);

if (object->transferMode =I2C_mode_blocking){
if (status =I2C_STATUS_ERROR){
Log_Print1 (Diags_User1、
"I2C:(%p)总线忙、传输未开始"、
hwAttrs->baseAddr);
object->mode = I2CCC26XX_BUSBUSY_MODE;
RET = false;

/*释放待机禁用约束。 *
power_releaseConstraint (PowerCC26XX_SB_disallow);
}
否则{
Log_Print1 (Diags_User1、
"I2C:(%p)在传输完成信标上挂起"、
hwAttrs->baseAddr);
/*
*在此处等待传输完成。
*可以从这里阻止、因为 I2C 的 Hwi 将解除阻止
*出错时
*
Semaphore_pend (Semaphore_handle (&(object->transferComplete))、BIOS_wait_forever);

/*这里无需释放待机禁止约束-在 swi 中完成*/

Log_Print1 (Diags_User1、
"I2C:(%p)事务已完成"、
hwAttrs->baseAddr);

/* Hwi 句柄已发布错误的"传输完成"检查*/
if (object->mode = I2CCC26XX_IDLE_MODE){
Log_Print1 (Diags_User1、
"I2C:(%p)传输正常"、
hwAttrs->baseAddr);
RET = true;
}
}

否则{
/*如果无法开始转接,请立即回叫*/
if (status =I2C_STATUS_ERROR){
object->mode = I2CCC26XX_BUSBUSY_MODE;
Swi_post (Swi_handle (&(object->swi)));
RET = false;
}
否则{
/*如果事务已开始,则返回 true */
RET = true;
}
}

/*释放此特定 I2C 句柄的锁*/
Semaphore_post (semaphore_handle (&(object->mutex)));

/*返回状态*/
返回(RET);
} 

这是我的 I2C 代码:

I2C_Handle 句柄;
I2C_Params 参数;
I2C_Transaction i2cTrans;
uint8_t txBuf[2]={0};//发送缓冲器

//I2C 驱动程序初始化
I2C_init();
I2C_PARAMS_INIT (params);

句柄= I2C_open (Board_I2C、params);
if (!handle){
//Error
}

//加速计
//地址= 0x10
// 0x80 = 0b10000000
// ODR = 1000 (1.66kHz (高性能));FS_XL = 00 (+/-2g 满量程)
TxBuf[0]= 0x10;
txBuf[1]= 0x80;
i2cTrans.writeCount = 2;
i2cTrans.writeBuf = txBuf;
i2cTrans.ReadCount = 0;
i2cTrans.readBuf =空;
i2cTrans.slaveAddress = 0x6B;

I2C_transfer (handle、&i2cTrans); 

物理连接如下所示:

ALTIDU          CC2650 Launchpad

SCL                DIO4
SDA                DIO5
VDD                3.3V
GND               GND GND

有人能帮我弄清楚问题在哪里?

提前感谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当您调用 I2C_transfer 时、您是否在 DIO4上看到 SCL 信号?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Atlantu 的 SA0?
    运行操作系统后必须调用 i2c 传输。 您可以在 SimpleBLEPeripheal_init 中初始化和调用

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

    是的、我已经插入示波器、我看到信号(黄色:SCL、蓝色:SDA)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    SA0被拔出、由于它有一个上拉电阻器、所以它的值为 VDD。
    我已经在调用 SimpleBLEPeripheral_init 中的所有函数
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于您可以看到 SCL/SDA 信号、这意味着您的 I2C 驱动器可以工作。 您的问题是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    波形数据似乎不正确。 SCL 只有16个时钟(错过了1个字节)、SDA 应为 b'11010110000100001000010000000
    这是我在 MPU9250上的代码。 工作正常。 它与您的代码相同。 因此、我认为您应该检查 I2C 的设置(BoardGpioInitTable、i2cCC26xxHWAttrs...)  Board.h 和 Board.c.中

    MPU9250_Status_TMPU9250_I2C_Init (void)
    {
    //! 初始化 I2C 参数
    //! 默认值:I2C_MODE_BLOCK_100kHz
    I2C_PARAMS_INIT (&MPU9250_I2C_PARAMS);
    IF (MPU9250_I2C_CLK_DEFAULT = MPU9250_I2C_CLK_100kHz)
    {
    MPU9250_I2C_PARAMS.bitrate = I2C_100kHz;
    }
    否则(MPU9250_I2C_CLK_RETURN = MP9250_I2C_CLK+= MP9250kHz
    
    
    
    
    
    
    
    );}MPU250_I2C_RETURN = MP9250_I2C_CLK_I2C_RETURN = MP9250kHz! 在 CC2650
    MPU9250_I2C_Handle = I2C_open (CC2650_LAUNCHXL_I2C0、&MPU9250_I2C_Params)上使用 I2C0;
    if (MPU9250_I2C_Handle = NULL)
    {
    return MPU9250_error;
    }
    else
    {
    return MPU9250_OK;
    }
    } 
    MPU9250_Status_TMPU9250_Write (MPU9250_T * iMPU9250、MPU9250_Reg_TiMPU9250_Reg、MPU9250_Reg_Data_TiMPU9250_Data)
    {
    //!set transmit Buffer
    I2C_Transaction;
    // set!Slave Address I2C_Transaction=
    iMPU9250_Select (MPUCC9250 = iMPUGEL =)
    
    i2cTransaction。slaveAddress = MPU9250_I2C_ACCEL_GYRO_ADDR;
    }
    否则(iMPU9250->MPU9250_CURRENT_Sensor = MPU9250_COMPARE_SELECT)
    {
    i2cTransaction.slaveAddress = AK8963_I2C_ADDR;
    }
    否则
    {
    返回 MPU9250_ERROR;
    }
    //!clear TX 数据缓冲
    区 memset (MPU9250_I2C_WriteBuffer、0x00、MPU9250_MAX_TRANSAGE_LENGTH);
    //!set WRITE 寄存器
    MPU9250_I2C_WriteBuffer = iMPU9250_REG_REGISG;
    //!I2UCCEST_R2250
    
    
    
    
    
    = i2UCCER.I2250 = i2UCCEST_R5_R5_BIC_R2REFER.I2REFER.I2REF_RIF_COMP_RENT
    
    = i_RISTERn = i2REF_RIST2_COMP_COMP_RENT
    
    
    返回 MPU9250_OK;
    }
    否则
    {
    返回 MPU9250_ERROR;
    }
    } 

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

    您好 Vy、您的答案是 thaks、我认为波形正常、只是图像太小、我进行了另一次捕获、这次使用 BMP180温度传感器(地址0x77)、尝试读取0xAA 寄存器、波形对我来说似乎正常、 器件上有一个应答、但 CC2650始终在信标中等待。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我看到您没有在代码中设置 I2C 读取缓冲区。

    i2cTransaction.readBuf =空;
    i2cTransaction.ReadCount = 0;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Alex:
    您能否发送 SimpleBLEPeripheral.c、main.c、Board.c 和 Board.h。 我将查看帮助您。 )
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我在 i2c 上读取 mpu9250的代码

    MPU9250_Status_TMPU9250_Read (MPU9250_T* iMPU9250、
    MPU9250_ReG_TiMPU9250_Reg、
    MPU9250_ReG_Data_T* oMPU9250_Data、
    MPU9250_Length)
    {
    if (= 0_UMP9250)=(0|) iMPU9250 = 0 = 0)
    
    返回 MPU9250_ERROR;
    }
    //!set transmit Buffer
    I2C_Transaction i2cTransaction;
    //!set Slave Address
    if (iMPU9250->MPU9250_Current_Sensor = MPU9250_ACCEL_GYRO_SELECT)
    {
    i2cTransaction .slaveAddress = MPU9250_ACADDR_AM4250;
    
    
    
    
    
    
    
    
    
    }i2UCC2250
    
    
    = iDC_ACCEP_ACCEP_ACCEP_ACCESD_ACCESD_ACCESD_ACCESD= MP9250;}iDC_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD= i+<COMPU9250_ACCESD_COMPU9250;}iDC_ACCESD_ACCESD_ACCESD_ACCESD_ACCESD_COMPE= iDC= iDC= iDC_ACCESD_ACCESD= i+
    
    i2cTransaction.ReadCount = iMPU9250_Length;
    //!开始传输
    if (I2C_transfer (MPU9250_I2C_Handle、&i2cTransaction)
    ){
    return MPU9250_OK;
    }
    否则
    {
    return MPU9250_error;
    }
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,YiKai,您是对的,但那是我试图向 AltIMU 设备写入一个寄存器时(我没有尝试读取任何内容)。 在使用 BMP180时、我尝试读取寄存器、并且我设置了一个缓冲区。

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

    当然、我会以.zip 格式附加文件

    e2e.ti.com/.../AltIMU.zip

    感谢您的观看!

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

    我看不到代码有什么显著差异、现在我不知道问题在哪里、但感谢您的帮助

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

    我为您编辑了。 请将 I2C 的引脚更改为您的引脚。 我对其进行编辑以映射我的板、以检查 MPU9250上的 WHOIAM reg。 它发挥了作用。
    我仅更改文件 CC2650_LAUNCHXL.c 和 CC2650_LAUNCHXL.h

    /* I2C */
    #define Board_I2C0_SCL0 IOID_29//IOID_4
    #define Board_I2C0_SDA0 IOID_30//IOID_5

    TxBuf[0]= 0x75;MPU9250的//WHOIAM
    i2cTrans.writeCount = 1;
    i2cTrans.writeBuf = txBuf;
    i2cTrans.ReadCount = 1;
    i2cTrans.readBuf = rxBuf;
    i2cTrans.slaveAddress = 0x68;// MPU9250的地址

    I2C_transfer (handle、&i2cTrans);

    e2e.ti.com/.../AltIMU_5F00_edit.rar

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

    您是否使用我编辑过的代码解决了您的问题?