主题中讨论的其他器件:ADS1110
我使用 I2C 模块与 ADS1110 ADC 进行通信。 我的控制器是线路上唯一的主器件。 一切都正常、但有时会发生、当我将应用程序下载到控制器并进入调试模式时、或者当我重新启动器 件时、I2C 线路将卡在 I2CMasterBusy 状态、并且我无法与 ADC 进行通信(因为我在每次迭代时都会检查 I2CMasterBusy)。 是否有办法重置 I2C 总线的状态? 我是否应该使用某种超时?
此致、
Ksawery
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.
我使用 I2C 模块与 ADS1110 ADC 进行通信。 我的控制器是线路上唯一的主器件。 一切都正常、但有时会发生、当我将应用程序下载到控制器并进入调试模式时、或者当我重新启动器 件时、I2C 线路将卡在 I2CMasterBusy 状态、并且我无法与 ADC 进行通信(因为我在每次迭代时都会检查 I2CMasterBusy)。 是否有办法重置 I2C 总线的状态? 我是否应该使用某种超时?
此致、
Ksawery
谢谢、我将尝试此解决方案。 最坏情况是否也适用于所有其他情况? 以下是我的代码的一部分:
// I2C 配置 SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); GPIOPinConfigure (GPIO_PB2_I2C0SCL); GPIOPinConfigure (GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
如果(!I2CMasterBusy (I2C0_BASE) { ... //读取 ADC } 否则//强制 ADC 释放 SDA 线 { GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_3); //模拟 SCL 时钟周期 对于(ucSCLCycle = 0;ucSCLCycle < I2C_RESET_CYCLLES;ucSCLCYC++)//I2C_RESET_CYCLES= 9 { GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0);//SCL 线路低电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2);//SCL 线路高 电平} //模拟停止条件 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0);//SCL 线路低电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、0);//SDA 线路低电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2);//SCL 线路高电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、GPIO_PIN_3);//SDA 线路高电平 //将引脚重新配置为 I2C GPIOPinConfigure (GPIO_PB2_I2C0SCL); GPIOPinConfigure (GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3); }
此代码是否与 I2C 的标准速度(100kbit/s)兼容?
由于某种原因、我今天无法重现问题、因此我目前还无法测试我的代码。
此致、
Ksawery
我设法再次重现此问题、解决方案确实起作用、但是在释放 I2C 线路之前、仍会输入两次 else 条件。 也许我应该增加延迟以匹配100kbit/s 的速度? 或者、我的代码中的事件顺序可能存在错误? 我的代码现在如下:
否则、//强制 ADC 释放 SDA 线 { GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_3); //模拟 SCL 时钟周期 对于(ucSCLCycle = 0;ucSCLCycle < I2C_RESET_CYCLLES;ucSCLCYC++) { GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0);//SCL 线路低电平 SysCtlDelay (100); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2);//SCL 线路高电平 SysCtlDelay (100); } //模拟停止条件 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、0);//SCL 线路低电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、0);//SDA 线路低电平 SysCtlDelay (100); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_2、GPIO_PIN_2);//SCL 线路高电平 GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、GPIO_PIN_3);//SDA 线路高电平 //将引脚重新配置为 I2C GPIOPinConfigure (GPIO_PB2_I2C0SCL); GPIOPinConfigure (GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3); }
系统时钟以50MHz 运行。
此致、
Ksawery
[引用 USER="Ksawery">我使用 I2C 模块与 ADS1110 ADC 通信。 我的控制器是线路上唯一的主器件。 一切都正常、但偶尔会发生、当我将应用程序下载到控制器并进入调试模式时、或者当我重新启动器件时、I2C 线路将卡在 I2CMasterBusy 状态
不是,“把一把大的猴子扳手扔进这个 saga”——但你真的想部署“I2CMasterBusy ()”吗?
PDL 注:
16.2.2.11 I2CMasterBusy
指示 I2C 总线是否繁忙。
原型:bool I2CMasterBusy (uint32_t ui32Base)
参数:ui32Base 是 I2C 模块的基址。 说明:此函数返回 I2C 总线是否繁忙的指示。 此函数可在多主器件环境中用于确定 另一个主器 件当前是否正在使用总线。
返回:如果 I2C 总线忙则返回 true;否则返回 false。
您将您的应用描述为,“单从机连接到单个 MCU”-因此“I2CMasterBusy ()”可以证明正确的功能选择吗? (即(另一个)主设备使用此总线的可能性有多大?)
相反-正如一个过去(非常相似)的线程所指出的那样-
16.2.2.12 I2CMasterBusy
指示 I2C 主设备是否忙。
原型:bool I2CMasterBusy (uint32_t ui32Base)
参数:ui32Base 是 I2C 模块的基址。 说明:此函数返回 I2C 主设备正忙于发送或接收数据的指示。
返回:如果 I2C 主机繁忙、则返回 true;否则返回 false。
这种"I2CMasterBusy()"是否更适合您的"单主器件"I2C 应用?
请注意-过去曾有过建议-参数:'I2C_MASTER_CMD_BURST_SEND_START'和'I2C_MASTER_CMD_BURST_SEND_CONT'-阻止 I2C 停止位的生成-如果和何时 部署了"更合适的函数"(似乎)... (即,您不会在出现上述任一(Devil)参数后使用 I2CMasterBusy()。)
感谢您的回复。 是的,我已经在我的应用程序中使用 I2CMasterBusy()了,该部分工作正常。 我不确定我是否应该在我的应用程序中使用 I2CMasterBusy(),因为我只有一个主函数,但我认为它也不会伤害。 现在我遇到了 ADC 有时可以使 SDA 线保持在低电平的问题,我不确定如果我继续运行应用程序而不进行 I2CMasterBusy()检查会发生什么情况。 我宁愿按照 Bob Crosby 的建议手动考虑这种情况。 据我所知、它不会导致应用程序出现任何问题。
此致、
Ksawery
当然、您有自己的权利-但如果我们采用"添加不需要的功能程序"-为什么要停止"仅此程序?"
"并非总是"更好-实际上、可能会"打开您的应用程序"以"意外后果"。 您报告(某些)随机情况的事实实际上是(可能)警告-"所有情况可能不好..."
你的开场白(第2句)清楚地描述了一个单身师父——这一事实(显然)“被人所用!”
生成额外的 I2C 时钟已成功(有时-但不是总是)恢复主从交换。 然而-简单 的'I2C Start' 通常'复位从器件'-再次启用数据交换-然而(也许)不包括您正在报告的'随机性'。 (在我看来-这/类似的技术-证明优于添加(不必要的)多主函数...)
[引用 user="Ksawere"]一切工作正常,直到 ADC 在进入调试模式后再次保持线下。
然而,当只有一个“单个大师在演奏”时,使用一个旨在“多蒂大师”的功能似乎被误导了。
您进入"调试模式"(显然是(单独)会导致您的问题)的"原因、时间、地点和方式"可能需要进一步(例如、某些)进行真正的检查...
是否应该(部分)关注/调查外部 从器件(ADC)"将其中一条 I2C 线路保持在低电平?" 这是(或应该是)您的关注点-这不是真的吗?
通过避免这种分析-您不是、"推广(解决方案)"-而是避免恰当(正常/习惯)但 更有价值的"寻找原因"? 一定要来 "预防"总是远远超出- 任何/所有"希望"的问题...
这篇文章声称、在主器件在传输期间复位后、需要16个 SCL 周期来恢复卡住的从器件。
https://www.i2c-bus.org/i2c-primer/analyzing-obscure-problems/blocked-bus/
当我建议9 SCL 时、恐怕我错过了主器件请求读取并在命令之后的 ACK 阶段复位的条件。 它将需要2个8位传输(16个时钟)来完成该读取请求。 我想您在18个时钟周期内会很好。
CB1、
我相信,在这种情况下,问题的根本原因是很清楚的。 当 IC2主器件在发送期间复位时、I2C 从器件在当前状态挂起、等待下一个 SCL。 当这个状态保持 SDA 线路为低电平时、总线被检测为忙。 当主器 件复位后、它可以通过读取 SDA 线作为 GPIO 并检查其是否为低电平、或者调用 I2CMasterBusy()函数来检测这种情况。
在所有 I2C 从器件都具有复位输入引脚的系统中、可通过确保 I2C 从器件在 I2C 主器件(微控制器)复位时复位来避免这种情况。 引脚数较少的 I2C 从器件可能没有复位输入(如 ADS1110)。 在这种情况下、可以使用上述权变措施。
Bob、
[引用 user="Bob Crosby"]当 IC2主设备在传输期间复位时,I2C 从设备在其当前状态下挂起
感谢您解决此问题。 但是-在哪里有这样的说法:'I2C 主设备'(即这个 I2C 总线上的唯一 MCU)已经被称为'在 I2C 传输期间复位?' 我(有限)的员工(学校已经回收了很多)也没有发现这种情况的"任何"证据! 这是一个关键/关键点-不是吗?
现在、如果 I2C 事务都处于(两者)"高和持续速率"-也许这样- MCU 的复位(可能)可能会在进行中的传输(实际事务)期间发生。 然而、"根本没有事实证据支持此类交易(高利率/持续 I2C 交易!")
此外-我们的海报必须特别努力来达到这种条件(即故意"重置 MCU -而 I2C 交易正在进行中)-我的团队认为、事实证明"不大可能"发生。 还记得-海报指出多次发生"挂起"-除非他的 MCU 复位电路存在"极有缺陷"-在 这种特定情况下、"MCU 在 I2C XMSN 期间复位"作为"问题触发器"寄存器显示为"已获取"!
此外-对于此类"单 MCU /主系统"、'I2CMasterBusy ()'函数的使用仍然是'不正确'(从'Get-Go'开始是如此)-这是海报的现实。 (在直指"避免"的情况下-继续干扰!)
事实上、"您"在调查(通常)"所需的 SCL 时钟数"以"租用总线"方面所做的特殊努力证明了信息丰富且有帮助。 然而-大学生和 我"继续"认为"最有可能导致奴隶不适的原因的覆盖面"仍然"未知"、 并且没有开展任何调查活动。 (这里没有人认为这是"最佳实践"-显然值得(一些)时间和精力!)
似乎、"将 MCU 复位为 ADC 的复位值(假设电压电平类似)会有助于"自行清除" ADC! (如果它受到干扰/困扰。) 此外-在 MCU 和寻址外设之间的任何事务之前、必须保证足够的"时间通过"-在 MCU 复位后立即进行。 人们相信,“这一纪律”——以及删除(不适当的)“I2CMasterBusy ()”——提供(两者)一 个广泛而真实的解决方案——并且(可能)消除(至少大大减少)对“SCL 时钟的大量”的要求!
从"长期"-有时令人痛苦的经历-我认为、"很可能"导致此类"I2C 挂起的原因可能是:
"不必要/非法的脉冲"-直接耦合或在 SCL 信号线路上引起!" 这将导致" MCU-Slave"后续(或正在进行)事务变为"不同步"-可能触发从属方的"总线闲置"。 I2C 信号长度过长、PCB 布局不良、噪声源放置在离(尤其是) SCL 信号布线太近的位置、以及使用"值太高的上拉电阻器"(即 MCU 内部的(来自任何供应商)-上述任何/全部都是"经证明的、可能可疑的!"
也许"额外的探究水平"(此处建模)更好地说明了"确定问题的"最可能原因"、并源于这一见解-发展卓越的、重点更突出的解决方案!
尊敬的 CB1:
感谢您的回复以及在尝试识别问题时所做的努力。 Bob Crosby、感谢您的澄清。 我可以确认问题很少发生、并且在将我的应用程序反复下载到控制器并进入调试模式时、我完全偶然发现了这一问题。 因此、正如您提到的、这可能会导致 SCL 线路上产生不需要/非法的脉冲。 我确信、在正常使用期间、问题不太可能发生(假设电路的其余部分(我不负责)正常工作)。 但是、由于我将把我的项目转交给另一个工程组(这纯粹是一个内部项目)、 对于那些只需要 IT 工作并且不熟悉应用细节的人、我不希望他们遇到任何意外问题(例如、他们必须手动重启器件的情况)。
考虑到我几乎完全不熟悉嵌入式编程、这是我在这个工作场所的第一个项目、现在我对这个变通办法感到满意-即使没有必要、它也证明可以在这些罕见的事件中工作。 也许,在未来有更多时间研究这个问题时,我可能会放弃使用 I2CMasterBusy(),但现在已经证明它是有用的。 如果您对该问题有任何其他见解、我很乐意将其考虑在内。
此致。
Ksawery
谢谢您-感谢您的周到回应。
作为一个活跃的论坛-首先是由'Luminary Micro Systems'(即 Stellaris 创建者)拥有/运行的论坛、现在已超过10年-以及超过25年的'Tech Wars'(包括共同创建-吸收过去的 Tech FiRM Public)-已经学习了'som'课程(也许)。 而且-希望-大部分知识、方法/(疯狂?) 精练的——可能会为他人服务——甚至在这里!
没有什么可添加的-但这些项目(可能)需要考虑:
对于"点"(就在上面)-" MCU 和 ADC 复位线路的连接"-您将保持沉默(如适用)。 多个"验证"已获得批准-但这项(相信)卓越建议似乎"逃避了您的通知"-我们是否可以问为什么?
任何认真的"迹象审核"都将检测到"多主控"I2C 函数的存在(不正确)-这无法证明您的优势-我不知道(如何更好)再次强调这一点...