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.

[参考译文] TCA9548A:I2C多路复用问题

Guru**** 2361250 points
Other Parts Discussed in Thread: TCA9548A, BQ3060
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/595448/tca9548a-i2c-multiplexing-problem

部件号:TCA9548A
主题中讨论的其他部件: BQ3060

i´m使用TCA9548A以多路复用具有相同地址的i2c器件。
此i2c器件是bq3060 IC,目的是从端口0和1中连接的IC读取寄存器。
我成功读取了端口0中的IC。 端口1中的另一个IC。 但当我尝试读取第一个端口0和第一个端口1之后的两个端口时,有时会出现读取问题。 问题在于TCA中的端口选择发生了更改。
我已经看到,当我有读取问题时,是因为在发送到TAC9548 (在“tcaselect()”,“BP_WriteReg”)中选择端口的i2c信号中,停止位发送不正确。 我在我的应用程序的代码下面发布,并且在我写入TCA端口时附加了i2c信号。
我的问题是,为什么有时我在TCA9548中写时停止位不能正确发送,而有时是正确发送。 如果发送不正常,则当停止位的数据较高时,时钟信号似乎会下降。

I2C信号发送到TCA以选择端口(黑色标记位是停止位):


我的代码是下一个:

tcaselect(0);
VoltageArray[0]=BP_ReadReg (0x09);
SOCArray[0]=BP_ReadReg (0x0d);

tcaselect(1);
VoltageArray[1]=BP_ReadReg (0x09);
SOCArray[1]=BP_ReadReg (0x0d);

void tcaselect(uint8_t I)
{
if (i >7) return;
tmp=(1<I);
BP_WriteValue (0x01,tmp);
}void t_Writut-Reg {(u8)-----



透射相位--------------------------- */
/*发送BP_I2C启动条件*/
I2C_GenerateSTART(BP_I2C, enable);

/*在BP_I2C EV5上测试并清除*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT))/* EV5 */
{
}/*

发送BP从属地址以写入*/ I2C_M7itResmit_I2C_D,
I2C_TransmitAddress I2C_I2C_I2C_I2C_Transmit_I2C_I2C_

/*在BP_I2C EV6上测试并清除它*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_TRANSMER_MODELE_SELECTED))/* EV6 */
{}/*


发送指定的寄存器数据指针*/
I2C_Reg Data(BP_I2C,(uint8_t)RegValue);

/*在BP_I2C EV8上测试并清除*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_BYTE_Transmitted ))/* EV8 */
{}/*


发送BP_Readstop条件*/
BP_GenerateSTOP(BP_GenerateSTOP, I2C_Ent



=16 I2I2I2I2I2C_Regut_Int


/*如果BP_I2C确认已被其它函数禁用,则启用BP_I2C确认*/
I2C_AcknowledgeConfig (BP_I2C, ENABE);

/*--------------- 透射相位--------------------------- */
/*发送BP_I2C启动条件*/
I2C_GenerateSTART(BP_I2C, enable);

/*在BP_I2C EV5上测试并清除*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT))/* EV5 */
{
}/*

发送STBP从属地址用于写入*/
ADBP_I2C_Send7itD, I2C_TransmitD(I2C_ADBP_D, I2C_TransmitAddress

/*在BP_I2C EV6上测试并清除*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_TRANSMORT_SELECTED))/* EV6 */
{
}/*

发送指定的寄存器数据指针*/
I2C_SendData(BP_I2C, RegName);

/*在BP_I2C_EV8上测试并清除*/
同时发送(I2C_EV8 (_I2C_EV8


接收阶段--------------------------- */*
发送重写条件*/
I2C_GenerateSTART(BP_I2C, enable);

/*测试EV5并清除*/
同时(!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT))/* EV5 */
{
}/*

发送BP从地址以读取*/
接收器_Send7bitAddress(I2C_I2C_I2C_, ADBP_I2C_DIC)

/*在EV6上测试并清除它*/
同时(!I2C_CheckEvent (BP_I2C, I2C_EVENT_MASTER_RECEIVER_MODED_SELECTED)/* EV6 */
{
}/*

在EV7上测试并清除它*/
同时(!I2C_CheckEvent (BP_I2C, I2C_EVENT_MASTER_MORTE)/* EV7 */
{}_I2I2C_RECETELET



=接收数据存储区(BP_16

/*禁用BP_I2C确认*/
I2C_鸣 谢配置(BP_I2C, disable);

/*发送BP_I2C停止条件*/
I2C_GenerateSTOP (BP_I2C, enable);

/*在RXNE标志上测试*/
同时(I2C_GetReceivStatus(BP_I2C, I2C_RESET_Lag_RXNE)== BP){}/*


存储BP_I2C_RegValue;


/*返回寄存器值*/
返回(RegValue);
} 

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

    您好,Ekiuser:

    您使用什么设备来控制TCA9548A?  它是TI的其中一个吗?  如果是这样,我可以将此帖子移到他们的论坛,以帮助您调试代码。  我们实际上只支持硬件。  可以清楚地看到,停止条件未由主控制器正确执行。  

    Francis Houde

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

    ´m,我´s它不是TI的´s´m器,我使用的是ST微控制器。

    但是,使用"writereg"功能选择一个端口的功能似乎是可以的。 如果我在任何一个TCA9548A端口中仅连接1个i2c设备,我可以正确读取所连接设备的任何i2c寄存器。 如果我只选择1个端口,则没有问题。
    如果我要从一个端口切换到另一个端口,以便读取连接到TCA端口的两个不同的i2c设备,则会出现问题。 是否是硬件问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Ekiuser:
    您是否有系统示意图? 我想查看它,以确保我知道一切是如何连接的。

    您正在总线上切换电容负载,这可能是问题所在。 您可能希望在设置停止条件后,在尝试通信之前设置短暂延迟。 这只是目前的猜测,但可能值得尝试。
    Francis Houde
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Francis:

    我管理系统以使其正常工作,而不会更改代码。 n´tn´t,弗朗西斯说:“我还没有系统的原理图,我也按照你的建议,尽量缩短了时间,但没有成功。

    我将所有i2c通信时钟放在一起;主i2c CLK信号与从属i2c时钟(端口0从属和端口1从属)放在一起。 n´t还不错,但我不明白为什么。 就我在数据表中所见,在本TCA9548A中,假定主i2c必须连接到SLC,SDA引脚; 然后,端口0中的从属i2c必须连接到SCL0和SDA0引脚,端口1中的从属i2c必须连接到引脚SCL1,sda1。 顺便说一下,所有GND都连接在一起。 n´t,我的系统无法正常工作(问题是我之前解释过的)。 我必须将SCL0和SCL1从TCA引脚移开,并与SCL主引脚连接。
    连接是否正确? 能否有人解释一下?

    谢谢你,ini Advance!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Ekiuser:
    我迷路了。 我真的很想看到一个示意图来了解正在发生的事情。 这真的毫无意义。 发送I2C命令的顺序是什么? 此外,您是否有设置的图片以及有关如何连接总线的信息? 线束? 主板到主板?
    Francis Houde
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    添加的图像中显示了i2c原理图。
    在第一个原理图中,如我所说,每个从属(每个bq3060) SDA和SCL都连接到TCA端口0和端口1。 n´t这种方案,系统无法正常工作。
    在第二个示意图中,所有时钟都连接在一起,系统工作正常。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Ekiuser:
    我知道这可能是一个愚蠢的问题,但您是否在SC和SD的所有通道上都有上拉列表,如果有,这些值是什么? 您是否使用万用表进行过验证? 您是否向控制寄存器写入了3h,然后在尝试与bq零件进行通信之前执行停止条件? 我知道您可能已经完成了所有这些工作,但我只是想确保我没有遗漏任何内容。
    弗朗西斯·胡德
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Ekiuser:
    从POST开头的波形看,您只打开B1而不是B1和B0,您只发送0x02h。 这是故意的吗?
    Francis Houde
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Francis,

    是的,我在每个SC,SD端口中都有上拉电阻器。 在主电路中,上拉电阻器为4k7,但我也尝试了10k。

    关于通信序列,正如您在代码中看到的,首先,我将控制字节发送给主控制字节以选择端口。 此控制字节以停止条件结束。 然后,我从从属设备读取一个寄存器(端口0或1中的bq)。 您可以在我在第一篇文章中发送的代码中检查此信息。

    为了选择端口0,我只打开B0并选择端口1 B1。 如果我要选择端口2,我只能打开B2。 这是正确的,n´t是吗?

    谢谢!

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

    (Francis本周不在办公室,因此我将研究这个问题。)

    您认为只需将B0设置为打开端口0,只需将B1设置为打开端口1等

    是否有方法可以验证端口上的电压,该端口在启用之前立即被激活? 是否有任何方法可以降低而不是拉高? 在"不正常"的情况下,当记录停止条件时(即启用信道时),时钟线会短暂地拉低。 但是,很难确定此时间范围-放大停止条件以更好地了解时钟转换发生的确切时间是有用的。

    另外(仅供我理解)-您是否总是在启用另一个信道的同时禁用一个信道,还是遵循"先接后断"(打开新信道,然后关闭旧信道)或"先接后断"(关闭当前信道, 然后打开新通道)程序? 我不确定这两种方式是否会有所不同,但我还是想问一下,以便为您提供的波形提供一些背景信息。

    此致,
    最大