I2C设备热插拔产生死锁

文章介绍了I2C通信协议的基本原理,以及在电池与MCU通信中出现的死锁现象。当电池热插拔导致通信异常时,通过复位I2C外设来恢复。解决I2C死锁的方法包括确保设备地址唯一、规划总线拓扑、设置合适时序参数、利用仲裁机制和优化软件设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

       I2C(Inter-Integrated Circuit)是一个串行通信总线,它由飞利浦公司在1980年代为了让主机连接其它外设而定制的一种低速通信协议,目前广泛应用于手机、电脑、家电等嵌入式设备。

       I2C使用两根数据总线,一根是数据线(SDA),一根是时钟线(SCL),采用双向漏极开路,并使用电阻进行上拉,I2C允许比较大的工作电压范围,但一般采用3.3V或者5V。设备地址使用7位长度和10位长度。I2C 传输速率有不同的模式:

                ·标准模式:100Kbit/s

                ·快速模式:400Kbit/s

                ·高速模式:3.4Mbit/s

       I2C死锁是指在I2C通信过程中,由于两个或多个设备之间的竞争或错误操作导致I2C总线上的数据传输无法正常完成,从而导致整个系统无法继续正常工作。I2C死锁是一个非常常见的问题,可能会影响到整个电路板或系统的稳定性和可靠性。

二、问题现象

      电池(芯片:BQ40Z80)与MCU之间采样I2C通信,设备在正常运行的情况下突然拔出一个电池,再插回去,导致电池一直通信不成功。逻辑分析仪查看实际波形如下所示:

       1.设备正常运行过程中拔出电池再插回去产生如下波形 

图2.0 电池拔插产生的波形

       2.在拔插电池产生异常的情况下,把电池拔出MCU产生如下波形

图2.1 在产生异常的情况下拔出电池MCU产生的波形

       3.电池拔出再插回去产生如下波形

图2.2 拔出电池再插回去产生的波形

       根据上面的实测波形发现,设备正常通信的情况下突然拔插电池,会导致通信状态错乱,且无法恢复。

三、解决方法

       I2C设备有些是支持热插拔,有些是不支持热插拔,而电池管理芯片有明确说明是支持热插拔,根据这个就可以从软件层面试着解决这个问题。由于这个芯片对时序要求比较严格,所以采用硬件I2C跟它通信。当遇到通信不正常的情况下,就复位I2C外设,代码如下所示:

if(Bq40z801ReadByte(BQ40Z80_DEV1_ADDR,STATUS_REG,&battery[0].status) == ESP_OK)

    {

        Bq40z801ReadByte(BQ40Z80_DEV1_ADDR,TEMPERATURE_REG,(uint16_t*)&battery[0].temperature);

        Bq40z801ReadByte(BQ40Z80_DEV1_ADDR,VOLTAGE_REG,&battery[0].voltage);

        Bq40z801ReadByte(BQ40Z80_DEV1_ADDR,CURRENT_REG,(uint16_t*)&battery[0].current);

        Bq40z801ReadByte(BQ40Z80_DEV1_ADDR,PERCENT_REG,&battery[0].percent);

        // Bq40z802ReadByte(BQ40Z80_DEV2_ADDR,0x0D,&battery[0].percent);

        battery[0].charge_state = GetBatteryStatus(battery[0].status,battery[0].current);

    }

    else

    {

        Battery[0].temperature = 0;

        Battery[0].voltage = 0;

        Battery[0].current = 0;

        Battery[0].percent = 0;

        Battery[0].charge_state = 0;

        Battery[0].status = 0;

        // memset((char*)&Battery[0],0,sizeof(&Battery[0]));

        ESP_LOGI(TAG,"byttery1 read fail\r\n");

        I2cReset(I2C0_NUM,I2C0_SCL_PIN,I2C0_SDA_PIN);

    }

      其实I2C死锁的原因有很多种,包括硬件故障、软件编程错误、通信协议不一致等。为了避免I2C死锁问题,我们可以采取以下几种措施:

       1.确保各个I2C设备的地址唯一,以避免地址冲突。

       2.设计时合理规划好I2C总线的拓扑结构,避免过长的传输线路和过多的设备导致信号失真和干扰。

       3.在设计I2C通信时,合理设置I2C时序参数,以确保数据传输的正确性和稳定性。

       4.对于需要进行复杂数据传输的场景,可以利用I2C的仲裁机制,避免设备之间的竞争和死锁现象发生。

       5.在程序设计上,应该合理使用锁和中断处理机制,以避免由于程序逻辑错误而导致I2C死锁问题发生。

       6.为了避免I2C死锁问题,我们需要在硬件和软件两方面重视I2C通信的稳定性和可靠性,并进行合理规划和设计。

       7.如果I2C设备对时序没有严格的要求,建议使用软件模拟I2C,这样可以避免很多问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值