2. 光模块I2C寄存器读写自动化测试
任务目标
通过 I2C 总线访问光模块的 A0h 页寄存器:读取厂商信息(地址 20h–35h)、波长(60h–61h)、温度(96h–97h),并向用户可写寄存器(如 62h–63h)写入一个值后回读,确认写入与回读一致。
环境与依赖
- Python 3.8+,安装
smbus2:pip install smbus2 - Linux 主机已加载
i2c-dev,光模块挂在某条 I2C 总线上(示例用/dev/i2c-1,模块地址0x50) - 用
i2cdetect -y 1确认模块地址可见后再运行
寄存器约定
- 厂商信息:20h–35h,ASCII 字符串
- 波长:60h–61h,大端 16 位,单位 nm
- 温度:96h–97h,有符号 16 位,分辨率 1/256 ℃
- 可写测试寄存器:62h–63h(用户 EEPROM 区),大端 16 位
完整实现
import time
from smbus2 import SMBus
BUS = 1
ADDR = 0x50
def read_bytes(bus, addr, reg, n):
return bus.read_i2c_block_data(addr, reg, n)
def write_word(bus, addr, reg, value):
bus.write_i2c_block_data(addr, reg, [(value >> 8) & 0xFF, value & 0xFF])
def read_word(bus, addr, reg):
d = bus.read_i2c_block_data(addr, reg, 2)
return (d[0] << 8) | d[1]
def read_vendor(bus, addr):
raw = read_bytes(bus, addr, 0x20, 0x16)
return bytes(raw).decode("ascii", errors="replace").strip()
def read_wavelength(bus, addr):
return read_word(bus, addr, 0x60)
def read_temperature(bus, addr):
raw = read_word(bus, addr, 0x96)
if raw >= 0x8000:
raw -= 0x10000
return raw / 256.0
def write_and_verify(bus, addr, reg, value):
write_word(bus, addr, reg, value)
time.sleep(0.05)
got = read_word(bus, addr, reg)
return got, got == value
def main():
with SMBus(BUS) as bus:
vendor = read_vendor(bus, ADDR)
wl = read_wavelength(bus, ADDR)
temp = read_temperature(bus, ADDR)
print(f"Vendor : {vendor}")
print(f"Wavelength: {wl} nm")
print(f"Temperature: {temp:.2f} C")
test_val = 0x5A5A
got, ok = write_and_verify(bus, ADDR, 0x62, test_val)
print(f"Write 0x{test_val:04X} -> read 0x{got:04X} : {'PASS' if ok else 'FAIL'}")
if __name__ == "__main__":
main()
运行与验证
- 运行:
python i2c_test.py - 观察输出:厂商字符串应为可读 ASCII;波长应为合理数值(如 1310 nm);温度应在环境温度附近。
- 写入回读行显示
PASS即表示 62h–63h 写入值与回读值一致,写入验证通过。 - 若
i2cdetect看不到 0x50,或运行报OSError,先检查接线、总线号与模块供电。