第五章:LCD 模块 —— 让你的开发板“看得见”世界!
🖥️ 让你的开发板“看得见”世界!
🎯 适用对象:零基础嵌入式小白
💡 开发环境:STM32G431RBT6 + STM32CubeMX + HAL 库
✅ 屏幕型号:2.4 英寸 MCU 屏,分辨率 240×320,8080 并行接口
🌟 引子:为什么 LCD 不是“插上就能显示”?
想象你第一次去自助餐厅:
- 餐厅有 16 条传送带(数据线),每条都放着不同菜品(像素数据)
- 门口有个保安(片选 CS),只有他点头,你才能进去
- 还有个服务员举着牌子(RS):“这是菜单(命令)” or “这是饭菜(数据)”
- 最后,厨师长喊一声“上菜!”(WR 信号),饭菜才真正端到你面前
LCD 显示也一样!
它不是“傻瓜设备”,而是一个需要严格指挥的精密舞台。
今天,我们就来当这个“导演”!
🔌 一、硬件原理图:LCD 是怎么连的?

📺 屏幕基本信息
| 项目 | 参数 |
|---|---|
| 尺寸 | 2.4 英寸 |
| 类型 | MCU 屏(内置控制器,如 ILI9341) |
| 分辨率 | 240 × 320 像素 |
| 接口 | 8080 并行时序(16 位数据线) |
🧩 引脚连接(类比高速公路)
| 信号 | STM32 引脚 | 功能比喻 |
|---|---|---|
| D0–D15 | GPIOC0 – GPIOC15 | 🛣️ 16 条车道:同时传输 16 位数据(一个像素颜色) |
| CS (片选) | PB9 | 🚧 入口大门:低电平 = 打开,允许通信 |
| RS (寄存器选择) | PB8 | 🪧 路牌:低 = 命令,高 = 数据 |
| WR (写使能) | PB5 | 📢 “上菜!”指令:下降沿触发写入 |
| RD (读使能) | PA8 | 📥 “取菜!”指令:下降沿触发读取 |
✅ 关键点:所有操作必须严格按顺序+时序执行,否则 LCD 会“懵圈”!
⚠️ 二、LED 与 LCD 引脚冲突?别慌!有锁存器!
❓ 问题描述
- LED 和 LCD 共用部分 GPIO 引脚
- 看似会互相干扰,比如:点亮 LED 会不会乱屏?
✅ 解决方案:锁存器(Latch)是幕后英雄!
🧠 生活比喻:快递分拣中心
- LCD 数据像“生鲜包裹”,LED 控制像“普通信件”
- 所有包裹先送到中央分拣台(GPIO)
- 锁存器就像两个独立的传送带:
- 一条专送 LCD(实时更新)
- 一条专送 LED(只在你“确认发货”时才动)
🔒 结论:
- LCD 输出变化 不会影响 LED
- 只有调用
LED_Update()(或类似函数)发送“锁存信号”,LED 才会刷新- 更改 LED 引脚 ≠ 影响 LCD(因为 LCD 用的是固定高速并口)
🕺 三、8080 时序协议 —— “LCD 的舞蹈规则”
🎭 什么是 8080 时序?
它是一套严格的并行通信协议,就像一支16人同步舞:
- 每个人(数据线)必须在同一拍子上举手/放下
- 指挥(CS/RS/WR)必须精准打拍子
- 节奏乱了 → 舞蹈失败(显示错乱)
🚗 通俗解释:多车道高速公路
- 16 条车道(D0–D15):同时跑 16 辆车(16 位数据)
- 交通灯(CS):绿灯亮(CS=0)才能进高速
- 路牌(RS):
- “前方施工”(RS=0)→ 这是命令车(如清屏、设坐标)
- “正常通行”(RS=1)→ 这是数据车(如画一个红点)
- 交警手势(WR):
- 手下压(WR=0)→ “开始卸货!”
- 手抬起(WR=1)→ “卸货完成!”
❗ 为什么不能随便改引脚?
因为 8080 要求所有数据线必须在同一组 GPIO(如 GPIOC),且时序极严。
如果你把 D0 改到 PA0,D1 改到 PB1……
就像让舞者站得东倒西歪——节奏全乱,显示花屏!
🛠️ 四、STM32CubeMX 配置要点

| 功能 | 配置项 |
|---|---|
| GPIOC0–15 | GPIO_Output,推挽,高速(用于数据线) |
| PB9 (CS) | GPIO_Output |
| PB8 (RS) | GPIO_Output |
| PB5 (WR) | GPIO_Output |
| PA8 (RD) | GPIO_Output(若需读屏) |
💡 注意:不要启用内部上下拉!输出模式即可。
💻 五、底层代码详解
1. 核心写操作(导演的“口令”)
// 写命令
#define LCD_CS_CLR() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET)
#define LCD_CS_SET() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET)
#define LCD_RS_CLR() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET) // 命令
#define LCD_RS_SET() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET) // 数据
#define LCD_WR_CLR() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET)
#define LCD_WR_SET() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET)
// 写16位数据到GPIOC
#define LCD_DATA_OUT(data) do { GPIOC->ODR = (data); } while(0)
📜 操作流程:
- 写命令:
LCD_RS_CLR()→LCD_DATA_OUT(cmd)→LCD_WR_CLR()→LCD_WR_SET() - 写数据:
LCD_RS_SET()→LCD_DATA_OUT(data)→LCD_WR_CLR()→LCD_WR_SET()
✅ 关键:WR 必须“先低后高”产生一个写脉冲
2. 高级功能:LcdSprintf() —— 像 printf 一样打印到屏幕!
#include "lcd.h"
#include <stdio.h>
#include <stdarg.h>
/**
* @brief 格式化字符串并显示在指定的LCD行上。
* 类似 printf,但直接输出到LCD。
*
* @param Line 行号(0~15,每行约20字符)
* @param format 格式化字符串,如 "Temp: %d°C"
* @param ... 可变参数
*
* @example
* LcdSprintf(0, "Score: %d", score);
*/
void LcdSprintf(uint8_t Line, char *format, ...)
{
char String[21]; // 缓冲区(20字符+1结束符)
va_list arg; // 可变参数列表
va_start(arg, format); // 初始化参数列表
vsprintf(String, format, arg); // 格式化到缓冲区
va_end(arg); // 清理
LCD_DisplayStringLine(Line, (u8 *)String); // 显示到LCD
}
🧠 技术点解析(笔记中的精华!):
| 组件 | 作用 | 比喻 |
|---|---|---|
va_list | 存储可变参数的“容器” | 一个装满配料的托盘 |
va_start | 指向第一个可变参数 | 厨师说:“从这里开始拿料!” |
vsprintf | 把格式串 + 参数 → 字符串 | 把配料按菜谱炒成菜 |
va_end | 清理资源 | 洗干净托盘 |
✅ 效果:
以前要拼字符串再显示,现在一行搞定:LcdSprintf(1, "X=%d, Y=%d", x, y);
3. 常用 LCD 函数速查表
| 函数 | 功能 | 示例 |
|---|---|---|
LCD_Init() | 初始化 LCD 控制器 | 启动时调用一次 |
LCD_Clear() | 清空整个屏幕 | LCD_Clear(); |
LCD_ClearLine(2) | 清除第2行 | 用于刷新单行数据 |
LCD_SetTextColor(RED) | 设置文字颜色 | 需包含颜色宏(如 RED=0xF800) |
LCD_SetBackColor(BLUE) | 设置背景色 | |
LCD_DisplayStringLine(0, "Hello") | 在第0行显示字符串 |
🧪 六、使用示例:打造你的“信息面板”
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
LCD_Init(); // 初始化LCD
LCD_Clear(WHITE); // 白底
LCD_SetTextColor(BLACK);
LCD_SetBackColor(WHITE);
uint8_t count = 0;
while (1)
{
LcdSprintf(0, "System Ready!");
LcdSprintf(1, "Count: %d", count++);
LcdSprintf(2, "Time: %ds", HAL_GetTick()/1000);
HAL_Delay(500);
}
}
✅ 效果:屏幕上实时显示计数和运行时间,像一个迷你仪表盘!
🧠 本章口诀(背下来!)
🖥️ 2.4寸MCU屏,240x320清又明!
🛣️ 16车道并行跑,8080时序要记牢!
🚧 CS开门RS指路,WR一抖数据入!
🔒 LED LCD虽共线,锁存器来保平安!
📝 LcdSprintf真方便,printf直接上屏幕!
🎨 清屏设色画文字,你的界面你做主!
✅ 总结
提供的 LCD 笔记已经非常系统!我们在此基础上:
- 用生活化比喻解释了 8080 时序、锁存器、引脚冲突
- 修复了代码细节(如可变参数语法)
- 结构化呈现,便于小白理解与实操
现在,你不仅能“点亮屏幕”,还能优雅地显示动态信息,为后续 GUI 开发打下坚实基础!
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)