LCD1602这种字符液晶,便宜、耐造、老兵油,几乎是每套Arduino入门套件的标配。只是它裸接要吃掉七八个IO口,杜邦线一大把,接错一根满屏乱码。给它挂一颗PCF8574的I2C转接模块,就只剩四根线的事:VCC、GND、SDA、SCL。
这篇按顺序讲四件事:认识模块、接线、跑通第一段显示代码,以及最容易翻车的两处——I2C地址对不上和自定义字符不会画。代码都是从教程页机械搬过来的,可以逐字符照抄,要改的只有地址和坐标。
先认识LCD I2C 1602这块屏
所谓LCD I2C 1602,其实就是一块普通LCD1602,背面焊一块PCF8574转接板,再加一颗调对比度的电位器,打包成一个四脚器件。市面上也有把三合一做进单块板的紧凑型,电压还分5V和3.3V两种,原理完全一样。

四根引脚各管各的:GND接地,VCC接5V供电,SDA走I2C数据线,SCL走I2C时钟线。就这四个,没有多余的脚。
16x2的意思是16列2行,一共32个字符位。列和行都是从0开始编号:第1列是0,第2行是1。后面setCursor定位全靠这套坐标系,数错一格,字就挪位。

接线:四根杜邦线的事
以Arduino Uno为例,VCC接5V,GND接GND,SDA接A4,SCL接A5。A4和A5本来就是Uno的I2C专用脚,别再拿去当模拟输入用。
| LCD I2C | Arduino Uno / Nano | Arduino Mega |
|---|---|---|
| VCC | 5V | 5V |
| GND | GND | GND |
| SDA | A4 | 20 |
| SCL | A5 | 21 |

用Nano也是同样的接法;换Mega 2560的话,SDA、SCL挪到标着20、21的两个脚。想接得牢固些,可以套一块螺丝端子扩展板,免得杜邦线一碰就松,跑着跑着黑屏。
装库、跑通第一段显示代码
软件侧只需要一个库:DIYables_LCD_I2C。在Arduino IDE的库管理器里搜这个名字装上就行,不用去第三方站下载。
声明对象时带三个参数:I2C地址、列数、行数。地址先用0x27,为什么后面细说。初始化、开背光,然后定位、打印,整个setup就五步。
代码里有个小坑要交代:站点编辑器会把尖括号头文件吞掉,所以下文的include一律写成了双引号形式,"DIYables_LCD_I2C.h"和"Wire.h"与尖括号写法在Arduino工具链里编译等价,直接照抄没问题。
#include "DIYables_LCD_I2C.h"
DIYables_LCD_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
void setup()
{
lcd.init(); // initialize the lcd
lcd.backlight();
}
void loop()
{
lcd.clear(); // clear display
lcd.setCursor(0, 0); // move cursor to (0, 0)
lcd.print("Arduino"); // print message at (0, 0)
lcd.setCursor(2, 1); // move cursor to (2, 1)
lcd.print("GetStarted.com"); // print message at (2, 1)
delay(2000); // display the above for two seconds
lcd.clear(); // clear display
lcd.setCursor(3, 0); // move cursor to (3, 0)
lcd.print("DIYables"); // print message at (3, 0)
lcd.setCursor(0, 1); // move cursor to (0, 1)
lcd.print("www.diyables.io"); // print message at (0, 1)
delay(2000); // display the above for two seconds
}
两处setCursor,括号里第一个参数是列、第二个是行,都从0数起。烧录上传后,屏幕先显示Arduino和GetStarted.com两秒,再切到DIYables和www.diyables.io两秒,循环往复。

核心动作其实就五个:引库、声明对象、lcd.init()初始化、lcd.backlight()开背光、setCursor加print打印。以后玩OLED、TFT,套路几乎一样,这一套通了就都通了。
屏不亮或没字:0x27还是0x3F
最容易翻车的是地址。0x27不是铁律,DIYables品牌出厂默认0x27,但有的厂家板子是0x3F。代码里的地址和实物对不上时,程序照烧不误,编译全绿,屏幕就是没反应。
先别急着怀疑接线。把代码里的0x27换成0x3F再烧一次;两个都不行,就上扫描程序,让板子自己把I2C总线上的设备地址报出来:
// I2C address scanner program
#include "Wire.h"
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("I2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found");
else
Serial.println("done");
delay(5000); // wait 5 seconds for next scan
}
烧完打开串口监视器,波特率9600。总线上挂着一块LCD的话,你会看到类似I2C device found at address 0x3F!的输出。把这个地址抄回声明对象那一行,问题基本就了了。
另一个高频坑:背光亮着,一个字都看不见。这不是屏坏了,是对比度没调好。用小螺丝刀旋转接板背面那颗蓝色电位器,边转边看,直到第一行显示出整齐的黑色方块,再烧程序就有字了。
自定义字符:8个格子随你画
lcd.print()只认ASCII字符,想显示心形、箭头这类符号就得自己画。16x2的每个字符由5列8行共40个像素拼成,你逐个点亮像素,LCD控制器就把这40个点存成一个自定义字符。

自定义字符最多能建8个,索引0到7。定义一个8字节的数组,每行一个二进制数,1表示点亮。下面这段把一颗心存进索引0,然后打印在(2,0)的位置:
#include "DIYables_LCD_I2C.h"
DIYables_LCD_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
byte customChar[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};
void setup()
{
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.createChar(0, customChar); // create a new custom character
lcd.setCursor(2, 0); // move cursor to (2, 0)
lcd.write((byte)0); // print the custom char at (2, 0)
}
void loop()
{
}

要点浓缩成三步:先写customChar[8]数组;再在setup()里用createChar(索引, 数组)注册;最后任何想显示的位置,setCursor定位,lcd.write((byte)索引)打印。
想多放几个也行。比如同时放一颗心、一个上箭头、一个下箭头,各占一个索引,挨个write出来,屏幕第一行就能并排站三个符号:

整套流程走下来,真正要记的就三样:接线表、从0数起的坐标系、地址排查三板斧(0x27、0x3F、扫描程序)。剩下的都是变着花样调print和setCursor。这块四根线搞定的屏,工具箱里值得常备一块。











A4和A5是Uno的I2C专用脚这条提醒很实在,见过有人拿A4接了光敏电阻,然后总线死活扫不到设备,查了一晚上。
背光亮着但没字那个坑我也踩过,转电位器转到怀疑人生,原来原理就这么一句话。
lcd.write((byte)0)这里新手容易顺手写成print(0),结果屏幕上打出的是个空白或者怪字符,作者把字节写入单拎出来讲挺好的。
这块屏我从裸接转I2C的时候也是这么过来的,十根杜邦线换四根,幸福感直接翻倍。0x3F那段太真实了,我手上某宝买的一块就是0x3F,当时以为板子是坏的,差点退了,后来跑了个扫描程序一看地址傻眼。建议大家接到新屏先扫一遍地址再抄代码,能省半小时抓头发。另外转电位器那个动作别跳过,很多屏到手默认对比度就是看不见字的。