You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TSL2591 I2C通信异常:返回寄存器地址而非有效数据求助

问题排查:I2C读取TSL2591返回寄存器地址而非预期值

问题描述

作为学院项目的一部分,在Vivado中基于PYNQ Z2 FPGA使用System Verilog编写I2C协议。代码通过仿真后,连接TSL2591设备,FPGA内部ILA观测到协议流程符合预期、设备正常应答,但读取特定寄存器时出现异常:

  • 读取设备ID寄存器0X12时,返回值始终为0X12而非预期的0X50
  • 读取测量数据寄存器0X14时,返回值为0X14
  • 已在写入使能命令至寄存器0X00后等待200ms再执行读取,且读取流程包含重启操作
  • 尝试8位或16位读取,16位读取时MSB为0,LSB仍为寄存器地址

可能的原因及排查步骤

1. I2C读写方向位错误

TSL2591的7位I2C地址为0x29,完整的帧首字节是7位地址 + 1位方向位:

  • 写操作:0x29 << 1 | 0 → 0x52
  • 读操作:0x29 << 1 | 1 → 0x53
    检查代码中,发送寄存器地址后的**重启(Repeated Start)**阶段,是否正确将方向位切换为读。如果重启后仍发送写方向地址,设备会把后续读操作当成写指令,返回的其实是你发送的寄存器地址回显。

2. 寄存器地址发送后的ACK处理错误

发送完目标寄存器地址后,必须等待设备的ACK应答(SDA拉低)。如果代码在设备返回ACK前就切换到读模式,或者错误发送了NACK,设备会无法正确接收寄存器地址,后续读取的就是无效的残留数据(刚好是你发送的地址值)。
用ILA重点观测:

  • 发送寄存器地址0x12后,设备是否返回了有效ACK
  • 重启信号发送后,读地址的ACK是否正常

3. TSL2591寄存器访问模式配置错误

TSL2591的寄存器地址为7位,发送的8位地址字节最高位决定访问模式:最高位为1是连续访问,为0是单次访问。如果代码错误地直接发送8位寄存器地址(比如把0x12作为完整字节发送),会导致设备解析的寄存器地址错误,返回异常数据。
检查代码中对寄存器地址的位宽处理逻辑,确认发送的是正确的7位地址+访问模式位组合。

4. I2C时钟时序不达标

TSL2591最高支持400kHz I2C时钟,若代码生成的时钟频率过高,或高/低电平时间不符合规范,设备无法正确解析指令。用ILA测量SCL的电平宽度:

  • 标准模式(100kHz):高电平≥4.7μs,低电平≥4.0μs
  • 快速模式(400kHz):高电平≥0.6μs,低电平≥1.3μs

5. 读数据阶段采样时序错误

I2C规范要求在SCL上升沿采样SDA数据。如果代码在下降沿或其他时刻采样,会捕捉到设备未准备好的残留信号,刚好是之前发送的寄存器地址。检查代码中锁存SDA数据的逻辑,确认采样时机正确。

6. 硬件隐性问题

即使ILA显示协议正常,仍需排查硬件:

  • SDA/SCL线路是否接了4.7kΩ上拉电阻(PYNQ Z2部分I2C引脚无自带上拉,需外接)
  • TSL2591的电源是否为3.3V,VCC/GND连接是否牢固
  • 引脚映射是否正确:确认SDA/SCL对应PYNQ Z2的I2C专用引脚

快速验证建议

  1. 先用PYNQ自带的Python I2C库连接TSL2591,确认硬件和设备本身能正常读取寄存器值
  2. 用ILA捕获完整读操作时序,和TSL2591数据手册的时序图逐帧对比,重点核对起始/重启信号、字节发送、ACK应答、读数据阶段的时序细节

内容的提问来源于stack exchange,提问作者leonid g

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:32:47