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.

[参考译文] CC2640R2F:支持 CC2640R2 的 I2C

Guru**** 2535150 points


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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1567050/cc2640r2f-i2c-with-cc2640r2

器件型号:CC2640R2F


工具/软件:

我正在我的 CC2640R2 板上运行 Simple_Central 代码、并使用 UART 将通过蓝牙接收到的数据中继到 LaunchXL-F280025。 因此、我想使用另一个连接到显示器的电路板以及一些按钮来回传递消息、以搜索蓝牙设备、然后进行连接。 通过 USB 串行显示的信息。  我尝试将 CC2640R2 用作 I2C 从器件。  在 I2C 驱动程序代码中、有一些设置函数、然后您调用 I2CTransfer 函数。  我正在尝试弄清楚此函数在 I2C 序列中的工作原理。  通常、从器件将一直等待、直到主器件发送起始位以及从器件地址、一旦从器件确认地址匹配、主器件将发送数据。  似乎该序列只是启动事务。  在封面下、如果您将主器件配置为从器件、该功能是否挂起并等待主器件发送起始位?  

 我一直在使用 STM 板学习裸机代码、并有一些基本的 I2C 代码、用于使用板上的多个 i2c 引脚配置主器件和从器件。  我尝试仅使用此电路板上的主代码并与 TI cc2640R2 电路板通信、但我没有收到 TI 电路板的任何响应。  STM 代码使用从设备的中断。  当我调试代码时、主器件发送一个起始位以及地址、由于设置了地址中断、这会触发从器件中断。  我想知道 STM 电路板是否在发送地址、但 TI 电路板未响应。  我设置了一个传输回调函数、但我一直收到失败状态、没有其他结果。  如果有任何想法可以引导我朝着正确的方向前进、我们将不胜感激。   

这是我在 simple_central 程序中的单独线程上启动的一些代码。   

void transferCallbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool status)
{


     Display_print1(dispHandle, 7, 0, "Transaction Status %i\n", status);

//      // Check for a semaphore handle
//      if (msg->arg != NULL) {
//
//          // Perform a semaphore post
//          sem_post((sem_t *) (msg->arg));
//      }
}


static void SerialPeriph_Init()
{
          // initialize optional I2C bus parameters
          I2C_Params params;
          I2C_Params_init(&params);
          params.bitRate = I2C_400kHz;
          params.transferMode = I2C_MODE_CALLBACK;
          params.transferCallbackFxn = &transferCallbackFxn;

          // Open I2C bus for usage
          I2C_Handle i2cHandle = I2C_open(0, &params);
          if (i2cHandle == NULL) {
                  Display_print0(dispHandle, 6, 0, "Error Initializing I2C\n");
                  while (1);
              }
              else {
                  Display_print0(dispHandle, 6, 0, "I2C Initialized!\n");
              }

         // Initialize slave address of transaction
          I2C_Transaction transaction = {0};
          transaction.slaveAddress = SLAVE_ADDR;

          // Read from I2C slave device
          transaction.readBuf = readBuffer;
          transaction.readCount = sizeof(readBuffer);

          while(1) {
              I2C_transfer(i2cHandle, &transaction);
          }
    }


在 Simple_Central_ taskFxn 的 init 函数中调用此代码

我还确保启用 BoardGpioInitTable 中的引脚

ONST PIN_Config BoardGpioInitTable[]={

CC2640R2_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_DRVSTR_MAX、/* LED 最初关闭*/
CC2640R2_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_DRVSTR_MAX、/* LED 最初关闭*/
CC2640R2_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS、/*按钮为低电平有效*/
CC2640R2_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS、/*按钮为低电平有效*/
CC2640R2_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PushPull | PIN_DRVSTR_MIN、/*外部闪存芯片选择*/
CC2640R2_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN、/*通过调试器反向通道的 UART RX */
CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PushPull、/*通过调试器反向通道的 UART TX */
CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN、/* SPI 主器件输出 — 从器件输入*/
CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN、/* SPI 主器件输入 — 从器件输出*/
CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN、/* SPI 时钟*/
CC2640R2_LAUNCHXL_I2C0_SCL0 | PIN_INPUT_EN | PIN_PULLUP、/* I2C 时钟*/
CC2640R2_LAUNCHXL_I2C0_SDA0 | PIN_INPUT_EN | PIN_PULLUP、/* I2C 时钟*/

PIN_Terminate
};

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

    您好!

    您是对的、从器件通常在等待主器件启动事务。 当 I2C 驱动程序设置为挂起模式时就会出现这种情况。 但是、在代码中、您要在回调模式下设置 I2C 驱动程序。 根据 API、此模式具有不同的行为

    I2C_MODE_CALLBACK 中、对 I2C_TRANSFER () 的调用立即返回。 事务完成时会调用应用程序的回调函数 I2C_Params.transferCallbackFxn。 对 I2C_TRANSFER () 的顺序调用将把 I2C_Transaction 结构放到一个内部队列中。 排队的事务将在上一个事务完成后自动启动。 无论先前事务的任何错误状态如何、都会出现此队列。 事务始终按时间顺序执行。 当每个事务完成时、I2C_Params.transferCallbackFxn 函数将进行异步调用。

    通过将 I2C 置于回调模式并在 while (1) 循环中运行、您会不断地将事务查询添加到内部队列中、从而快速填充缓冲区、毫无理由地使用大量计算时间和功耗。

    因为您已经在努力创建新线程、 我认为、您的用例的理想解决方案是在阻断模式下使用 I2C 。 您可以在 I2C 的 API 概要中看到有关如何使用阻塞模式的示例

    此致、
    Lea