ESP32 学习笔记(07)· IIC 驱动 LCD1602 液晶屏

注:本系列为个人学习 ESP32 的记录,主要通过再记录的方式学习,参考和搬运转载极客侠 GeeksMan 的文章。
著作权归极客侠 GeeksMan 所有,基于 GPL 3.0 协议。原文链接:https://docs.geeksman.com/esp32/Arduino/01.esp32-arduino-intro.html
IIC 驱动 LCD1602 液晶屏幕
1. LCD1602 液晶屏
LCD1602 是很多单片机爱好者较早接触的字符型液晶显示器,所以,在这里花点时间是值得的。
1602 液晶屏的称呼来自于其显示的内容容量,其中的 16 代表每行的字符(数字或英文字符)数,02 代表屏幕一共两行,实际开发中根据需要显示信息的内容多少不但可以选用 1602 屏,还可以选用诸如 2004 屏等。如下图:

1602 液晶显示屏除了电源、地以外,有 3 个控制引脚 RS R/W E 和 8 个数据引脚 DB0-7。

2. 认识 IIC(I2C)接口
由于 1602 的管脚数过多,如果直接与 ESP32 开发板连接需要占用大量的 GPIO 管脚,不但容易造成资源浪费,连接也非常不方便。
因此实际使用时往往会给 1602 屏增加一块 IIC 驱动版,将 1602 的 16 个管脚连接到由 PCF8574T 作为主要芯片的驱动版上,将接口转换为 IIC 再连接开发板,具体情况如上图所示。
IIC 是一种硬件设备间常用的接口通讯协议,全称是 Inter-Integrated Circuit,也可以写为 I2C。他的设计时的理念是:信号线尽量少并且速率要尽量高。 信号线少,可以减少引脚占用,这对早期的芯片(引脚很少)的很重要。
使用 IIC 接口时一共需要连接四根线,包括:VCC、GND、SDA、SCL,其中 SDA 和 SCL 需要占用 GPIO 管脚,连接到开发板上任何一组 IIC 接口的对应管脚都可以。
标准的 I2C 需要两根信号线:
- SCL(Serial Clock):时钟线,时钟都是有 master 提供的
- SDA(Serial Data):双向数据线,发数据或者收数据(收发不能同时)
简单来说,只需要 2 根线,就可以对多台设备传输大量数据,减少单片机上 IO 口的占用。
硬件电路设计
将材料按照下图相连:

注意:
注意需要使用开发板上的 5V 电压,而不是 3.3V。真实环境下使用 3.3V 会无法显示或者显示很暗。
这里连接的这两个引脚可不是随便连接的,而是对应了 ESP32 芯片原理图,ESP32 的 I2C 引脚的 SDA 对应 D21,SCL 对应 D22,如图:

软件程序设计
我们可以了解 LiquidCrystal_I2C 库的使用:
LiquidCrystal_I2C(uint8_t addr, uint8_t cols, uint8_t rows):构造函数,用于构造 LCD I2C 对象,参数:addr是地址,默认的是 0x27,cols是 LCD 显示的列数,rows是 LCD 显示的函数;void init():初始化显示屏;void clear():清除 LCD 屏幕上内容,并将光标置于左上角;void home():将光标在定位在屏幕左上角;void noBacklight()与void backlight():是否开启背光;print():显示内容;void leftToRight()与void rightToLeft():控制文字显示的方向,默认是从左向右;void noDisplay()与void display():关闭显示或恢复显示(内容不会丢失);void setCursor(uint8_t col, uint8_t row):设置光标的位置,列,行,基于 0;void noCursor()与void cursor:显示与不显示光标,默认不显示;void noBlink()与void blink():光标是否闪烁,默认不闪烁。
现在,我们就可以写代码了。
1. 在屏幕上显示 Hello,world
了解了第三方库之后,我们先写一个最简单的程序,比如,在屏幕上显示 Hello, world,代码如下:
#include "LiquidCrystal_I2C.h"
// 设置 LCD1602 的地址,列数,行数
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
// 初始化 LCD 对象
lcd.init();
// 打印内容
lcd.backlight();
lcd.print("Hello, world!");
}
void loop()
{
}
2. 读取串口输入内容
在这个程序中,我们需要用到串口的另外两个方法 Serial.available() 与 Serial.read():
Serial.available():返回串口缓冲区中当前剩余的字符个数。一般用这个函数来判断串口的缓冲区有无数据,当Serial.available()>0时,说明串口接收到了数据,可以读取;Serial.read()指从串口的缓冲区取出并读取一个 Byte 的数据,比如有设备通过串口向 Arduino 发送数据了,我们就可以用Serial.read()来读取发送的数据。
//使用`LiquidCrystal_I2C` 库
#include "LiquidCrystal_I2C.h"
// 设置 LCD1602 的地址,列数,行数
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
// 初始化 LCD 对象
lcd.init();
// 开启背光
lcd.backlight();
// 开启串口通信
Serial.begin(9600);
}
void loop()
{
// 检测是否有串口输入
if (Serial.available()) {
// 延时以等待所有数据传输完成
delay(100);
// 清屏
lcd.clear();
// 反复读取串口的数据并在 LCD1602 屏幕上显示,直到数据读完
while (Serial.available() > 0) {
lcd.write(Serial.read());
}
}
}
系列导航:返回目录索引 | 上一篇:06. 数模转换器 ADC 实验 | 下一篇:08. SPI 驱动 OLED 液晶屏(上):Adafruit_SSD1306 库