PAYATHON 2026

Raspberry Pi 用 .NET 驱动 PCF8574 LCD 出现 Error 121

数据小许

结论

Error 121 表示底层 I²C 数据传输失败。先确认 Raspberry Pi 与 PCF8574 能否通信,再检查 LCD 初始化和引脚映射。即使地址正确、I²C 已启用,也不能说明每次传输都能成功。

在使用 i2c-bcm2835 驱动的系统上,控制器报告应答错误时,驱动会返回 EREMOTEIO,通常表示设备没有正常应答。错误的具体含义还需结合实际使用的控制器驱动判断。Linux 驱动源码

现有材料不足以确定 WPI410、HW-61 或 .NET 代码中的哪一项导致了故障,也没有异常堆栈来判断具体在哪一步失败。

1. 先检查电平转换器两侧的供电

通过两个独立的 Wago 端子分配 5V 和 GND,接线关系本身没有明显矛盾。还需检查实际电压和接触情况,并确认电平转换器是否按要求接入了两侧参考电源。

断电核对接线后,上电测量:

  • HW-61 的 VCC 与 GND 之间是否有稳定的 5V。
  • WPI410 的高压侧参考电源是否按模块说明接到 5V。
  • WPI410 的低压侧参考电源是否按模块说明接到 Raspberry Pi 的 3.3V。
  • Raspberry Pi、外部 PSU、WPI410 和 HW-61 的 GND 是否实际导通。
  • SDA、SCL 是否分别经过转换器的对应通道,有无接反、松动或虚焊。

原描述提到了给 WPI410 提供 5V,但没有详细说明低压侧参考电源的接法,应单独核实。具体端子名称和供电要求以 WPI410 的说明为准,不能仅凭模块名称推断。

Raspberry Pi 的 GPIO 使用 3.3V 电平,不能直接承受 5V。测量时要特别确认 Raspberry Pi 一侧的 SDA、SCL 没有被拉到 5V。Raspberry Pi 硬件文档

2. 检查上拉电平和总线速度

I²C 的 SDA、SCL 需要合适的上拉。先检查 HW-61 和电平转换器是否已有上拉电阻,以及上拉接到了哪一路电源,再考虑是否需要增加电阻。

以 TI PCF8574 为例,输入高电平最低要求为 0.7 × VCC。当 VCC = 5V 时,这相当于 3.5V,因此不能保证直接输入 3.3V 就能可靠工作。该器件规定的最高 I²C 时钟频率为 100 kHz;如果实际芯片来自其他厂商,应核对对应的数据手册。TI PCF8574 数据手册

总线空闲时,检查低压侧 SDA、SCL 是否接近 3.3V,高压侧是否达到对应的上拉电压。如果某条线持续为低电平,优先检查是否存在短路、接反、转换器供电问题,或设备拉低总线。万用表只能帮助判断静态电平;间歇性故障需要用示波器或逻辑分析仪观察波形与 ACK。

3. 确认程序使用的总线和地址

如果系统已安装 i2c-tools,先查看适配器:

i2cdetect -l

确认 busId: 1 对应实际接线使用的总线。停止显示应用并确认目标是 PCF8574 后,可以只探测目标地址:

i2cdetect -y 1 0x27 0x27

判断结果时注意:

  • 显示 27:这次探测获得了响应,仍需验证实际读写是否稳定。
  • 显示 --:这次探测没有获得响应,应继续检查接线、供电和地址。
  • 显示 UU:通常表示该地址已被内核驱动占用,需要先确认对应驱动。

I2cConnectionSettings 使用的是 7 位设备地址。如果实际地址确实为 0x27,就保留 0x27,不要为了加入读写位而自行左移。

4. 暂时移除 LCD 层,执行最小读取测试

先让 PCF8574 独立完成 I²C 事务。以下示例使用现有项目中的 System.Device.I2c,不创建 Pcf8574、GpioController 或 Lcd1602:

using System;
using System.Device.I2c;
using System.IO;
using System.Threading;

try
{
    var settings = new I2cConnectionSettings(
        busId: 1,
        deviceAddress: 0x27);

    using var device = I2cDevice.Create(settings);

    for (int i = 0; i < 10; i++)
    {
        byte value = device.ReadByte();
        Console.WriteLine($"Read {i + 1}: 0x{value:X2}");
        Thread.Sleep(50);
    }
}
catch (IOException ex)
{
    Console.Error.WriteLine(ex);
}

这里读取的是 PCF8574 的端口状态,不是 LCD 字符,也不应预设一定会返回某个固定值。

如果测试也报 Error 121,说明故障可以在不经过 LCD 初始化的情况下复现,应继续排查总线、供电、地址和转换器。如果读取成功,只能证明这些读事务成功;LCD 初始化涉及的写事务和时序仍需检查。

5. 根据异常位置检查 LCD 配置

在原代码各个初始化阶段的前后增加日志,确认异常发生在创建 Pcf8574、创建 Lcd1602、Clear() 还是 Write()。创建 I2cDevice 成功不代表设备已经应答。

异常日志可以改为:

_logger.LogError(ex, "Display initialization failed");

原代码配置的扩展端口映射为:

PCF8574 端口LCD 信号
P0RS
P1R/W
P2E
P3背光控制
P4 至 P7D4 至 D7

这些数字指的是 PCF8574 的端口编号。需要对照 HW-61 的实际走线或原理图验证,不能仅凭转接板型号认定映射一致。

如果 PCF8574 通信稳定,但 LCD 仍然空白或乱码,再检查上述映射、焊点、对比度,以及显示屏控制器与 Lcd1602 的兼容性。当前没有提供显示屏控制器资料,不能直接断言该驱动完全匹配。

完成修正后,分别验证最小 I²C 测试和原显示程序。若错误仍然存在,可以结合异常堆栈、两侧实测电压以及失败事务的 ACK 波形,进一步缩小原因范围。

备注:内容仅供参考。