[开发工具] I2C 读写,不产生停止信号

[复制链接]
76|31
刮台风就会有人g 发表于 2026-7-18 15:43 | 显示全部楼层
如果是STM32的硬件I2C,建议在初始化时开启DMA模式。PIO模式在中断响应慢的时候容易丢时序,导致控制器状态机错乱。DMA模式下,数据传输由硬件自动完成,最后自动产生STOP信号,稳定性比中断模式高很多
喂什么玩意 发表于 2026-7-18 21:16 | 显示全部楼层
有些从设备对时序要求很严,特别是那种老式的EEPROM。如果你用的是硬件I2C,记得配置CR2寄存器里的AUTOEND位。如果这个位没置位,传输完NBYTES个字节后硬件会自动停在ACK/NACK阶段等待你手动发STOP,这时候总线就会挂起
感觉很反感mva 发表于 2026-7-19 08:03 | 显示全部楼层
我也遇到过类似情况,后来发现是时钟拉伸的问题。如果从设备在处理数据时拉低了SCL,而主设备的超时设置太短,可能会导致通信异常终止但没有正确的STOP信号。试着把I2C的Timeout参数改大一点,或者用示波器抓一下SCL有没有被从设备强行拉低
合同圣诞节fy 发表于 2026-7-20 11:04 | 显示全部楼层
看你发的图,Setup Write之后有个奇怪的脉冲。这可能是总线上的噪声或者是上拉电阻太小导致的振铃。I2C总线的上拉电阻一般建议用4.7k或10k,如果电阻太小,GPIO驱动能力不足,电平翻转就会出问题,导致控制器误判
很过分好的suj 发表于 2026-7-22 09:02 | 显示全部楼层
还有一个可能,就是你的代码里是不是调用了HAL_I2C_Mem_Write这种带内存地址的函数?这种函数内部会先发地址再发数据,如果中间的时序配合不好,可能会在发完内存地址后卡住。试着拆分成两次操作:先发Start+地址,再发数据,看看能不能正常出STOP
烟雨蒙蒙520 发表于 2026-7-22 11:38 | 显示全部楼层
如果是多主机环境,或者有多个从设备挂在总线上,要注意仲裁丢失的问题。如果总线上有其他设备在同时发送数据,你的控制器可能会检测到仲裁丢失而自动停止发送,这时候就不会有正常的STOP信号,而是直接释放总线
发货后已经wi 发表于 2026-7-22 19:45 | 显示全部楼层
检查一下你的I2C速度配置。标准模式100kHz和快速模式400kHz对上升时间的要求不一样。如果你的硬件电路寄生电容比较大,跑400kHz时上升沿太缓,可能会被误判为总线忙,从而导致控制器状态机卡死在不发STOP的状态
哈根达斯uz 发表于 2026-7-22 20:53 | 显示全部楼层
有些从设备在接收到错误指令后会锁死总线,这时候需要主设备发送至少9个SCL脉冲来复位从设备的状态机,然后再发STOP。你可以试试在出错后手动模拟一段时钟信号,看看能不能恢复通信
广告商宝宝xx 发表于 2026-7-23 16:31 | 显示全部楼层
如果是调试阶段,建议先别用复杂的库函数,直接操作寄存器写一个简单的I2C发送流程。比如直接写DR寄存器发数据,然后检查ISR寄存器的TC位,确认传输完成后再手动置位CR2的STOP位。这样能排除掉库函数封装带来的干扰,定位到底是硬件问题还是软件逻辑问题
天天向善 发表于 2026-7-24 08:50 | 显示全部楼层
软件模拟I2C灵活,可随时发送停止信号,但会占用CPU和时钟资源。
lllook 发表于 2026-7-27 18:34 | 显示全部楼层
调整I2C传输至DMA模式,设置传输字节数,完成回调中无需停止I2C。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
0