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.

[参考译文] CC2541:使用 I2C 时 BLE 广播消失的问题

Guru**** 2826755 points

Other Parts Discussed in Thread: CC2541

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1043185/cc2541-problem-disappearing-ble-advertisement-using-i2c

器件型号:CC2541

尊敬的读者:

目前、我正在从事一个同时需要 I2C 功能和 BLE 功能的项目。 CC2541支持这些功能、因此这很好。   

情况

  • 我能够 使用 I2C 协议写入 PCA9635 LEDdriver 模块的寄存器。  
  • 我能够使用 BLE 连接到器件、我有恒定的传入数据流(每350ms 一次)。

目标

  • 能够实现稳定(连续)的 BLE 连接、并且能够不时(不太频繁)向 LEDdriver 写入数据。

问题

  • 使用 I2C 写入寄存器时、器件停止广播其配置文件(在 lightBlue 应用中不再可见)。 因此、BLE 和 I2C 都可以单独工作、但将它们一起使用可以解决问题。

结果

  • 将全局中断使能位设置为0会破坏 BLE 连接。 发现此问题后、解释相当简单、因为 BLE 需要中断才能工作。
  • 在 BLE 软件开发人员指南中、我发现应用的处理时间(I2C)可能最多需要2ms。 (第7.6.2节:限制 BLE 活动期间的应用处理)。 我可以轻松测量事件的时间吗? 由于 BLE 的中断具有最高优先级(对吧?)、连接如何中断。 我希望 I2C 通信会中断、而不是 BLE 广播。  
  • 向 I2CDATA 寄存器写入0x00或0x01时、器件在 lightBlue 应用中仍然可见、因此 BLE 似乎仍然工作。 将0xAA 写入 I2cData (从而写入 LED 驱动器)时、器件会在 lightBlue 应用中消失。 考虑到这一点、假设这是一个时序问题:向 I2cData 这样的寄存器写入更多1是否需要更长时间?

所以我的问题是、这个问题的原因是什么、如何解决呢?  
我用于写入 I2C 数据的 I2C 函数为:

typedef 枚举

 // HAL_I2C_MASTER 模式时钟频率。
 i2cClock_123KHZ = 0x00、
 i2cClock_144KHZ = 0x01、
 i2cClock_165KHZ = 0x02、
 i2cClock_197KHZ = 0x03、
 i2cClock_33KHZ = 0x80、
 i2cClock_267KHZ = 0x81、
 i2cClock_533KHZ = 0x82
} i2cClock_t;

空 HalI2CInit (i2cClock_t 时钟速率)

 //设置上拉引脚。
 I2CWC = 0x0C;// 0000 1100

 //重置 I2C 配置
 I2CCFG = 0x00;// 0000 0000

 //设置 I2C 时钟速率
 I2C_CLOCK_RATE (时钟速率);

 //启用全局中断(IEN0.EA = 1)
 IEN0 |= 0x80;// 1000 0000
 //启用中断(P2IE = 1)
 IEN2 |= 0x02;// 0000 0010

 //启用 I2C (ENS1 = 1)
 I2C_ENABLE();

空 HalI2CDisable (空)

 //通过删除时钟信号来停止通信
 I2C_STOP();

 //禁用时钟信号
 I2C_disable();

 //禁用中断(P2IE = 0)
 IEN2 &= 0xFD;// 1111 1101

 //不要禁用全局中断,因为这会破坏 BLE 功能。
 //禁用全局中断(IEN0.EA = 0)
 // IEN0 &= 0x7F;// 0111 1111

void setLEDOUTPUT0 (uint8寄存器 LEDOUT0)


 HalI2CInit (i2cClock_33KHZ);

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //设置 LEDOUTPUT 0 - 3
 //通过发送起始位来启动通信(STA = 1)
 // 1:清除 SI 位(到0)(中断标志)
 I2CCFG &= 0xF7;// 1111 0111
 // 2:设置起始位(设为1)
 I2CCFG |= 0x20;// 0010 0000
 // 3:等待 SI 位被置位(设为1)(中断标志)
 while (((I2CCFG & 0x08)= 0);// 0000 1000
 // 4:未设置起始位(至0)
 I2CCFG &= 0xDF;// 1101 1111

 //发送设备地址并通知写入
 if (I2CSTAT = 0x08)//如果一个 START 条件已经被发送(应该)
 {
  // 1:将器件地址和 R/W 加载到 I2C 数据寄存器中
  I2cData =((0x00 << 1)| 0x00);// 0x00 =写入
  // 2:清除 SI 位(到0)(中断标志)
  I2CCFG &= 0xF7;// 1111 0111
  // 3:等待 SI 位被置位(设为1)(中断标志)
  while (((I2CCFG & 0x08)= 0);// 0000 1000
 }

 //将数据字节发送到设备
 // 1:检查器件(从器件)是否已确认请求。
 如果(I2CSTAT = 0x18)//如果器件地址和写入位已经发送,则接收到 ACK。
 {
  //发送字节
  // 1:将 dataByte 加载到 I2C 数据寄存器中
  I2cData = 0x14;//dataByte;
  // 2:清除 SI 位(到0)(中断标志)
  I2CCFG &= 0xF7;// 1111 0111
  // 3:等待 SI 位被置位(设为1)(中断标志)
  while (((I2CCFG & 0x08)= 0);// 0000 1000
 }

 //将数据字节发送到设备
 // 1:检查器件(从器件)是否已确认请求。
 如果(I2CSTAT = 0x28)//如果器件地址和写入位已经发送,则接收到 ACK。
 {
  //发送字节
  // 1:将 dataByte 加载到 I2C 数据寄存器中
  I2cData =寄存器 LEDOUT0;//0xAA;//dataByte;
  // 2:清除 SI 位(到0)(中断标志)
  I2CCFG &= 0xF7;// 1111 0111
  // 3:等待 SI 位被置位(设为1)(中断标志)
  while (((I2CCFG & 0x08)= 0);// 0000 1000
 }

 //通过设置停止位(STO = 1)停止通信
 HalI2CDisable();

 返回;

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

    您好 Stefan、

    您能告诉我们您正在使用的 SDK 吗? 一名执行人将很快发表评论。

    最棒的

    不需要

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

    是的 、这是 V1.3.2。

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

    您好 Stefan、

    我建议您迁移到最新的 SDK 并重新测试。 1.3.2 SDK 已使用多年、不再有可行的产品发展路径。  

    您可以在以下位置找到最新的 SDK: www.ti.com/.../BLE-STACK