2. LCD驱动芯片概述:常见I2C接口LCD驱动芯片介绍
做I2C接口的LCD驱动,说白了就是跟驱动芯片打交道。市面上这类芯片不少,但常用的就那么几款。我个人习惯先把芯片的内部框图看明白,再去调时序——这样心里有底,示波器上看到波形也知道哪里出了问题。
这一节,我带大家过一遍三款最常见的I2C接口LCD驱动芯片:SSD1306、PCF8574T、HT1621。它们各有各的脾气,但掌握了它们的内部结构和显存映射规律,调试起来就顺手多了。
2.1 SSD1306:OLED驱动的主力
SSD1306是驱动OLED屏的明星芯片,128×64像素的单色OLED屏几乎都用它。我最早接触它是在一个智能手环项目上,当时为了省电选了OLED,结果发现这芯片的显存管理还挺讲究。
内部框图
SSD1306的内部结构可以分成几个关键模块:
- MCU接口模块:支持I2C、SPI、6800/8080并行接口。I2C模式下,从设备地址固定为0x3C(写)或0x3D(读)。
- 显示数据RAM(GDDRAM):128×64位,共1024字节。这是核心存储区,每个bit对应一个像素点。
- 行驱动器和列驱动器:负责把RAM里的数据扫描到OLED面板上。
- 振荡器和电荷泵:内部自带DC-DC升压电路,产生OLED需要的7~15V驱动电压。
- 命令解码器:解析I2C总线发来的命令,控制显示模式、对比度、扫描方向等。
关键点:SSD1306的I2C接口只支持100kHz标准模式和400kHz快速模式。我曾经遇到过客户用1MHz去跑,结果通信时好时坏——示波器一看,上升沿太慢,SCL高电平时间不够。所以,别超规格。
显存映射与页寻址模式
SSD1306的显存组织方式有点绕,但搞懂了就很简单。它把128×64像素分成8页(Page0~Page7),每页128个字节,每个字节的8个bit对应一列上的8个像素点。
你想想看,这就像把屏幕切成8条横带,每条横带8个像素高。写数据时,先选页,再选列,然后连续写字节。字节的bit0对应页内最上方的像素,bit7对应最下方的像素。
我的经验:调试时最容易犯的错是页地址和列地址搞混。我习惯用示波器抓I2C波形,先确认命令字节是否正确——0x00是命令模式,0x40是数据模式。页地址命令是0xB0~0xB7,列地址低4位是0x00~0x0F,高4位是0x10~0x1F。别问我为什么强调这个,我当年调了整整一个下午才发现列地址高4位没设对。
页寻址模式下,写数据时列地址会自动递增,但页地址不会。写满一页128个字节后,列地址会回卷到0,但页不变。要换页,必须重新发页地址命令。
// SSD1306页寻址写数据示例
void SSD1306_WritePage(uint8_t page, uint8_t *data, uint16_t len) {
// 设置页地址 (0xB0 + page)
I2C_Write(0x3C, 0x00, 0xB0 | (page & 0x07));
// 设置列地址低4位
I2C_Write(0x3C, 0x00, 0x00);
// 设置列地址高4位
I2C_Write(0x3C, 0x00, 0x10);
// 写数据
I2C_Write(0x3C, 0x40, data, len);
}
2.2 PCF8574T:I2C转并口的桥梁
PCF8574T不是专门的LCD驱动芯片,它是个I2C转8位并行I/O的扩展器。但市面上很多1602/2004字符型LCD模块都靠它来转接——因为标准的HD44780接口需要至少6根线,而PCF8574T只需要2根I2C线。
内部框图
PCF8574T的结构相对简单:
- I2C从机接口:地址由A0、A1、A2引脚决定,范围0x20~0x27。
- 8位准双向I/O口:P0~P7,可独立配置为输入或输出。
- 开漏输出和内部上拉:每个I/O口内部有弱上拉,输出高电平时靠上拉电阻。
- 中断输出(INT):当输入状态变化时,INT引脚会拉低,通知MCU读取。
注意:PCF8574T的I/O口驱动能力有限,每个引脚最大拉电流只有1mA。直接驱动LCD背光会烧芯片!我见过一个同事把背光LED直接挂在P0口上,结果芯片冒烟了。正确的做法是加三极管或MOS管驱动。
与LCD的接线映射
PCF8574T转接LCD模块时,通常的映射关系如下:
| PCF8574T引脚 | LCD HD44780引脚 | 功能说明 |
|---|---|---|
| P0 | RS | 寄存器选择(0=命令,1=数据) |
| P1 | RW | 读写选择(通常接地,只写) |
| P2 | E | 使能信号(高脉冲有效) |
| P3 | BL | 背光控制(可选) |
| P4~P7 | D4~D7 | 4位数据总线 |
这里有个坑:PCF8574T写数据时,必须先读一次(伪读)才能正确输出。因为它的输出寄存器在写操作后会自动清零。我刚开始用的时候,死活调不通,后来翻数据手册才发现这个“特性”。
2.3 HT1621:段码LCD的常青树
HT1621是段码式LCD驱动芯片,常用于电表、温控器、计算器这类需要显示数字和简单符号的设备。它支持32×4=128个段,也就是最多128个显示点。
内部框图
HT1621的内部结构包括:
- I2C/3线串行接口:支持I2C和3线SPI两种模式。I2C模式下地址固定为0x7A(写)。
- 显示RAM:32×4位,共16字节。每个bit控制一个段的亮灭。
- 偏压发生器:产生1/3或1/4偏压,驱动LCD的COM和SEG信号。
- 内部RC振荡器:产生LCD驱动所需的32kHz~64kHz时钟。
- 命令解码器:支持系统使能、偏压设置、显示开关、闪烁控制等命令。
实用技巧:HT1621的I2C时序有点特殊——它要求SCL时钟频率不超过300kHz,而且写数据时必须在SCL低电平时改变SDA。我遇到过用400kHz去驱动,结果显示乱码。示波器一看,SDA建立时间不够。降速到250kHz就正常了。
显存映射与段映射
HT1621的显存是16字节,每个字节的高4位和低4位分别对应不同的COM口。具体映射关系如下:
| RAM地址 | COM0 (bit3) | COM1 (bit2) | COM2 (bit1) | COM3 (bit0) |
|---|---|---|---|---|
| 0x00 | SEG1 | SEG2 | SEG3 | SEG4 |
| 0x01 | SEG5 | SEG6 | SEG7 | SEG8 |
| ... | ... | ... | ... | ... |
| 0x0F | SEG61 | SEG62 | SEG63 | SEG64 |
嗯,这里要注意:HT1621的段映射不是连续的。比如你要点亮SEG1对应的段,需要往地址0x00的bit3写1。这个映射关系每个厂家做的LCD屏都不一样,必须看屏的规格书。
2.4 三款芯片对比总结
为了让你快速对比,我整理了一张表:
| 特性 | SSD1306 | PCF8574T | HT1621 |
|---|---|---|---|
| 显示类型 | 点阵OLED | 字符LCD(转接) | 段码LCD |
| 分辨率/段数 | 128×64像素 | 取决于LCD模块 | 32×4=128段 |
| I2C地址 | 0x3C/0x3D | 0x20~0x27 | 0x7A |
| 最大I2C速率 | 400kHz | 400kHz | 300kHz |
| 显存大小 | 1024字节 | 1字节(I/O寄存器) | 16字节 |
| 页寻址 | 支持(8页) | 不支持 | 不支持 |
| 典型应用 | 智能穿戴、仪表 | 1602/2004模块 | 电表、遥控器 |
选型时,我的建议是:
- 需要显示图形或汉字 → SSD1306
- 只需要显示几行字符,且想用现成模块 → PCF8574T转接的LCD1602
- 需要低功耗、显示数字和符号 → HT1621
2.5 知识结构图:I2C LCD驱动芯片选型与内部结构
下面这张图帮你理清三款芯片的核心差异和内部模块关系:
2.6 调试要点总结
最后,把我这些年调这三款芯片踩过的坑总结一下:
- SSD1306:页地址和列地址必须成对设置,缺一不可。写数据前先发0x00进入命令模式,再发0x40进入数据模式。I2C速率别超过400kHz。
- PCF8574T:写数据前先伪读一次,否则输出不对。背光驱动要加外部三极管,别直接挂I/O口。地址引脚A0~A2要上拉或下拉固定,别悬空。
- HT1621:I2C速率别超过300kHz。段映射必须对照屏的规格书,不同厂家不一样。写显存时注意COM和SEG的对应关系,搞反了显示会乱。
重要提醒:不管用哪款芯片,上电后第一件事是用示波器抓I2C波形,确认设备地址和ACK信号。如果地址对了但没有ACK,八成是芯片没上电或者复位引脚没拉高。我遇到过好几次这种低级错误,浪费了大半天。