找回密码
 立即注册
查看: 171|回复: 2

电路板重新上电后,iic初始化会卡死,这是为什么

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-28 13:19:20
已绑定手机

6

主题

3

回帖

60

积分

注册会员

积分
60
发表于 2025-9-28 13:19:20 | 显示全部楼层 |阅读模式
各位大佬,求助
电路板重新上电后,iic初始化会卡死,这是为什么
电路接USB转TTL串口打印,电路重新上电(不拆串口线),单片机下挂载2片IIC通讯的传感器,重新供电,程序会卡在iic初始化处

截图202509281317586545.jpg
截图202509281318063515.jpg
截图202509281318158509.jpg

回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-9-28 13:23:00 | 显示全部楼层
您好,针对您描述的“电路板重新上电后,I2C初始化会卡死”的问题,结合您提到的场景(使用USB转TTL串口打印、单片机挂载两个I2C传感器、程序卡在I2C初始化处),我们可以从以下几个方面进行系统性分析与排查:

一、问题现象简述

在电路板重新上电(未断开串口线)的情况下,程序在I2C初始化阶段出现卡死现象。初步判断为I2C总线初始化过程中,主控制器(单片机)无法正确完成I2C通信的初始化流程,导致程序阻塞在初始化函数中。

二、可能原因分析

1. I2C总线处于非空闲状态(Bus Busy)
现象描述:I2C总线在复位或上电后未正确释放,导致SCL或SDA引脚被拉低,总线处于“Busy”状态。
可能原因:
上次断电时,某个从设备未正确释放总线。
某个从设备在上电后未能及时释放SDA/SCL,导致主设备无法拉高总线。
影响:主设备在初始化I2C模块时,检测到总线繁忙,无法进入正常工作模式,导致初始化失败或程序阻塞。

2. I2C从设备未正确复位或响应
现象描述:在单片机尝试初始化I2C通信时,从设备未正确响应ACK信号,导致主设备等待ACK超时。
可能原因:
从设备供电不稳定或上电顺序不当。
从设备地址配置错误或冲突。
从设备内部状态异常(如上次通信未完成、进入休眠状态等)。
影响:主设备在发送START信号或设备地址后收不到ACK,导致程序卡在等待ACK的循环中。

3. I2C引脚配置错误或硬件冲突
现象描述:I2C引脚(SCL/SDA)未正确配置为开漏输出或上拉电阻配置不当。
可能原因:
引脚误配置为推挽输出,导致总线拉高失败。
上拉电阻阻值过大或未接,导致总线无法稳定拉高。
引脚复用功能未正确使能。
影响:总线无法正常通信,主设备在初始化阶段检测到引脚状态异常,程序卡死。

4. I2C初始化代码逻辑问题
现象描述:初始化流程中存在未处理的异常情况,导致程序进入死循环。
可能原因:
初始化代码中未设置超时机制。
初始化流程中未清除I2C标志位(如BUSY、TXE、RXNE等)。
初始化顺序错误(如先使能I2C再配置GPIO)。
影响:主设备在初始化阶段无法跳出循环或进入错误状态,导致程序卡死。

三、排查建议

1. 使用示波器检查I2C总线状态
目的:确认SCL和SDA引脚在初始化前是否处于高电平,判断总线是否空闲。
建议操作:
上电后立即用示波器查看SCL和SDA波形。
观察是否存在持续拉低、毛刺、时序异常等问题。

2. 检查I2C从设备状态
目的:确认从设备是否正常响应,地址是否冲突。
建议操作:
使用I2C扫描工具(如I2C Scanner)扫描总线地址。
单独测试每个从设备,排除设备冲突或故障。

3. 检查I2C引脚配置
目的:确保引脚配置为开漏输出,并接有合适的上拉电阻。
建议操作:
检查GPIO配置是否为开漏输出。
检查是否外接上拉电阻(通常为4.7kΩ~10kΩ)。
确保I2C复用功能已正确使能。

4. 检查初始化代码逻辑
目的:排查初始化流程中是否存在死循环或未处理异常。
建议操作:
检查是否设置了超时机制(如使用HALI2CInit()时,是否启用了超时)。
检查是否在初始化前清除了BUSY标志位。
检查是否在初始化前正确配置了GPIO、时钟、I2C参数等。

5. 尝试软件复位I2C模块
目的:在初始化前强制复位I2C模块,释放总线。
建议操作:
在初始化前调用HALI2CDeInit()或直接操作寄存器复位I2C模块。
重新配置并初始化I2C模块。

四、解决方案建议

方案一:硬件层面处理总线复位
操作方法:
在I2C初始化前,强制将SDA和SCL引脚拉高一段时间(如通过GPIO模拟)。
或者使用一个MOSFET控制SDA/SCL的上拉电源,初始化前短暂断开再恢复。
优点:可强制释放总线,避免总线卡死。
缺点:需额外硬件支持,增加设计复杂度。

方案二:软件层面添加总线恢复机制
操作方法:
在初始化I2C前,检测总线状态,若发现总线繁忙,尝试发送9个时钟周期(模拟SCL),强制从设备释放SDA。
示例代码(模拟SCL):
   
  1. c
  2.     void I2CBusRecover(void) {
  3.         int i;
  4.         GPIOInitTypeDef GPIOInitStruct = {0};
  5.         // 将SCL和SDA配置为输出模式
  6.         GPIOInitStruct.Pin = SCLPIN | SDAPIN;
  7.         GPIOInitStruct.Mode = GPIOMODEOUTPUTOD;
  8.         GPIOInitStruct.Pull = GPIONOPULL;
  9.         GPIOInitStruct.Speed = GPIOSPEEDFREQHIGH;
  10.         HALGPIOInit(GPIOPORT, &GPIOInitStruct);
  11.         // 拉高SDA
  12.         HALGPIOWritePin(GPIOPORT, SDAPIN, GPIOPINSET);
  13.         // 发送9个SCL脉冲
  14.         for(i = 0; i < 9; i++) {
  15.             HALGPIOWritePin(GPIOPORT, SCLPIN, GPIOPINRESET);
  16.             Delayus(5);
  17.             HALGPIOWritePin(GPIOPORT, SCLPIN, GPIOPINSET);
  18.             Delayus(5);
  19.         }
  20.         // 发送STOP信号
  21.         HALGPIOWritePin(GPIOPORT, SDAPIN, GPIOPINRESET);
  22.         Delayus(5);
  23.         HALGPIOWritePin(GPIOPORT, SCLPIN, GPIOPINSET);
  24.         Delayus(5);
  25.         HALGPIOWritePin(GPIOPORT, SDAPIN, GPIOPINSET);
  26.         Delayus(5);
  27.         // 恢复为I2C功能
  28.         // ...
  29.     }
复制代码
优点:无需额外硬件,适用于大多数I2C接口问题。
缺点:需要额外代码逻辑,增加初始化时间。

五、总结

电路板重新上电后I2C初始化卡死的问题,通常是由以下几种原因引起:

1. I2C总线未正确释放,处于Busy状态;
2. 从设备未正确响应,导致主设备等待ACK超时;
3. I2C引脚配置错误或上拉电阻缺失;
4. 初始化代码逻辑存在缺陷,未处理异常情况。

建议您结合硬件和软件两个层面进行排查。优先使用示波器观察总线状态,确认是否总线异常;其次检查从设备地址和响应情况;最后优化初始化代码逻辑,加入超时和总线恢复机制。

如需进一步分析,建议上传具体的I2C初始化代码段、硬件连接图以及使用的单片机型号,以便更有针对性地定位问题。

祝您问题早日解决!

如有更多技术问题,欢迎继续交流。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:585
  • 最近打卡:2025-10-16 07:20:54
已绑定手机

86

主题

6274

回帖

1万

积分

超级版主

积分
11738
发表于 2025-9-29 22:04:34 | 显示全部楼层
可能是通过串口供电了,断电不彻底
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 08:12 , Processed in 0.120984 second(s), 62 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表