LCD12864模块使用教程:零基础项目应用

从零开始玩转LCD12864:嵌入式开发中的“老派但靠谱”显示方案

你有没有遇到过这样的场景?
手里的单片机项目已经能采集传感器数据、执行控制逻辑,甚至还能通过串口把信息发给电脑——但一旦脱离上位机,设备就像个“哑巴”,完全不知道它在想什么。这时候,一块小小的显示屏就成了打通人机交互“最后一公里”的关键。

今天我们要聊的,就是一款在嵌入式圈子里经久不衰的经典角色:LCD12864。它不像OLED那样炫酷,也不如TFT彩屏那般绚丽,但它便宜、省电、稳定,最重要的是——哪怕你是51单片机新手,也能在一个下午把它点亮


为什么是LCD12864?一个被低估的实用主义者

在智能手表满天飞、TFT屏幕白菜价的今天,为什么还有人用这种“黑白块”?答案很简单:不是所有系统都需要全彩动画,大多数时候,我们只需要看懂几个字就够了

想想家里的微波炉面板、工厂里的温控仪、或者实验室里那台老旧的数据记录仪——它们不需要滑动菜单或触摸反馈,只要清晰地告诉你“当前温度:75°C”、“运行中…”就足够了。这类需求,正是LCD12864的主场。

它的分辨率是128列 × 64行像素,听起来不高,但对于文本和简单图形来说绰绰有余。更关键的是,很多型号内置了中文字库芯片(比如ST7920),这意味着你可以直接发送汉字编码,而不用自己做字模提取、烧录Flash那一套繁琐流程。

一句话总结优势
成本低 + 功耗极低 + 支持中文 + 驱动简单 = 中小型嵌入式项目的理想选择。


拆开看看:LCD12864是怎么工作的?

别被“图形液晶”四个字吓到,其实它的内部结构非常清晰。我们以最常见的ST7920控制器为例来拆解。

显示内存怎么管?DDRAM 和 GDRAM 的分工

LCD12864有两种工作模式:

  • 文本模式(Text Mode):写入的是字符代码(比如ASCII或GB2312),由控制器自动查表生成点阵并显示。
  • 图形模式(Graphic Mode):直接操作显存,逐位绘制图像。

这两种模式背后对应两块不同的内存区域:

内存类型全称用途
DDRAMDisplay Data RAM存放要显示的字符码,每页最多显示32个字符(共4行)
GDRAMGraphic Display RAM图形模式下使用的显存,大小为128×64 bit,即1024字节

在文本模式下,你往DDRAM里写一个'A',屏幕就会出现字母A;而在图形模式下,你要手动向GDRAM写入每一位像素数据,才能画出想要的图案。

屏幕地址怎么寻址?“页-列”结构解析

GDRAM被划分为8页(Page),每页包含8行像素(纵向8位),共64行。每一行有128列,也就是128个字节。所以整个显存布局是一个8页 × 128列的二维空间。

Page 0: [0x80][0x81]...[0xFF] ← 第0~7行 Page 1: [0x90][0x91]...[0xFF] ← 第8~15行 ... Page 7: [0xF0][0xF1]...[0xFF] ← 第56~63行

当你想在某个位置绘图时,必须先设置页地址和列地址,然后连续写入数据。这有点像老式打印机一行一行打印纸张。


接口怎么连?并行还是串行?

LCD12864常见的接口方式有三种:

  1. 8位并行
  2. 4位并行
  3. SPI串行(部分支持)

其中最常用的是4位并行模式,因为它能在保证速度的同时节省MCU的IO资源。

引脚定义一览(典型16脚模块)

引脚名称功能说明
1VSS
2VDD电源(+5V或3.3V)
3VO对比度调节(接电位器中间)
4RS寄存器选择:0=指令,1=数据
5RW读写控制:0=写,1=读
6EN使能信号,上升沿触发
7~10D0~D3数据线(低4位,4位模式不用)
11~14D4~D7数据线(高4位,在4位模式下使用)
15PSB并/串选择:1=并行,0=串行
16NC/RST复位(部分模块有效)
17LED+背光正极(需限流电阻)
18LED-背光负极

🔧 实际接线建议:
-VO接一个10kΩ可调电阻,两端分别接VDD和GND;
-LED+串联220Ω电阻再接到电源,防止背光电流过大;
- 所有电源引脚附近加0.1μF陶瓷电容去耦。


手把手教你写驱动:从初始化到显示字符串

下面这段代码基于STC89C52单片机(经典51核),采用4位并行接口实现基本功能。即使你刚学单片机不久,也能轻松理解每一步在做什么。

#include <reg52.h> // 控制引脚定义 sbit RS = P1^0; // 寄存器选择 sbit RW = P1^1; // 读写控制 sbit EN = P1^2; // 使能信号 #define LCD_DATA_PORT P0 // 数据端口(只用低4位) // 毫秒级延时(根据晶振调整) void delay_ms(unsigned int ms) { unsigned int i, j; for (i = 0; i < ms; i++) for (j = 0; j < 110; j++); } // 写命令函数(4位模式) void lcd_write_command(unsigned char cmd) { // 先送高4位 LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | (cmd & 0xf0); RS = 0; RW = 0; EN = 1; delay_ms(1); EN = 0; // 再送低4位 LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | ((cmd << 4) & 0xf0); RS = 0; RW = 0; EN = 1; delay_ms(1); EN = 0; delay_ms(2); // 等待指令执行完成 } // 写数据函数 void lcd_write_data(unsigned char dat) { LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | (dat & 0xf0); RS = 1; RW = 0; EN = 1; delay_ms(1); EN = 0; LCD_DATA_PORT = (LCD_DATA_PORT & 0x0f) | ((dat << 4) & 0xf0); RS = 1; RW = 0; EN = 1; delay_ms(1); EN = 0; delay_ms(2); } // 初始化函数 void lcd_init() { delay_ms(20); LCD_DATA_PORT &= 0x0f; // 清空高四位 lcd_write_command(0x33); // 必须连续两次设置8位模式 lcd_write_command(0x32); // 进入4位模式前的准备 lcd_write_command(0x28); // 4位模式,双行显示,5x7字体 lcd_write_command(0x0C); // 开显示,关光标,关闪烁 lcd_write_command(0x06); // 自动增量地址,画面右移 lcd_write_command(0x01); // 清屏 delay_ms(2); }

关键点解读

  • 为什么先发0x33和0x32?
    这是ST7920的标准初始化流程。由于一开始不确定模块处于什么状态,需要先尝试三次“唤醒”操作,确保进入4位模式。

  • EN引脚的作用是什么?
    它像是一个“确认键”。每次数据准备好后,拉高EN再拉低,相当于告诉LCD:“我现在给你数据了,请读取”。

  • 为什么每个操作后都有delay_ms(1)?
    因为LCD控制器处理指令需要时间(通常≥1.6ms)。如果不等待,可能会导致命令丢失或乱码。


如何在屏幕上显示内容?

有了基础函数,就可以封装更高层的功能了。

在指定位置显示字符串

void lcd_show_string(unsigned char x, unsigned char y, char *str) { unsigned char addr; switch(y) { case 0: addr = 0x80 + x; break; // 第一行 case 1: addr = 0x90 + x; break; // 第二行 case 2: addr = 0x88 + x; break; // 第三行 case 3: addr = 0x98 + x; break; // 第四行 default: return; } lcd_write_command(addr); // 设置起始地址 while(*str) { lcd_write_data(*str++); } }

调用示例:

void main() { lcd_init(); lcd_show_string(0, 0, "Hello World!"); lcd_show_string(0, 1, "LCD12864 Test"); while(1); // 主循环停在这里 }

你会发现,“Hello World!”出现在第一行,“LCD12864 Test”出现在第二行。虽然不能换行自动回车,但对固定布局的小型界面来说完全够用。


中文显示怎么做?真的能直接打汉字吗?

是的!只要你用的是带中文字库的版本(如ST7920),就可以直接显示汉字。

GB2312编码中,汉字按“区位码”组织。例如:

  • “中” 字的区位码是 5448(十进制)
  • 转换成十六进制为 0x3630
  • 向DDRAM写入这两个字节即可显示
// 显示“中文测试” lcd_show_string(0, 0, "Chinese"); // 英文 lcd_write_command(0x80 + 8); // 移动到第9个字符位置 lcd_write_data(0x36); // “中” lcd_write_data(0x30); lcd_write_data(0x2d); // “文” lcd_write_data(0x47); lcd_write_data(0x2a); // “测” lcd_write_data(0x68); lcd_write_data(0x2b); // “试” lcd_write_data(0x6a);

当然,实际开发中我们会用工具生成完整的字模数组,或者使用现成的中文显示库来简化操作。


实战技巧与常见坑点

别以为接上线就能亮,这些经验之谈能帮你少走弯路:

❗ 常见问题与解决方案

问题现象可能原因解决方法
屏幕全黑或全白VO电压不对调节电位器,观察对比度变化
完全无显示电源未接好 / EN信号异常检查VDD/GND,确认EN有脉冲
出现乱码或偏移初始化顺序错误严格按照0x33→0x32→0x28流程
背光亮但无字符RS/RW/EN接反用万用表检查控制线电平
显示残影或重影缺少延时每次写操作后增加至少2ms延迟
切换模式花屏未关闭显示就切换图形模式前执行lcd_write_command(0x08)关闭显示

💡 设计建议

  1. 电源设计要稳:在VDD与GND之间加0.1μF贴片电容,抑制高频噪声;
  2. 通信线尽量短:尤其是EN和RS线,远离电机、继电器等干扰源;
  3. 背光可控化:将LED+接到GPIO,通过PWM调节亮度,延长电池寿命;
  4. 加入软件复位机制:长时间运行后可能出现通信错乱,定期重启LCD更可靠;
  5. PCB布局注意阻抗匹配:若走线较长,可在控制线上串联小电阻(约22Ω)防反射。

它适合你的项目吗?应用场景盘点

如果你正在做一个以下类型的项目,LCD12864很可能是个不错的选择:

工业仪表:压力表、流量计、温湿度监控器
家电控制板:洗衣机、烤箱、饮水机的操作界面
教学实验平台:学生练手的理想外设,成本低、资料多
电池供电设备:静态显示几乎不耗电,配合背光开关可达月级续航
脱机运行系统:无需连接电脑即可查看状态和参数

而如果你要做的是:

❌ 彩色UI界面
❌ 触摸交互
❌ 动态刷新率高的动画
❌ 小尺寸高密度显示

那建议考虑OLED或TFT方案。


最后一点思考:经典为何不死?

技术总是在进步,但我们不能因此否定那些“老物件”的价值。LCD12864或许不够酷,但它代表了一种设计理念:用最简单的办法解决最实际的问题

它不需要复杂的图形库,不需要DMA传输,甚至连malloc都不用。几百字节的内存、几条IO线、一段百行代码,就能构建出完整的人机界面。

对于初学者而言,它是理解“外设驱动机制”的绝佳入口;对于工程师来说,它是快速验证原型的得力助手。

未来也许会有更多新型电子纸、超低功耗LCD涌现,但在很长一段时间内,LCD12864仍将是嵌入式世界里那个默默无闻却始终可靠的“老兵”


如果你也在用这块屏幕,欢迎留言分享你的项目经验!有没有遇到过“调了一整天才发现EN脚没接对”的惨痛经历?咱们评论区见 😄

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1141493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx权限问题详解及解决方案

一、前言 在运行Nginx服务器时&#xff0c;权限问题是一个常见的困扰&#xff0c;尤其是在Linux环境下。权限配置不当可能导致Nginx无法启动、无法访问某些目录或文件&#xff0c;甚至影响到网站的正常运行。本文将深入探讨Nginx权限问题的原因&#xff0c;并提供有效的解决方案…

Excel数据透视表:如何显示未使用的数据验证列表项

在Excel中&#xff0c;数据透视表是强大的数据分析工具&#xff0c;能够快速汇总和分析大量数据。然而&#xff0c;当你试图在数据透视表中显示一个包含未使用项目的数据验证列表时&#xff0c;可能会遇到一些挑战。本文将详细介绍如何在数据透视表中显示所有可能的项目&#x…

Node.js看我的就行了!!!

#最近nodejs崩了好多次&#xff0c;所以我决定重装。由于没有卸载干净&#xff0c;折腾了我两天# 终于&#xff0c;我今天下午装好了 我们从卸载开始(没有安装的小伙伴直接到第二步) 一、卸载node.js Windows系统彻底卸载 nodejs 1. 开始菜单中搜索node&#xff0c;找到并…

Nginx搭建负载均衡

Nginx搭建负载均衡 引言 在当今互联网时代&#xff0c;网站和应用的可用性、可靠性和性能至关重要。随着流量的增加&#xff0c;单一服务器往往难以承载所有请求&#xff0c;从而导致性能瓶颈。负载均衡&#xff08;Load Balancing&#xff09;是一种将流量分散至多台服务器的技…

Git命令补全优化:解决分支名称冲突

在日常的Git操作中,利用Tab键进行命令补全是一个非常方便的功能。例如,当我们输入git switch de并按下Tab键时,如果存在多个以"de"开头的分支(如develop和dev-1234),命令补全会停止在git switch dev。即使我们删除了dev-1234分支,补全功能仍然会因为之前的存在…

AD中从电路图到PCB的设计流程:系统学习篇

从原理图到PCB&#xff1a;在Altium Designer中构建可靠硬件设计的实战路径你有没有经历过这样的时刻&#xff1f;花了一整天画好电路图&#xff0c;信心满满地点击“更新PCB”&#xff0c;结果弹出一堆红色警告&#xff1a;“封装未指定”、“网络冲突”、“Extra Primitive D…

STC15系列与Keil C51结合的PWM输出全面讲解

深入掌握STC15单片机PWM输出&#xff1a;从寄存器配置到Keil实战调优在嵌入式控制的世界里&#xff0c;PWM&#xff08;脉宽调制&#xff09;是一项看似基础却极为关键的技术。无论是调节LED亮度、驱动直流电机&#xff0c;还是实现数字电源的闭环稳压&#xff0c;背后都离不开…

u8g2中自定义字体嵌入的实战案例

让你的嵌入式界面“有颜有料”&#xff1a;u8g2自定义字体实战全解析你有没有遇到过这样的情况&#xff1f;项目快上线了&#xff0c;老板看了一眼OLED屏幕上的显示效果&#xff0c;皱着眉头说&#xff1a;“这字太普通了&#xff0c;不像我们品牌调性。” 或者用户反馈&#x…

软件I2C在STM32上的实现:手把手教程(从零开始)

软件I2C在STM32上的实现&#xff1a;从协议到代码的深度实践 你有没有遇到过这样的场景&#xff1f;项目已经进入PCB布线阶段&#xff0c;突然发现硬件I2C引脚被串口占用了&#xff1b;或者多个传感器都需要接入I2C总线&#xff0c;但MCU只提供一路I2C外设。更糟的是&#xff0…

【LLaVA】《Improved Baselines with Visual Instruction Tuning》译读笔记

Improved Baselines with Visual Instruction Tuning 摘要 大型多模态模型&#xff08;LMM&#xff09;最近在视觉指令调优方面取得了令人鼓舞的进展。本文首次系统性地研究在 LLaVA 框架下在受控环境中探讨 LMMs 的设计选择。本文展示了 LLaVA 中全连接的视觉语言连接器功能…

vivado安装包版本选择:核心要点一文说清

Vivado安装包版本怎么选&#xff1f;搞懂这几点&#xff0c;告别环境踩坑你有没有遇到过这样的情况&#xff1a;刚接手一个老项目&#xff0c;打开工程时弹出“Project file corrupted”&#xff1b;或者辛辛苦苦写完代码&#xff0c;综合到一半报错“Part not found”&#xf…

Blazor WebAssembly 中的 MudBlazor 折叠面板绑定与更新

简介 在 Blazor WebAssembly 开发中&#xff0c;MudBlazor 是一个非常受欢迎的 UI 组件库&#xff0c;它提供了丰富的组件和样式&#xff0c;极大地简化了前端开发。然而&#xff0c;在使用其折叠面板&#xff08;Expansion Panels&#xff09;时&#xff0c;如何正确地绑定数据…

ChatGPT 基于 GPT(Generative Pre-trained Transformer)架构,通过大规模预训练和微调实现自然语言处理。

AI 发展指南&#xff1a;技术演进路线ChatGPT 的技术基础ChatGPT 基于 GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构&#xff0c;通过大规模预训练和微调实现自然语言处理。其核心是 Transformer 的自注意力机制&#xff0c;能够捕捉长距离依赖关系。训…

深度解析:AI提示系统技术架构中的多轮对话管理设计

深度解析&#xff1a;AI提示系统技术架构中的多轮对话管理设计 摘要/引言 在当今人工智能飞速发展的时代&#xff0c;AI提示系统广泛应用于聊天机器人、智能客服等诸多场景。多轮对话管理作为AI提示系统技术架构的关键组成部分&#xff0c;直接影响着用户体验和系统的实用性。本…

线性回归是机器学习中最基础的算法之一,用于建立输入变量(特征)与输出变量

线性回归原理与代码实现线性回归是机器学习中最基础的算法之一&#xff0c;用于建立输入变量&#xff08;特征&#xff09;与输出变量&#xff08;目标&#xff09;之间的线性关系。以下是其核心原理及Python实现。数学原理线性回归模型表示为&#xff1a; $y wX b$ 其中&…

基于STM32的下载异常:no stlink detected系统学习

当你的STM32下不了程序&#xff1a;深度解析 no stlink detected 的根源与实战解决 你有没有遇到过这样的场景&#xff1f; 手头的STM32开发板一切看起来都正常&#xff0c;电源灯亮了&#xff0c;接线也没松动。可当你在STM32CubeIDE里点击“Download”时&#xff0c;弹出…

STM32 HAL库配置HID协议的超详细版教程

手把手教你用STM32 HAL库实现USB HID设备&#xff1a;从零到“即插即用”的完整实战你有没有遇到过这样的场景&#xff1f;开发一个调试工具&#xff0c;想通过USB把数据传给电脑&#xff0c;结果客户抱怨&#xff1a;“怎么还要装驱动&#xff1f;”、“Mac上根本没法用&#…

Multisim汉化实战:软件层修改完整指南

Multisim汉化实战&#xff1a;从资源修改到自动化部署的完整技术路径你有没有遇到过这样的场景&#xff1f;打开Multisim准备做电路仿真&#xff0c;刚点开“Place”菜单就卡住了——Ground是接地还是电源&#xff1f;Probe到底该译成“探针”还是“探测器”&#xff1f;对于初…

用DFS找出指定长度的简单路径

在图论和计算机科学中,寻找图中所有符合条件的路径是常见的问题之一。今天我们将探讨如何使用深度优先搜索(DFS)来找出一个有向图中从给定顶点出发的所有简单路径,这些路径的长度不超过指定的最大长度k。我们将通过一个具体的实例来展示这个过程,并讨论DFS的优势和一些需要…

STM32下vTaskDelay实现任务延时的完整指南

如何在 STM32 上用vTaskDelay实现高效任务延时&#xff1f;FreeRTOS 多任务调度的底层逻辑全解析你有没有遇到过这样的场景&#xff1a;在一个 STM32 项目中&#xff0c;既要读取传感器数据&#xff0c;又要刷新显示屏、处理串口通信&#xff0c;结果发现主循环卡顿严重&#x…