ESP32+合宙1.8寸屏保姆级教程:MicroPython驱动ST7735显示中文(附固件与字体)
ESP32+合宙1.8寸屏中文显示实战:从零搭建MicroPython开发环境
第一次拿到ESP32开发板和合宙的1.8寸TFT屏幕时,我盯着那堆引脚和陌生的术语发呆了半小时。作为从软件转硬件的开发者,最头疼的就是这种"看起来简单但实际暗藏玄机"的嵌入式项目。本文将用最直白的语言,带你避开我踩过的所有坑,完成从硬件连接到中文显示的全流程。
1. 硬件准备与接线指南
1.1 认识你的硬件装备
在开始接线前,我们需要明确手头的"武器":
- ESP32开发板:推荐使用ESP32-DevKitC,这是最通用的开发板型号
- 合宙1.8寸TFT屏幕:型号通常为ST7735S,分辨率为128x160
- 杜邦线:建议准备10根母对母杜邦线
注意:不同批次的合宙屏幕驱动芯片可能略有差异,但ST7735的驱动方式基本兼容。
1.2 精准接线方案
接线错误是新手最常见的失败原因。以下是经过验证的可靠接线方案:
| 屏幕引脚 | ESP32引脚 | 备注 |
|---|---|---|
| SCK | GPIO18 | 时钟线 |
| SDA | GPIO23 | 数据线 |
| DC | GPIO21 | 数据/命令选择 |
| CS | GPIO16 | 片选信号 |
| RES | GPIO22 | 复位信号 |
| VCC | 3.3V | 电源正极 |
| GND | GND | 电源地 |
常见问题排查:
- 屏幕不亮:检查VCC是否接3.3V而非5V
- 花屏现象:确认所有接线接触良好,特别是GND
- 无任何反应:检查RES引脚是否已正确连接
2. MicroPython固件刷写实战
2.1 固件选择与下载
普通MicroPython固件不支持中文显示,我们需要特殊版本:
# 推荐固件下载命令(Linux/macOS) wget https://github.com/kaixindelele/ssd1306-MicroPython-ESP32-Chinese/releases/download/v1.0/esp32-chinese-0.4.0.binWindows用户可以直接从GitHub页面下载,注意选择对应自己开发板型号的版本。
2.2 使用esptool刷写固件
安装必要的工具:
pip install esptool擦除原有固件(重要!):
esptool.py --port /dev/ttyUSB0 erase_flash写入新固件:
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-chinese-0.4.0.bin提示:如果遇到权限问题,在Linux/macOS上可以尝试在命令前加sudo
3. 驱动与字体文件部署
3.1 上传ST7735驱动库
在Thonny IDE中新建文件,粘贴以下代码并保存为st7735.py:
from time import sleep_ms from ustruct import pack from machine import SPI, Pin import framebuf class ST7735(framebuf.FrameBuffer): # 精简版的驱动类实现 def __init__(self, width, height, spi, dc, rst, cs, rot=0, bgr=0): self.spi = spi self.dc = dc self.rst = rst self.cs = cs self.buffer = bytearray(height * width * 2) super().__init__(self.buffer, width, height, framebuf.RGB565SW) def show(self): self._write(0x2A, pack('>HH', 0, self.width-1)) self._write(0x2B, pack('>HH', 0, self.height-1)) self._write(0x2C, self.buffer)右键点击文件选择"上传到/",将其保存到ESP32设备根目录。
3.2 准备中文字体文件
中文显示需要额外的字体文件,推荐使用12像素的GB2312字体:
- 下载字体文件:GB2312-12.fon
- 通过Thonny的文件管理器上传到设备根目录
字体文件大小约750KB,上传可能需要1-2分钟,请耐心等待。
4. 完整中文显示示例
4.1 基础显示代码
创建一个新的main.py文件,输入以下代码:
import machine import time from st7735 import ST7735 # 硬件初始化 spi = machine.SPI(2, baudrate=20000000, polarity=0, phase=0, sck=machine.Pin(18), mosi=machine.Pin(23)) lcd = ST7735(128, 160, spi, dc=machine.Pin(21), cs=machine.Pin(16), rst=machine.Pin(22), rot=2) # 加载字体 lcd.font_load('/GB2312-12.fon') # 显示中文 lcd.text("MicroPython中文显示", 10, 30, 0xFFFF) lcd.text("合宙1.8寸TFT屏幕", 10, 50, 0x07E0) lcd.text("ESP32驱动示例", 10, 70, 0xF800) lcd.show()4.2 高级显示技巧
实现文字滚动效果:
def scroll_text(display, text, y_pos, color, delay=100): width = len(text) * 12 # 估算文本宽度 for x in range(128, -width, -1): display.fill(0) display.text(text, x, y_pos, color) display.show() time.sleep_ms(delay) scroll_text(lcd, "欢迎使用ESP32中文显示系统", 60, 0xFFFF)创建彩色进度条:
def draw_progress_bar(display, x, y, width, height, progress, color): display.rect(x, y, width, height, color) display.fill_rect(x, y, int(width * progress), height, color) # 使用示例 for p in range(0, 101, 5): draw_progress_bar(lcd, 20, 100, 80, 10, p/100, 0x07E0) lcd.text(f"进度: {p}%", 30, 120, 0xFFFF) lcd.show() time.sleep(0.2)5. 常见问题解决方案
5.1 显示异常排查
花屏/乱码:
- 检查SPI时钟速率是否过高,尝试降低到10MHz
- 确认DC和CS引脚定义正确
- 重新上传字体文件
中文显示为方框:
- 确认字体文件已正确上传
- 检查字体文件路径是否正确
- 确保使用的固件支持中文
5.2 性能优化技巧
当需要频繁刷新显示时:
# 优化后的刷新方法 def optimized_refresh(display, partial=False): if partial: # 只刷新指定区域 display._write(0x2A, pack('>HH', 20, 100)) # X起始和结束 display._write(0x2B, pack('>HH', 30, 80)) # Y起始和结束 else: # 全屏刷新 display._write(0x2A, pack('>HH', 0, 127)) display._write(0x2B, pack('>HH', 0, 159)) display._write(0x2C, display.buffer)5.3 电源管理
为延长电池供电时的使用时间:
# 进入低功耗模式 def sleep_display(display): display._write(0x10) # SLPOUT命令 machine.lightsleep(1000) # 休眠1秒 # 唤醒显示 def wake_display(display): display._write(0x11) # SLPIN命令 display._write(0x29) # DISPON命令6. 项目扩展与进阶应用
6.1 结合传感器数据显示
以温湿度传感器为例:
from dht import DHT11 dht = DHT11(machine.Pin(15)) def update_sensor_data(): dht.measure() lcd.fill(0) lcd.text("当前环境数据:", 10, 20, 0xFFFF) lcd.text(f"温度: {dht.temperature()}℃", 10, 50, 0xF800) lcd.text(f"湿度: {dht.humidity()}%", 10, 80, 0x07E0) lcd.show() # 每2秒更新一次 while True: update_sensor_data() time.sleep(2)6.2 创建简单UI界面
实现按钮交互界面:
button = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) menu_items = ["温度监测", "湿度记录", "系统设置"] current_selection = 0 def draw_menu(): lcd.fill(0) lcd.text("主菜单", 40, 10, 0xFFFF) for i, item in enumerate(menu_items): color = 0x07E0 if i == current_selection else 0xFFFF lcd.text(f"{'>' if i == current_selection else ' '} {item}", 20, 40 + i*20, color) lcd.show() def button_irq(pin): global current_selection current_selection = (current_selection + 1) % len(menu_items) draw_menu() button.irq(trigger=machine.Pin.IRQ_FALLING, handler=button_irq) draw_menu()6.3 网络时钟示例
连接WiFi获取网络时间:
import network import ntptime def connect_wifi(ssid, password): sta_if = network.WLAN(network.STA_IF) if not sta_if.isconnected(): sta_if.active(True) sta_if.connect(ssid, password) while not sta_if.isconnected(): pass return sta_if.ifconfig() def show_network_time(): connect_wifi("your_SSID", "your_password") ntptime.settime() while True: now = time.localtime() lcd.fill(0) lcd.text("网络时钟", 30, 20, 0x07E0) lcd.text(f"{now[0]}-{now[1]}-{now[2]}", 20, 60, 0xFFFF) lcd.text(f"{now[3]}:{now[4]}:{now[5]}", 30, 90, 0xFFFF) lcd.show() time.sleep(1)