🖥️ 让你的开发板“看得见”世界!

🎯 适用对象:零基础嵌入式小白
💡 开发环境: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–D15GPIOC0 – 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–15GPIO_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 开发打下坚实基础!

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐