手把手教你用Arduino和U8g2库点亮LCD12864屏幕(ST7920芯片版)
手把手教你用Arduino和U8g2库点亮LCD12864屏幕(ST7920芯片版)
当第一次拿到LCD12864液晶屏时,许多创客都会被它那128x64像素的显示能力所吸引。这块看似简单的屏幕,却能承载从文本到图形的丰富信息。本文将带你从零开始,用Arduino和强大的U8g2库,一步步点亮这块基于ST7920控制芯片的显示屏。
1. 硬件准备与连接
在开始编程前,正确的硬件连接是成功的第一步。ST7920芯片的LCD12864模块通常有20个引脚,但实际使用中我们只需要关注其中关键的几个:
必备材料清单:
- Arduino开发板(UNO或Nano最常见)
- LCD12864显示屏(ST7920芯片)
- 杜邦线若干(建议使用不同颜色区分)
- 10KΩ电位器(用于对比度调节)
- 面包板(可选,方便接线)
连接电路时,最让新手困惑的往往是引脚定义。以下是经过验证的标准接法:
| LCD引脚 | 功能说明 | Arduino连接 | 备注 |
|---|---|---|---|
| VSS | 电源地 | GND | 必须可靠接地 |
| VDD | 电源正极 | 5V | 切勿接3.3V |
| RS(CS) | 片选信号 | D2 | 可自定义其他数字引脚 |
| RW(SID) | 数据信号 | D3 | 相当于SPI的MOSI |
| E(SCLK) | 时钟信号 | D4 | 相当于SPI的SCK |
| PSB | 模式选择 | GND | 接地选择串行模式 |
| RST | 复位信号 | RESET | 或接Arduino的RESET |
| VO | 对比度调节 | 电位器中间脚 | 两端接VDD和VSS |
注意:不同厂家的LCD模块引脚标注可能略有差异,遇到显示问题时首先检查接线是否正确。我曾遇到过标注为"SDA"/"SCL"的模块,实际仍需按SPI方式连接。
2. U8g2库的安装与配置
U8g2库之所以成为驱动单色显示屏的首选,在于它惊人的兼容性——支持超过200种显示控制器。安装过程简单却至关重要:
- 打开Arduino IDE,点击"工具"→"管理库"
- 在搜索框输入"U8g2"
- 选择Oliver Kraus开发的版本(当前最新为2.32.x)
- 点击"安装"按钮
若网络环境导致安装失败,可手动下载ZIP包:
# 获取最新U8g2库 wget https://github.com/olikraus/u8g2/archive/master.zip然后在IDE中选择"项目"→"加载库"→"添加.ZIP库"。
库初始化代码详解:
#include <U8g2lib.h> // 软件SPI方式初始化 U8G2_ST7920_128X64_F_SW_SPI u8g2( U8G2_R0, // 显示旋转方向 /* clock=*/ 4, // SCK引脚(D4) /* data=*/ 3, // MOSI引脚(D3) /* cs=*/ 2 // CS片选引脚(D2) );硬件SPI版本性能更优(需使用特定引脚):
// 硬件SPI初始化(UNO的SCK=13, MOSI=11) U8G2_ST7920_128X64_F_HW_SPI u8g2( U8G2_R0, /* cs=*/ 2, /* dc=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE );3. 基础显示功能实现
成功初始化后,让我们从最简单的"Hello World"开始,逐步探索U8g2的强大功能。
3.1 文本显示核心代码
void setup() { u8g2.begin(); // 初始化显示 } void loop() { u8g2.firstPage(); do { // 设置字体(高度8像素) u8g2.setFont(u8g2_font_ncenB08_tr); // 在(0,24)坐标显示文本 u8g2.drawStr(0, 24, "Hello Maker!"); } while (u8g2.nextPage()); delay(1000); }关键点解析:
firstPage()和nextPage()构成了U8g2特有的页面缓冲机制- 坐标系统原点(0,0)位于屏幕左上角
- 字体高度决定Y坐标取值(如8pt字体至少需要Y≥8)
3.2 字体与排版进阶
U8g2内置了丰富字体,查看所有可用字体:
// 在setup()中添加 Serial.begin(9600); for (const char **f = u8g2_fonts; *f; f++) { Serial.println(*f); }常用字体组合推荐:
| 字体名称 | 特点 | 适用场景 |
|---|---|---|
| u8g2_font_6x10_tr | 小字号,清晰 | 多行文本 |
| u8g2_font_unifont_t_chinese | 中文字库 | 中文显示 |
| u8g2_font_inb24_mf | 大号数字 | 数值突出显示 |
| u8g2_font_7x14B_tf | 加粗英文 | 标题文字 |
动态变量显示示例:
int counter = 0; void loop() { u8g2.firstPage(); do { u8g2.setFont(u8g2_font_7x14B_tf); u8g2.setCursor(0, 20); u8g2.print("Count:"); u8g2.setFont(u8g2_font_inb24_mf); u8g2.setCursor(40, 50); u8g2.print(counter++); } while (u8g2.nextPage()); delay(500); }4. 图形绘制与高级应用
除了文本,U8g2的图形功能同样强大。让我们实现一个动态进度条:
4.1 基础图形元素
// 绘制矩形进度条框架 u8g2.drawFrame(10, 20, 100, 10); // 填充进度(0-100范围) int progress = 50; u8g2.drawBox(10, 20, progress, 10); // 绘制分隔线 for (int i=0; i<=10; i++) { u8g2.drawVLine(10+i*10, 20, 10); }4.2 复合图形示例:简易UI
void drawUI() { // 顶部标题栏 u8g2.drawBox(0, 0, 128, 12); u8g2.setFontMode(1); // 透明字体 u8g2.setDrawColor(0); // 白色绘制 u8g2.setFont(u8g2_font_7x14B_tf); u8g2.drawStr(5, 10, "System Monitor"); // 恢复默认绘制颜色 u8g2.setDrawColor(1); // CPU使用率指示器 u8g2.drawFrame(10, 20, 108, 8); u8g2.drawBox(10, 20, random(10,100), 8); // 温度显示 u8g2.setFont(u8g2_font_6x10_tr); u8g2.drawStr(10, 40, "Temp:"); u8g2.setCursor(50, 40); u8g2.print(random(20,30)); u8g2.print("°C"); }5. 常见问题排查
遇到显示异常时,可按照以下步骤排查:
屏幕无任何显示
- 检查VDD和VSS是否接反
- 测量VO引脚电压(正常应为0.5-1V)
- 尝试调节电位器改变对比度
显示乱码或条纹
- 确认PSB引脚已接地(串行模式)
- 检查时钟引脚接触是否良好
- 降低SPI速度(添加
u8g2.setBusClock(100000))
部分内容显示异常
- 检查字体高度与Y坐标的匹配
- 确保每次loop()都调用firstPage()/nextPage()
- 尝试减少显示内容测试内存是否不足
示波器诊断技巧:
- 正常工作时SCLK引脚应有规则的脉冲信号
- 数据传输期间SID引脚应有高低电平变化
- CS引脚应在每次传输前变为低电平
通过以上步骤,你应该已经掌握了LCD12864的基础到进阶使用方法。在实际项目中,这种显示屏常被用于:
- 3D打印机状态监控
- 智能家居控制面板
- 数据采集系统可视化
- 迷你游戏机显示
