嵌入式 LCD 驱动开发全流程详解

🖥️ 嵌入式 LCD 驱动开发全流程详解

在嵌入式世界里,
能不能把"信息显示出来" ,

往往决定了一个项目看起来像不像"成品"。

从黑屏到显示画面,

LCD 驱动几乎是每个嵌入式工程师都绕不开的一关。


🧠 一、先搞清楚:LCD 驱动到底在"驱"什么?

很多新手一听"LCD 驱动",就以为是:

"写几个函数,屏就亮了?"

实际上,LCD 驱动至少包含 四个层面:

  1. 硬件接口通信(SPI / I2C / RGB / MIPI)
  2. 屏幕控制芯片初始化
  3. 显存 / 显示缓冲管理
  4. 图形与字符绘制接口

👉 你驱动的不是"屏",而是 屏后面的控制器。


🧩 二、常见嵌入式 LCD 类型速览

1️⃣ 字符屏(1602 / 2004)

  • 并口 / I2C
  • 显示字符
  • 调试友好,但表现力有限

2️⃣ 图形 LCD(TFT / OLED)

类型 特点
OLED 自发光、对比高、功耗低
TFT 彩色、分辨率高、需背光

3️⃣ 常见控制芯片

屏幕 控制器
0.96 OLED SSD1306
1.3 OLED SH1106
2.4 TFT ILI9341
1.8 TFT ST7735
2.8 TFT ST7789

🔌 三、LCD 硬件连接方式(决定复杂度)

🔹 SPI(最常见)

  • 引脚少
  • 驱动简单
  • 速度中等
text 复制代码
CS / DC / RST / CLK / MOSI

🔹 I2C(字符屏 & 小 OLED)

  • 更省引脚
  • 速度慢
  • 不适合大分辨率

🔹 RGB 并口(高端项目)

  • 速度快
  • 硬件复杂
  • 占用引脚多

⚙️ 四、LCD 驱动开发的标准流程(重点)

✅ Step 1:确认屏幕参数

你至少要知道:

  • 分辨率(如 240×320)
  • 控制芯片型号
  • 接口类型
  • 显示方向
  • 供电 & 背光方式

没数据手册,不要写驱动。


✅ Step 2:底层通信驱动(SPI/I2C)

以 SPI 为例,你需要两个最基础函数:

c 复制代码
void LCD_WriteCmd(uint8_t cmd);
void LCD_WriteData(uint8_t data);

示例:

c 复制代码
void LCD_WriteCmd(uint8_t cmd)
{
    LCD_DC_LOW();
    LCD_CS_LOW();
    HAL_SPI_Transmit(&hspi1, &cmd, 1, 100);
    LCD_CS_HIGH();
}

void LCD_WriteData(uint8_t data)
{
    LCD_DC_HIGH();
    LCD_CS_LOW();
    HAL_SPI_Transmit(&hspi1, &data, 1, 100);
    LCD_CS_HIGH();
}

✅ Step 3:复位与初始化时序

LCD 不会上电就能用,必须初始化。

典型流程:

text 复制代码
硬件复位 → 延时 → 发送初始化命令表

示例:

c 复制代码
void LCD_Reset(void)
{
    LCD_RST_LOW();
    HAL_Delay(50);
    LCD_RST_HIGH();
    HAL_Delay(120);
}

初始化命令通常是一长串:

c 复制代码
LCD_WriteCmd(0x11); // Sleep Out
HAL_Delay(120);
LCD_WriteCmd(0x29); // Display On

👉 顺序和延时都不能乱。


✅ Step 4:设置显示窗口(GRAM)

LCD 的像素数据,

实际上是写进 显示 RAM(GRAM) 的。

c 复制代码
void LCD_SetWindow(uint16_t x1, uint16_t y1,
                   uint16_t x2, uint16_t y2)
{
    LCD_WriteCmd(0x2A); // Column addr
    LCD_WriteData(x1 >> 8);
    LCD_WriteData(x1 & 0xFF);
    LCD_WriteData(x2 >> 8);
    LCD_WriteData(x2 & 0xFF);

    LCD_WriteCmd(0x2B); // Row addr
    ...
    LCD_WriteCmd(0x2C); // Memory write
}

✅ Step 5:写像素(点亮世界的第一步)

c 复制代码
void LCD_DrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
    LCD_SetWindow(x, y, x, y);
    LCD_WriteData(color >> 8);
    LCD_WriteData(color & 0xFF);
}

当你第一次点亮一个像素时------
LCD 驱动已经成功 50% 了。


🖊️ 五、字符与图形绘制原理

字符是怎么画出来的?

本质是:

点阵字体 + 像素填充

c 复制代码
if(font[i] & (1 << bit))
    LCD_DrawPixel(x, y, color);

常见绘制接口封装

  • LCD_DrawLine()
  • LCD_DrawRect()
  • LCD_DrawCircle()
  • LCD_ShowChar()
  • LCD_ShowString()

📦 六、显存 vs 直接刷屏

方案 1:直接写 LCD(简单)

  • RAM 占用小
  • 刷新慢
  • 可能闪屏

方案 2:FrameBuffer(进阶)

  • MCU RAM 保存整屏
  • 双缓冲
  • UI 更丝滑
text 复制代码
240 × 320 × 2Byte ≈ 150KB

🧯 七、新手最常见的 LCD 坑

现象 原因
黑屏 初始化顺序错误
白屏 方向 / 参数错
花屏 分辨率或窗口错
颜色反了 RGB/BGR 顺序
显示偏移 映射没处理
刷屏慢 SPI 频率低

🚀 八、性能优化思路(工程级)

  • SPI 提速(DMA)
  • 批量写像素
  • 区域刷新
  • 字库放 Flash
  • RTOS 分离 UI 任务

🧠 九、LCD 驱动的"终极形态"

成熟项目中:

text 复制代码
底层驱动
  ↓
显示抽象层
  ↓
GUI 库(LVGL / emWin)

你写的 LCD 驱动,

就是 GUI 的"地基"。


✅ 十、总结一句话

LCD 驱动 = 通信 + 初始化 + 显存管理 + 绘图接口。

一旦你真正驱动过一块 LCD,

你就会发现:

嵌入式,不只是"能跑程序",

而是"能把系统展示给用户"。


相关推荐
AI模型调用笔记19 小时前
Copilot Fusion:用 Python 跑通模型级联
人工智能·驱动开发·语言模型·copilot
mounter6252 天前
深入理解 gccrs:GCC 如何实现 Rust 编译器,以及编译 Linux 内核面临的挑战
linux·驱动开发·rust
硅基手札2 天前
CAN 技术系列 04 · CAN 帧格式
驱动开发·嵌入式开发·通信协议·can总线
硅基手札3 天前
操作系统设计思想系列 13 · NuttX 深度 — POSIX 飞控底座 + RTOS 群像
架构·操作系统·嵌入式开发·ecos·sel4·nuttx
万物智能信息科技3 天前
六轴传感器Motion驱动框架开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
硅基手札3 天前
CAN 技术系列 03 · CAN 位定时与同步
嵌入式开发·通信协议·can总线·bug定位调试
晓蛋3 天前
嵌入式开发中的C语言特性
嵌入式开发·陷阱·编程技巧·缺陷·c语言特性
AMASENSYS艾马斯4 天前
变频器滤波器选型与EMC合规建议
驱动开发·单片机·其他·硬件工程·精益工程
沃普天科技4 天前
100W 氮化镓充电器充电头扩展坞一体化设计,实用性翻倍
驱动开发·计算机外设·音视频·硬件工程·pcb工艺
硅基手札4 天前
操作系统设计思想系列 11 · ThreadX 深度 — 预抢占阈值·认证型设计
操作系统·开源项目·嵌入式开发·嵌入式操作系统·设计思想·threadx