嵌入式 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,

你就会发现:

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

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


相关推荐
yuanmenghao17 小时前
CAN系列 — (6) CAN FD 带宽、CPU、中断:工程上是如何一起算的?
网络·驱动开发·单片机·mcu·自动驾驶·信息与通信
Tronlong创龙1 天前
DR1 评估板 PL 端 FPGA 开发完全指南:基础案例与 ADC 采集模块详解(一)
开发板·嵌入式开发·硬件开发·工业控制
食咗未1 天前
Linux tcpdump工具的使用
linux·服务器·网络·驱动开发·tcp/ip·测试工具·tcpdump
peixiuhui1 天前
RK3576加持的G8701边缘计算网关深度评测:工业级AIoT的终极解决方案
人工智能·边缘计算·rk3588·嵌入式开发·aiot·工业控制·rk3576
咕噜咕噜万2 天前
ATDD实践:验收测试驱动开发的完整方法论与工具链
驱动开发
Guistar~~2 天前
【Linux驱动开发IMX6ULL】WS73 驱动移植的详细教程基于USB协议--WIFi网卡、蓝牙BLE、星闪SLE
linux·驱动开发
比奇堡派星星2 天前
Linux 杂项设备驱动框架详解
linux·arm开发·驱动开发
chen_mangoo2 天前
Rockchip debian预置安装deb包
linux·驱动开发·嵌入式硬件
进击大厂的小白2 天前
65.设备树下platform_device和platform_driver
驱动开发