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

Orange Pi Zero 2与PI4IOE5V96248 I2C扩展板引脚映射异常排查

PI4IOE5V96248 I2C扩展板引脚映射异常问题排查

我使用Orange Pi Zero 2搭配PI4IOE5V96248 48位I/O扩展板(I2C通信),编写了以下Python代码,但出现引脚映射异常:输入LED1时实际点亮引脚9,输入LED48时实际点亮引脚40,且LED1-8完全无法工作。调整状态计算逻辑后有时会出现所有LED熄灭的情况,当前代码仅能驱动LED9-48。

原代码

import smbus
import time

bus = smbus.SMBus(3)
slave_address = 0x20

def set_led_state(states):
    try:
        bus.write_i2c_block_data(slave_address, 0x00, states)
        print("Address acknowledgment: Received")
        print("Data byte acknowledgment: Received")
        print(f"Address byte sent: 0x{slave_address:02X}")
        print(f"Data bytes sent: {[f'0x{s:02X}' for s in states]}")
    except IOError:
        print("Address acknowledgment: Not received")
        print("Data byte acknowledgment: Not received")

# Define LED states
LED_OFF = 0x00
LED_1 = 0x01
LED_2 = 0x02
LED_3 = 0x04
LED_4 = 0x08
LED_5 = 0x10
LED_6 = 0x20
LED_7 = 0x40
LED_8 = 0x80

# Prompt the user to select an LED
def prompt_led_selection():
    led = int(input("Enter the LED number (1-48) to switch on (0 to exit): "))
    if led == 0:
        return None
    elif led < 1 or led > 48:
        print("Invalid LED number. Please try again.")
        return prompt_led_selection()
    else:
        return led

# Repeat the LED selection until the user chooses to exit (0)
while True:
    selected_led = prompt_led_selection()
    if selected_led is None:
        break

    # Calculate the LED state based on the selected LED number
    state_index = (selected_led - 1) // 8
    bit_position = (selected_led - 1) % 8

    # Create an array of LED states
    states = [LED_OFF] * 6
    states[state_index] = 0x01 << bit_position

    set_led_state(states)

    # Print the selected LED number
    print(f"LED {selected_led} switched ON")
    time.sleep(0.1)  # Delay for 2 seconds

# Turn off all LEDs
set_led_state([LED_OFF] * 6)
print("All LEDs are OFF")

数据手册说明

写入操作时,主设备(微控制器)先寻址从设备,将包含从地址字节的最后一位置为逻辑0以进入写入模式。PI4IOE5V96248会发出应答,随后主设备发送第一个数据字节对应IO0_7至IO0_0。该字节得到应答后,主设备发送第二个数据字节对应IO1_7至IO1_0,以此类推。


问题根源分析

  1. 写入了只读的输入寄存器:PI4IOE5V96248的0x00-0x05是输入寄存器(只读),写入操作完全无效。原代码中bus.write_i2c_block_data(slave_address, 0x00, states)将数据写入输入寄存器,直接导致LED1-8(对应PORT0)无法响应。
  2. 输出寄存器地址错误:该芯片的输出寄存器起始地址为0x06(对应PORT0),后续PORT1-PORT5的输出寄存器地址依次是0x07-0x0B。原代码的写入地址完全偏离了输出控制区域,这是部分引脚错位的核心原因。
  3. 未配置端口为输出模式:PI4IOE5V96248的配置寄存器(0x12-0x17)默认值为0xFF(所有引脚设为输入模式)。即使写入正确的输出寄存器,若未将端口配置为输出,引脚也无法驱动LED。
  4. 位序与手册要求反转:数据手册明确第一个数据字节对应IO0_7至IO0_0,即字节的最高位(bit7)对应IO0_7,最低位(bit0)对应IO0_0。但原代码用0x01 << bit_position将bit0对应IO0_0,导致LED编号与实际引脚错位。

修正后的代码示例

import smbus
import time

bus = smbus.SMBus(3)
slave_address = 0x20

# 寄存器地址定义
OUTPUT_PORT_BASE = 0x06
CONFIG_PORT_BASE = 0x12

def init_expander():
    # 将所有6个端口配置为输出模式(写入0x00到配置寄存器)
    try:
        bus.write_i2c_block_data(slave_address, CONFIG_PORT_BASE, [0x00]*6)
        print("扩展板端口已配置为输出模式")
    except IOError:
        print("配置扩展板失败")

def set_led_state(states):
    try:
        # 写入输出寄存器,起始地址为OUTPUT_PORT_BASE
        bus.write_i2c_block_data(slave_address, OUTPUT_PORT_BASE, states)
        print(f"输出数据已发送: {[f'0x{s:02X}' for s in states]}")
    except IOError:
        print("发送数据失败")

def prompt_led_selection():
    led = int(input("Enter the LED number (1-48) to switch on (0 to exit): "))
    if led == 0:
        return None
    elif led < 1 or led > 48:
        print("Invalid LED number. Please try again.")
        return prompt_led_selection()
    else:
        return led

# 初始化扩展板端口为输出
init_expander()

while True:
    selected_led = prompt_led_selection()
    if selected_led is None:
        break

    port_index = (selected_led - 1) // 8
    bit_position = (selected_led - 1) % 8
    # 反转位序,匹配手册中IOx_7对应字节bit7的要求
    reversed_bit = 7 - bit_position

    states = [0x00] * 6
    states[port_index] = 0x01 << reversed_bit

    set_led_state(states)
    print(f"LED {selected_led} switched ON")
    time.sleep(0.1)

# 关闭所有LED
set_led_state([0x00] * 6)
print("All LEDs are OFF")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:24:58