ESP32 LCD1602显示实验报告
实验报告
实验名称 :ESP32 LCD1602显示实验
实验环境:ESP32开发板、LCD1602液晶显示屏(I2C接口)、VS Code + ESP-IDF、Arduino IDE、MicroPython
一、实验目的
1.1 基本目标
- 理解LCD1602液晶显示器的工作原理和驱动方法
- 掌握ESP32与LCD1602(I2C接口)的硬件连接方式
- 掌握ESP-IDF、Arduino和MicroPython三种开发环境下I2C设备的编程方法
- 实现LCD1602显示文字信息和动态计数功能
1.2 进阶目标
- 理解I2C通信协议的基本原理
- 掌握PCF8574T I/O扩展芯片的工作机制
- 学习不同开发环境下I2C驱动的使用方法
- 掌握LCD初始化和命令发送的时序要求
1.3 知识点覆盖
- I2C总线通信协议(起始条件、停止条件、数据有效性)
- LCD1602(HD44780控制器)的工作原理
- PCF8574T I/O扩展芯片的引脚映射关系
- 4位并行数据传输模式
- LCD初始化序列和命令集
二、实验原理
2.1 LCD1602显示器概述
LCD1602是一种字符型液晶显示模块,采用Hitachi HD44780控制器,可显示2行、每行16个字符。每个字符由5×8点阵构成,支持自定义字符和标准ASCII字符集。
2.2 HD44780控制器指令集
HD44780控制器提供了一系列控制命令,用于设置显示模式、光标位置和清屏等操作。主要命令包括:清屏命令(0x01)、光标归位命令(0x02)、输入模式设置命令(0x06)、显示开关控制命令(0x0C)、功能设置命令(0x28)和光标定位命令(0x80)。
2.3 I2C接口与PCF8574T
标准LCD1602需要至少6个I/O引脚(RS、RW、E、D4-D7),为节省引脚资源,通常使用PCF8574T I2C扩展芯片。PCF8574T将I2C总线信号转换为并行数据,通过8位输出端口控制LCD。其引脚映射关系为:P0对应RS(命令/数据选择)、P1对应RW(读/写控制,通常接地)、P2对应E(使能信号)、P3对应背光控制、P4至P7分别对应D4至D7数据线。
2.4 4位数据传输模式
为减少引脚占用,LCD1602通常工作在4位模式。在该模式下,每个字节需要分两次传输:先发送高4位,再发送低4位。每次传输都需要配合使能信号(E)产生上升沿,使LCD锁存数据。
2.5 I2C通信协议
I2C(Inter-Integrated Circuit)是一种两线式串行通信总线,使用SDA(数据线)和SCL(时钟线)两条信号线。通信过程包括:起始条件(SCL高电平时SDA下降沿)、地址发送(7位设备地址加读写位)、数据传输(每字节后跟应答位)、停止条件(SCL高电平时SDA上升沿)。
2.6 LCD初始化时序
LCD1602在上电后需要按照特定时序进行初始化,包括:等待电源稳定(50ms)、发送三次0x30命令进行4位模式切换、设置显示参数(2行、5×8点阵)、开启显示并关闭光标、清屏、设置输入模式(地址递增)。严格的时序要求是LCD正常工作的关键。
2.7 三种开发环境对比
|------------|-----------------|-----------------|---------------------|
| 特性 | ESP-IDF | Arduino | MicroPython |
| 驱动实现 | 底层寄存器操作 | 库函数封装 | 类封装 |
| I2C初始化 | 配置结构体 | Wire库自动 | 简洁一行 |
| LCD初始化 | 手动发送命令序列 | 库自动处理 | 手动或库 |
| 代码复杂度 | 较高 | 低 | 最低 |
| 调试便利性 | 中等 | 好 | 最好 |
三、实验设备与材料
3.1 硬件清单
|--------------|------------------|------------|------------|
| 设备名称 | 型号/规格 | 数量 | 用途 |
| ESP32开发板 | ESP32-WROOM-32 | 1块 | 主控单元 |
| LCD1602模块 | 带I2C背板(PCF8574T) | 1个 | 字符显示 |
| 杜邦线 | 公对母 | 4根 | I2C连接 |
| USB数据线 | Type-C/Micro | 1根 | 供电与下载 |
3.2 软件环境
ESP-IDF开发环境:
- 操作系统:Windows 10/11 或 Ubuntu 20.04
- VS Code版本:1.80+
- ESP-IDF版本:v5.1
- 插件:Espressif IDF
Arduino开发环境:
- Arduino IDE版本:2.0+
- ESP32板包版本:3.3.7
- 库依赖:LiquidCrystal_I2C
MicroPython开发环境:
- MicroPython固件版本:v1.20+
- 开发工具:Thonny IDE 4.0+
- Python版本:3.8+
3.3 I2C地址说明
LCD1602 I2C模块的默认地址通常为0x27或0x3F,具体取决于背板电路设计。实验中可通过I2C扫描程序检测实际地址。
3.4 硬件连接说明
LCD1602 I2C模块与ESP32开发板通过4根线连接:VCC接3.3V或5V电源、GND接地、SDA接GPIO21、SCL接GPIO22。连接时应确保电源线接触良好,避免通信不稳定。LCD背面的蓝色电位器用于调节屏幕对比度,如显示方块可适当旋转调节。
四、实验内容与步骤
4.1 实验内容划分
本实验分为两个子任务:
|--------------|--------------|----------------------|
| 任务编号 | 任务名称 | 功能描述 |
| 任务A | LCD基本显示 | 在LCD上显示静态文本信息 |
| 任务B | LCD动态计数 | LCD第二行显示递增计数,背光周期性闪烁 |
4.2 实验步骤
步骤1:环境搭建
- 安装VS Code和ESP-IDF插件
- 安装Arduino IDE和ESP32板包及LiquidCrystal_I2C库
- 安装Thonny IDE和MicroPython固件
步骤2:硬件连接
- 将LCD1602的VCC连接到ESP32的3.3V
- 将LCD1602的GND连接到ESP32的GND
- 将LCD1602的SDA连接到ESP32的GPIO21
- 将LCD1602的SCL连接到ESP32的GPIO22
步骤3:I2C地址检测
- 编写I2C扫描程序
- 运行程序获取LCD的实际I2C地址
- 记录地址供后续使用
步骤4:代码编写
- 分别使用三种环境编写任务A代码
- 分别使用三种环境编写任务B代码
步骤5:编译烧录
- 依次编译三种环境的代码
- 烧录到ESP32开发板
步骤6:验证测试
- 观察LCD是否正常显示文字
- 验证计数功能是否正常工作
- 验证背光闪烁功能
步骤7:分析总结
- 对比三种环境的开发体验
- 记录遇到的问题和解决方案
五、基于ESP-IDF的代码实现
5.1 I2C初始化
ESP-IDF环境下使用driver/i2c.h提供的API进行I2C总线配置。配置过程包括:设置I2C主机模式、指定SDA和SCL引脚、配置时钟频率(100kHz)、使能内部上拉电阻。通过i2c_param_config函数应用配置,i2c_driver_install函数安装驱动程序。
5.2 LCD驱动实现
LCD驱动需要实现的核心功能包括:I2C单字节写入函数、4位数据发送函数、字节发送函数(分两次4位)、命令发送函数和数据发送函数。所有函数都需要包含适当的延时以满足LCD的时序要求。
5.3 LCD初始化序列
初始化序列严格按照HD44780规范实现:上电后等待50ms、连续发送三次0x30命令切换到4位模式、发送0x28设置4位模式双行显示、发送0x0C开启显示关闭光标、发送0x01清屏、发送0x06设置地址递增模式。每个命令后需添加适当延时。
5.4 显示功能实现
显示功能包括:清屏函数、光标定位函数、字符串打印函数和格式化打印函数。光标定位函数根据行号(0或1)和列号(0至15)计算DDRAM地址,然后发送定位命令。字符串打印函数逐个字符发送到LCD。

5.5 主程序逻辑
主程序首先初始化I2C总线和LCD,然后显示启动信息"ESP32 LCD1602"和"I2C OK!"。在主循环中,计数器每秒递增一次,更新第二行显示内容。每5次计数时闪烁背光一次,提供视觉反馈。
六、基于Arduino的代码实现
6.1 库依赖
Arduino环境下使用LiquidCrystal_I2C库,该库封装了底层I2C通信细节,提供简洁的API接口。使用前需在库管理器中搜索安装。
6.2 I2C地址检测
Arduino提供了Wire库用于I2C通信。地址检测程序通过循环扫描0x01至0x7F地址范围,使用Wire.beginTransmission和Wire.endTransmission函数检测设备响应,记录有响应的地址。
6.3 LCD初始化
使用LiquidCrystal_I2C库时,初始化过程非常简单:创建LiquidCrystal_I2C对象并传入I2C地址和LCD尺寸参数,调用init方法初始化,调用backlight方法开启背光,调用clear方法清屏。
6.4 显示功能
库提供的显示函数包括:setCursor设置光标位置、print打印字符串、clear清屏、createChar创建自定义字符。这些函数封装了底层的命令发送和数据传输,大大简化了开发工作。

6.5 主程序逻辑
主程序结构与ESP-IDF版本类似,但代码量大幅减少。在setup函数中完成LCD初始化后,loop函数循环更新计数显示,使用库函数进行字符串格式化和打印。
七、基于MicroPython的代码实现
7.1 I2C初始化
MicroPython使用machine.I2C类进行I2C操作,初始化代码非常简洁:I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)。I2C扫描使用i2c.scan()方法直接返回设备地址列表。
7.2 驱动实现方式
MicroPython环境下有两种实现方式:手动编写底层驱动或使用第三方库。手动驱动需要实现PCF8574T的位操作逻辑,包括背光控制、使能脉冲生成、4位数据发送等。这种方式的优点是理解深入、无依赖,但代码量较大。
7.3 LCD初始化
手动初始化时需严格遵循时序要求:初始延时、初始化序列发送、功能设置、显示模式设置、清屏和输入模式设置。时序错误会导致LCD不显示或显示异常。

7.4 I2C通信注意事项
MicroPython的I2C写入使用writeto方法,参数为地址和字节数据。需要注意的是,PCF8574T要求每发送一个字节后有一定延时,否则LCD可能无法正确锁存数据。使能脉冲的时序也需精确控制。
7.5 主程序逻辑
主程序首先扫描I2C总线确认LCD地址,然后初始化LCD并显示启动信息。主循环中更新计数器并刷新第二行显示,同时实现周期性背光闪烁功能。异常处理机制可在通信错误时自动重试。
八、实验结果与分析
8.1 功能验证结果
|--------------|-----------------|-----------------|---------------------|------------|
| 测试项目 | ESP-IDF | Arduino | MicroPython | 结果 |
| I2C设备识别 | 正常 | 正常 | 正常 | 通过 |
| LCD初始化 | 正常 | 正常 | 正常 | 通过 |
| 静态文字显示 | 正常 | 正常 | 正常 | 通过 |
| 动态计数显示 | 正常 | 正常 | 正常 | 通过 |
| 背光控制 | 正常 | 正常 | 正常 | 通过 |
8.2 I2C地址检测结果
通过扫描程序检测,LCD1602 I2C模块的实际地址通常为0x27或0x3F。不同批次的背板可能使用不同地址,实验前必须进行地址确认。
8.3 显示效果
LCD正常工作时,第一行显示"ESP32 LCD1602",第二行显示"I2C OK!",随后第二行变为"Cnt: 0001"并每秒递增。背光每5秒闪烁一次,提供明显的视觉反馈。
8.4 三种环境对比分析
|------------|-----------------|-------------------|---------------------|
| 指标 | ESP-IDF | Arduino | MicroPython |
| 代码行数 | 约200行 | 约50行 | 约150行(手动) |
| 开发难度 | 较高 | 低 | 中等 |
| 执行效率 | 最高 | 中等 | 较低 |
| 依赖库 | 无 | LiquidCrystal_I2C | 无或第三方 |
| 调试便利性 | 中等 | 好 | 最好 |
| 适用场景 | 产品开发 | 快速原型 | 教学测试 |
九、实验总结
9.1 实验收获
通过本实验,掌握了LCD1602液晶显示器的工作原理和驱动方法,理解了I2C通信协议和PCF8574T扩展芯片的工作机制。能够在ESP-IDF、Arduino和MicroPython三种环境下实现I2C设备驱动,掌握了不同开发环境的特点和适用场景。
9.2 技术要点总结
LCD初始化时序是驱动开发的关键,严格的延时要求必须满足。I2C通信的地址检测是调试的第一步,确认地址正确才能进行后续开发。4位数据传输模式下字节的分包发送和使能脉冲生成是驱动实现的核心。背光控制和对比度调节影响显示效果,需要正确配置。
9.3 三种环境适用场景
ESP-IDF适合对性能和资源有严格要求的商业产品开发,代码效率最高但开发周期较长。Arduino适合快速原型验证和初学者学习,丰富的库支持大幅降低开发难度。MicroPython适合教学演示和快速测试,交互式环境便于调试,但性能和内存占用是限制因素。