3. EPD 硬件接口解析:SPI 接口时序、数据/命令控制、忙检测与复位时序

电子纸(EPD)显示驱动芯片与主控处理器之间的物理通信链路,是 FrameBuffer 驱动能够正常工作的硬件基础。本章将深入解析 EPD 硬件接口的四个核心要素:SPI 总线时序、数据/命令(D/C#)控制、忙检测(Busy)引脚以及复位(RST)时序。理解这些接口的电气特性和时序要求,是编写稳定、高效的 EPD 驱动的第一步。

3.1 EPD 硬件接口架构概览

典型的 EPD 模组与主控 SoC 之间的连接,通常包含以下信号线:

信号名称 方向 功能描述
SCLK (SPI Clock) 主控 → EPD SPI 串行时钟,由主控提供,决定数据传输速率
MOSI (Master Out Slave In) 主控 → EPD 主控输出数据线,用于发送命令和数据
MISO (Master In Slave Out) EPD → 主控 从设备输出数据线,部分 EPD 用于读取状态或寄存器
CS# (Chip Select) 主控 → EPD 片选信号,低电平有效,选中 EPD 芯片进行通信
D/C# (Data/Command) 主控 → EPD 数据/命令选择:高电平表示数据,低电平表示命令
BUSY (Busy) EPD → 主控 忙状态指示:高电平表示芯片正忙,低电平表示空闲
RST# (Reset) 主控 → EPD 硬件复位信号,低电平有效,用于初始化芯片
接口选型提示: 大多数 EPD 驱动芯片(如 IT8951、SSD1680、UC8151)使用 3.3V 逻辑电平。与主控 SoC(如 1.8V 的 i.MX 或 RK 系列)连接时,必须使用电平转换器(如 TXS0108E)或确保 SoC 引脚兼容 3.3V 输入。
EPD 硬件接口连接框图 主控 SoC (i.MX / RK / STM32) SPI 控制器 GPIO (D/C#, RST#) GPIO (BUSY 输入) EPD 模组 (IT8951 / SSD1680) SPI 从设备 命令/数据缓冲 时序控制器 (TCON) SCLK MOSI CS# D/C# RST# BUSY

3.2 SPI 接口时序详解

EPD 驱动芯片通常支持 SPI Mode 0(CPOL=0, CPHA=0)或 SPI Mode 3(CPOL=1, CPHA=1)。在 Mode 0 下,时钟空闲时为低电平,数据在时钟上升沿采样;在 Mode 3 下,时钟空闲时为高电平,数据在时钟上升沿采样。绝大多数 EPD 驱动芯片默认使用 SPI Mode 0。

3.2.1 SPI 时序参数要求

不同 EPD 驱动芯片对 SPI 时钟频率和时序有严格要求。以下为常见芯片的典型参数:

参数 符号 最小值 典型值 最大值 单位
SPI 时钟频率 f_SCLK - 10 20 MHz
时钟高电平时间 t_CLKH 25 50 - ns
时钟低电平时间 t_CLKL 25 50 - ns
CS# 建立时间 t_CSS 20 50 - ns
CS# 保持时间 t_CSH 20 50 - ns
数据建立时间 t_DSU 10 20 - ns
数据保持时间 t_DHD 10 20 - ns
时序风险提示: 当主控 SoC 的 SPI 时钟频率超过 EPD 芯片的最大额定值时,可能导致数据采样错误、命令解析失败,甚至芯片锁死。建议在驱动初始化阶段,将 SPI 时钟配置为 10 MHz 或更低,待验证通信稳定后再逐步提高。
SPI Mode 0 (CPOL=0, CPHA=0) 时序图 CS# t_CSS t_CSH SCLK MOSI D7 D6 D5 D4 D3 D2 D1 D0 数据在时钟上升沿采样 (红色虚线指示采样点)

3.3 数据/命令控制(D/C# 引脚)

D/C# 引脚是 EPD 驱动芯片区分 SPI 总线上传输的是 命令 还是 数据 的关键信号。其逻辑电平定义如下:

  • 低电平(0):表示当前 SPI 传输的是 命令(Command),例如初始化配置、寄存器写入、刷新触发等。
  • 高电平(1):表示当前 SPI 传输的是 数据(Data),例如图像像素数据、查找表(LUT)内容等。

3.3.1 命令/数据发送流程

在驱动中,发送命令和数据的典型流程如下:

  1. 拉低 CS#:选中 EPD 芯片。
  2. 设置 D/C# 为低电平:指示接下来发送的是命令。
  3. 通过 SPI 发送命令字节:例如 0x01(软件复位)或 0x10(写入配置)。
  4. 设置 D/C# 为高电平:指示接下来发送的是数据。
  5. 通过 SPI 发送数据字节:例如配置参数或图像数据。
  6. 拉高 CS#:结束本次通信。
驱动实现示例: 在 Linux 内核驱动中,通常使用 gpiod_set_value() 控制 D/C# 引脚,使用 spi_write() 或 spi_write_then_read() 进行 SPI 数据传输。
/* 发送命令 */
static void epd_send_command(struct spi_device *spi, uint8_t cmd)
{
    /* 设置 D/C# 为低电平(命令模式) */
    gpiod_set_value(epd->dc_gpio, 0);
    /* 发送命令字节 */
    spi_write(spi, &cmd, 1);
}

/* 发送数据 */
static void epd_send_data(struct spi_device *spi, const uint8_t *data, size_t len)
{
    /* 设置 D/C# 为高电平(数据模式) */
    gpiod_set_value(epd->dc_gpio, 1);
    /* 发送数据 */
    spi_write(spi, data, len);
}

3.4 忙检测(Busy 引脚)

EPD 驱动芯片在执行内部操作(如刷新显示、初始化、查找表加载)时,会通过 BUSY 引脚向主控报告其工作状态。正确使用忙检测是防止驱动向芯片发送无效命令、避免通信冲突的关键。

3.4.1 Busy 引脚电平定义

BUSY 电平 芯片状态 驱动行为
高电平(1) 芯片正忙(Busy),正在执行内部操作 驱动应等待,不得发送新命令或数据
低电平(0) 芯片空闲(Idle),可以接收新命令 驱动可以继续发送命令或数据

3.4.2 忙检测实现策略

在驱动中,忙检测通常采用 轮询(Polling) 或 中断(Interrupt) 两种方式:

  • 轮询方式:在发送命令后,循环读取 BUSY 引脚电平,直到检测到低电平。适用于简单场景,但会占用 CPU。
  • 中断方式:将 BUSY 引脚配置为上升沿/下降沿触发的中断,在中断处理函数中唤醒等待队列。效率更高,适合多任务系统。
轮询超时处理: 在轮询忙检测时,务必设置超时机制。例如,EPD 刷新操作可能持续 500ms 至 2s,如果超过 5s 仍未检测到空闲状态,应视为芯片异常,执行复位或报错。
/* 轮询等待芯片空闲,带超时 */
static int epd_wait_idle(struct epd_device *epd, unsigned long timeout_ms)
{
    unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);

    while (time_before(jiffies, timeout)) {
        if (gpiod_get_value(epd->busy_gpio) == 0) {
            return 0; /* 芯片空闲 */
        }
        usleep_range(1000, 2000); /* 每 1-2ms 轮询一次 */
    }
    dev_err(&epd->spi->dev, "Busy wait timeout!\n");
    return -ETIMEDOUT;
}

3.5 复位时序(RST# 引脚)

硬件复位是 EPD 驱动芯片初始化的第一步。正确的复位时序可以确保芯片内部状态机、寄存器和存储器处于已知的初始状态。

3.5.1 复位时序要求

典型的 EPD 复位时序包含以下步骤:

  1. 拉低 RST#:将复位引脚置为低电平,持续至少 10 µs(具体值参考芯片数据手册)。
  2. 保持低电平:确保芯片内部复位逻辑完成。
  3. 拉高 RST#:释放复位,芯片开始执行内部初始化。
  4. 等待初始化完成:通过 BUSY 引脚检测芯片是否进入空闲状态。
参数 符号 最小值 典型值 单位
复位低电平脉冲宽度 t_RST_LOW 10 50 µs
复位后等待时间 t_RST_WAIT 10 50 ms
初始化完成时间 t_INIT 100 500 ms
EPD 复位时序图 RST# t_RST_LOW (≥10µs) BUSY t_INIT (芯片初始化中) 空闲 (Idle) t0 t1 t2 t

3.6 接口调试常见问题与排查

在 EPD 驱动开发过程中,硬件接口问题是最常见的故障来源。以下为典型问题及排查方法:

← 上一章📖 返回目录下一章 →
现象 可能原因 排查方法
SPI 通信无响应 SCLK 极性/相位错误;CS# 未正确拉低;电平不匹配 使用逻辑分析仪抓取 SPI 波形,验证 Mode 0/3;检查电平转换
命令发送后芯片无反应 D/C# 时序错误;复位不充分;芯片处于忙状态 检查 D/C# 电平切换时序;执行完整复位流程;等待 BUSY 释放