4. 8080并行接口详解:控制线与数据线的实战密码
8080并行接口,说白了就是单片机与LCD之间最经典的高速公路。我最早接触它是在做一款工业手持设备时,那时候选型手册上写着“8080 8-bit parallel”,我还以为是什么古董协议。结果一查,这玩意儿到今天还在大量使用——稳定、简单、够快。
这一章,咱们就把8080接口的每根线、每个时序参数掰开揉碎。你想想看,搞懂了这些,以后调屏再也不会一脸懵。
4.1 接口信号线:谁负责什么,心里要有数
8080接口的信号线可以分为两大类:控制线和数据线。控制线是“指挥官”,数据线是“士兵”。
| 信号名 | 方向 | 功能描述 |
|---|---|---|
| CS (Chip Select) | MCU → LCD | 片选信号,低电平有效。只有CS拉低时,LCD才会响应其他控制信号。 |
| RS (Register Select) | MCU → LCD | 寄存器选择。RS=0 写命令/读状态;RS=1 写数据/读数据。 |
| RD (Read) | MCU → LCD | 读使能,低电平有效。拉低时LCD将数据放到数据总线上。 |
| WR (Write) | MCU → LCD | 写使能,低电平有效。拉低时MCU将数据写入LCD。 |
| RST (Reset) | MCU → LCD | 复位信号,低电平有效。拉低至少10us后释放,完成硬件复位。 |
| DB0~DB7 (Data Bus) | 双向 | 8位并行数据总线。16位接口则扩展到DB0~DB15。 |
4.2 控制线的“性格”与实战接法
4.2.1 CS:片选,别让它悬空
CS是接口的“门禁”。只有CS拉低,LCD才会“开门”接收指令。如果CS一直拉高,你折腾RD、WR都没用。
我在项目中遇到过一个问题:屏幕偶尔不响应,查了半天发现CS引脚虚焊。嗯,这种低级错误最坑人。
4.2.2 RS:命令还是数据?就靠它
RS这根线决定了数据总线上传输的是“命令”还是“数据”。
- RS = 0:写命令(比如设置显示坐标、初始化参数)或读状态(比如读忙标志)。
- RS = 1:写数据(比如像素颜色值)或读数据(比如读GRAM内容)。
你想想看,如果RS接反了,你写进去的命令会被当成数据,屏幕显示肯定乱套。我见过有人把RS和WR接反,结果屏幕死活不亮——查了两天才发现。
4.2.3 RD与WR:读写的“心跳”
RD和WR是接口的“节拍器”。它们决定了数据什么时候被读取、什么时候被写入。
- WR写操作流程:MCU先把数据放到DB总线上,然后拉低WR。LCD在WR上升沿锁存数据。
- RD读操作流程:MCU拉低RD,LCD把数据放到DB总线上。MCU在RD上升沿读取数据。
这里有个关键点:RD和WR不能同时为低。如果同时拉低,LCD会进入不确定状态。我早期做项目时,时序写错了,RD和WR重叠了100ns,结果屏幕花屏。后来加了延时才解决。
4.2.4 RST:复位,别偷懒
RST是硬复位。上电后,MCU必须给RST一个低电平脉冲(通常≥10us),然后释放。LCD内部寄存器会恢复到默认值。
4.3 数据线:8位还是16位?这是个问题
数据线DB0~DB7(或DB0~DB15)是并行传输的“主干道”。位数越多,单次传输的数据量越大,但引脚也越多。
| 接口宽度 | 数据线数量 | 单次传输数据量 | 典型应用场景 |
|---|---|---|---|
| 8位 | 8根 (DB0~DB7) | 1字节 | 低端MCU、引脚紧张、刷新率要求不高 |
| 16位 | 16根 (DB0~DB15) | 2字节 | 高性能MCU、高刷新率、大尺寸屏幕 |
我个人习惯:如果MCU引脚够用,优先选16位。为什么?因为一次传2个字节,刷屏速度直接翻倍。但要注意,16位模式下,数据线的顺序不能接错——DB0对DB0,DB1对DB1,错一根就全乱。
4.4 时序参数分析:快慢之间见真章
时序参数是8080接口的灵魂。你写代码时,每个信号的建立时间、保持时间、脉冲宽度都必须满足LCD数据手册的要求。
4.4.1 核心时序参数
| 参数符号 | 参数名称 | 典型值 (8位模式) | 说明 |
|---|---|---|---|
| tcyc | 写周期时间 | ≥ 100ns | 两次写操作之间的最小间隔 |
| tAS | 地址建立时间 | ≥ 0ns | RS/CS在WR下降沿前的稳定时间 |
| tAH | 地址保持时间 | ≥ 10ns | RS/CS在WR上升沿后的保持时间 |
| tDSW | 数据建立时间 | ≥ 10ns | 数据在WR上升沿前的稳定时间 |
| tDHW | 数据保持时间 | ≥ 10ns | 数据在WR上升沿后的保持时间 |
| tPWL | WR低电平脉冲宽度 | ≥ 40ns | WR拉低的最小持续时间 |
| tPWH | WR高电平脉冲宽度 | ≥ 40ns | WR拉高的最小持续时间 |
这些参数看着多,其实核心就三条:
- 建立时间:数据/地址必须在时钟沿之前稳定。
- 保持时间:数据/地址必须在时钟沿之后保持稳定。
- 脉冲宽度:时钟信号的低/高电平必须够长。
4.4.2 写时序图解
下面这张SVG图展示了8080接口的写时序流程。我建议你对照着看,比光看文字清楚得多。
4.4.3 读时序图解
读时序和写时序类似,但数据方向相反。MCU拉低RD后,LCD把数据放到总线上,MCU在RD上升沿读取。
4.5 代码实战:用STM32驱动8080接口LCD
光说不练假把式。下面是一段基于STM32的8080接口驱动代码,我加了详细的注释。
// 8080接口写一个字节
void LCD_WriteByte(uint8_t data, uint8_t isCommand) {
// 设置RS:0=命令,1=数据
if (isCommand) {
LCD_RS_LOW(); // RS = 0
} else {
LCD_RS_HIGH(); // RS = 1
}
// 拉低CS,选中LCD
LCD_CS_LOW();
// 把数据放到数据总线上
LCD_DATA_PORT = data;
// 产生一个WR脉冲
LCD_WR_LOW(); // 拉低WR
delay_ns(50); // 保持低电平≥40ns
LCD_WR_HIGH(); // 拉高WR,LCD在上升沿锁存数据
// 拉高CS,释放总线
LCD_CS_HIGH();
}
// 从LCD读一个字节
uint8_t LCD_ReadByte(void) {
uint8_t data;
// 设置RS=1(读数据)
LCD_RS_HIGH();
// 拉低CS
LCD_CS_LOW();
// 将数据线设为输入模式
LCD_DATA_MODE_INPUT();
// 产生一个RD脉冲
LCD_RD_LOW(); // 拉低RD
delay_ns(50); // 等待数据稳定
data = LCD_DATA_PORT; // 读取数据
LCD_RD_HIGH(); // 拉高RD
// 恢复数据线为输出模式
LCD_DATA_MODE_OUTPUT();
// 拉高CS
LCD_CS_HIGH();
return data;
}
4.6 硬件连接优化:少走弯路
硬件连接看似简单,但细节决定成败。下面是我总结的几个优化点:
- 数据线等长:如果PCB空间允许,让DB0~DB7走线长度尽量一致。长度差超过5cm时,高速传输可能出问题。
- 控制线加10kΩ上拉:CS、RS、RD、WR都加上拉电阻,防止MCU未初始化时引脚悬空导致LCD误动作。
- RST加RC复位电路:在RST引脚对地接一个10μF电容,对VCC接一个10kΩ电阻。这样上电时RST会自动拉低一段时间,省得MCU专门控制。
- 数据线加33Ω串联电阻:如果MCU和LCD距离较远(超过10cm),串联电阻可以抑制信号反射。我吃过这个亏——不加电阻时,数据线上有振铃,导致偶尔读错数据。