1. 项目概述与环境搭建

各位同学好,我是你们这门课的讲师。做嵌入式这些年,我接触过不少显示方案,但说实话,I2C 接口的 LCD 驱动一直是我个人很偏爱的一个入门项目。为什么?因为它麻雀虽小五脏俱全——既有通信协议,又有硬件控制,还能立刻看到效果。

这一章,我们先打好基础。把 I2C 是什么、LCD1602 怎么工作的、开发环境怎么搭,一次性理清楚。

1.1 什么是 I2C 协议?

I2C,全称 Inter-Integrated Circuit,是飞利浦公司(现在的 NXP)在 80 年代推出的。说白了,就是让芯片之间能互相说话的一种总线标准。

它只有两根线:

  • SDA(串行数据线)—— 传数据用的
  • SCL(串行时钟线)—— 提供时钟节拍

我刚开始学的时候,总觉得两根线能传数据很神奇。后来自己用逻辑分析仪抓了一次波形,才真正理解——时钟线负责打拍子,数据线在拍子间隙里传 0 和 1,就这么简单。

I2C 的核心特点:

  • 主从架构:一个主设备(比如树莓派 Pico)可以挂多个从设备(比如 LCD、传感器)
  • 每个从设备有唯一地址,7 位或 10 位
  • 标准模式 100 kbps,快速模式 400 kbps
  • 支持多主机,但咱们项目只用单主机

你想想看,如果每个外设都单独拉一堆 GPIO 引脚,板子早就乱成蜘蛛网了。I2C 用两根线就能挂几十个设备,这就是它经久不衰的原因。

1.2 LCD1602 是怎么工作的?

LCD1602,名字就告诉你了——16 个字符 × 2 行。每个字符由 5×8 的点阵组成。

传统的接法需要至少 8 根数据线加几根控制线,非常占引脚。所以市面上出现了 I2C 转接板,把并行接口转成 I2C 串行接口。我们用的就是这种方案。

转接板的核心芯片通常是 PCF8574,一个 I2C 转并行口的 IO 扩展芯片。它负责接收 I2C 总线上的指令,然后模拟出 LCD 需要的并行时序。

避坑指南: 我曾经买过一批便宜的 I2C 转接板,结果发现地址不一样。PCF8574 的默认地址是 0x27,但有些厂家用了 PCF8574A,地址变成 0x3F。所以拿到模块后,第一件事就是用 I2C 扫描程序确认地址。

LCD1602 内部有 DDRAM(显示数据 RAM)和 CGROM(字符生成 ROM)。你往 DDRAM 里写一个 ASCII 码,CGROM 就会自动把对应的点阵显示出来。说白了,你只需要告诉它「在第几行第几列显示什么字符」,剩下的硬件自己搞定。

1.3 硬件准备清单

做这个项目,你需要准备以下硬件:

器件 数量 说明
树莓派 Pico 1 块 RP2040 主控,支持 MicroPython
LCD1602 模块 1 块 带 I2C 转接板(PCF8574)
杜邦线(母对母) 4 根 VCC、GND、SDA、SCL
USB 数据线 1 根 给 Pico 供电和烧录程序
面包板(可选) 1 块 方便接线调试

接线非常简单:

  • LCD 的 VCC → Pico 的 3.3V(或 5V,看模块规格)
  • LCD 的 GND → Pico 的 GND
  • LCD 的 SDA → Pico 的 GP0(I2C0 的 SDA)
  • LCD 的 SCL → Pico 的 GP1(I2C0 的 SCL)

注意: 有些 LCD 模块需要 5V 供电才能正常工作,但 Pico 的 GPIO 是 3.3V 逻辑。好在 I2C 是开漏输出,加上转接板上有电平转换,一般没问题。但如果你的模块不亮,先查供电电压。

1.4 搭建 Python 开发环境

我们使用 MicroPython,因为它上手快、调试方便。我个人习惯用 Thonny IDE,对新手很友好。

环境搭建步骤:

  1. 下载 Thonny:从 thonny.org 下载安装包,装好就行
  2. 烧录 MicroPython 固件:
    • 按住 Pico 上的 BOOTSEL 键,插上 USB
    • Thonny 右下角选择「MicroPython (Raspberry Pi Pico)」
    • 点击「安装或更新固件」,选择下载好的 .uf2 文件
  3. 验证环境:在 Shell 里输入 print("Hello Pico"),能看到输出就对了

小技巧: 我第一次烧录时忘了按 BOOTSEL 键,折腾了十分钟。记住:先按住按键,再插 USB,等电脑识别出「RPI-RP2」盘符再松手。

1.5 扫描 I2C 设备

硬件接好了,环境搭好了,怎么知道 I2C 通不通?写个扫描程序:

from machine import Pin, I2C

# 初始化 I2C0,SDA=GP0,SCL=GP1
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)

# 扫描总线上的设备
devices = i2c.scan()
if devices:
    print("找到 I2C 设备,地址:")
    for addr in devices:
        print(hex(addr))
else:
    print("没有找到 I2C 设备,请检查接线")

运行后如果打印出 0x27 或 0x3F,恭喜你,硬件通了。如果什么都没显示,嗯,我曾经也遇到过——多半是线松了,或者地址不对。

1.6 本章知识体系

下面这张图帮你理清这一章的核心脉络:

第1章 知识体系结构 I2C LCD 驱动入门 I2C 协议基础 LCD1602 工作原理 开发环境搭建 SDA / SCL 主从架构 5×8 点阵 PCF8574 MicroPython 核心目标:理解 I2C 通信原理,掌握 LCD 驱动基础 完成硬件接线与环境验证,为后续编程做好准备

这一章我们完成了三件事:理解了 I2C 协议的核心思想、搞清了 LCD1602 配合转接板的工作原理、搭好了开发环境并验证了硬件通信。这些都是后面写驱动代码的基石。