ST硬件IIC上电检一直检测到忙状态

本文介绍了一种在STM8S003作为I2C主机与HTU21D从机通信过程中出现的总线忙问题及解决方法。问题出现在突然断电后快速重启,导致主机检测到I2C总线忙而无法读取数据。文章详细分析了故障原因,并提供了一种通过模拟时钟信号来释放总线的方法。

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

硬件环境:
I2C主机:STM8S003
I2C从机:HTU21D
控制方式:硬件IIC


问题描述:
在程序正常运行的过程中,拔掉设备电源并迅速插回,可能出现主机不能与从机进行连接并且主机持续检测到I2C总线忙,导致无法读取温度,并且复位也不能解决。使用示波器测量SCL和SDA,发现SDA为低,SCL为高。但当断电时间长一点再次上电,通信正常。

问题原因:
板间存在较大电容,在拔掉电源的后,单片机迅速掉电停止工作,而从机在电容板间电容的的支撑下能够继续工作一段时间,并且掉电的时间处于主从机通信的过程,从机保持数据线为低状态,并等待主机的时钟信号。但是此时主机复位将不再继续产生时钟信号,并且上复位后重新初始化硬件I2C模块,硬件I2C检测到SDA为低且不是自身占用的总线,所以将置为BUSY状态,导致主机不能访问I2C总线。
解决方案:
由于是从机持有数据线并等待时钟信号,所以我们在上电第一次就检测到BUSY状态时,将I2C的IO口设置为普通的GPIO输出口,模拟100K的时钟频率,并在检测到SDA为高时,发送一个STOP信号,用以完成(中断)从机的上次通信过程,使I2C总线恢复空闲状态,然后在软复位I2C。(本方法仅适用于单主机模式)
图1 模拟I2C时序

I2C_Cmd(DISABLE); //禁用I2C
GPIO_Init(GPIOB,GPIO_PIN_4,GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_IN_FL_NO_IT); 
while(time--)
{
    GPIO_WriteLow(GPIOB,GPIO_PIN_4);
    delay_us(10);
    GPIO_WriteHigh(GPIOB,GPIO_PIN_4);
    delay_us(10);
    ret = GPIO_ReadInputPin(GPIOB,GPIO_PIN_5);
    if(SET == ret)
    {
        GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_OUT_PP_HIGH_FAST);
        delay_us(5);
        GPIO_WriteLow(GPIOB,GPIO_PIN_5);
        delay_us(10);
        GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_IN_FL_NO_IT);
        return HAL_OK;
     }
}
return HAL_ERROR;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

張公㜽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值