
1. 项目概述从“点阵”到“视界”的微型革命如果你玩过Arduino或者树莓派对那种经典的1602字符液晶屏一定不陌生。它确实能显示信息但那个蓝底白字的界面总让人觉得离“现代显示”差了那么点意思。后来我们有了OLED有了IPS显示效果是上去了但价格和功耗也上去了。直到我遇到了“Pico LCD 0.96”这个项目它像是一个精巧的平衡点在一块比拇指指甲盖大不了多少的屏幕上实现了160x80的全彩显示核心驱动板甚至比屏幕本身还小直接插在树莓派Pico的GPIO上就能用。这不仅仅是给Pico加了个“脸”更是打开了一扇通往微型、低功耗、高集成度交互界面的大门。这个项目本质上是一个为树莓派PicoRP2040微控制器量身定制的SPI接口彩色LCD显示屏模块。它的核心价值在于以极低的硬件成本和极简的连接方式为嵌入式开发、物联网设备、便携式仪器乃至桌面小摆件提供了一个功能完备的图形化人机交互界面。你不再需要为了显示几个图标、一段动画或者一个简单的菜单去动用尺寸和功耗都大得多的屏幕。对于创客、学生和产品原型开发者来说Pico LCD 0.96是一个近乎完美的“瑞士军刀”式显示解决方案。它解决的是在资源受限的微控制器平台上实现“看得见、看得清、看得美”的显示需求。2. 核心硬件拆解麻雀虽小五脏俱全拿到Pico LCD 0.96模块第一印象就是紧凑。整个模块由两部分构成一块0.96英寸的IPS液晶面板和一块集成了驱动芯片、背光电路和FPC连接器的PCB底板。这种分体式设计很聪明既降低了整体模组的高度也方便未来更换不同规格的屏幕。2.1 屏幕面板IPS技术的降维打击这块0.96英寸的屏幕采用的是IPSIn-Plane Switching平面转换技术。相较于早期单片机常用的TN屏IPS屏的最大优势就是可视角度极大。你从几乎任何角度看过去色彩和亮度都不会有严重的失真或变色。这对于一个可能被放在桌角、拿在手里不同角度观看的小设备来说体验提升是巨大的。其分辨率为160x80像素虽然听起来不高但考虑到屏幕对角线只有0.96英寸约24.4毫米其像素密度PPI达到了惊人的约202显示文字和简单图形已经非常锐利完全没有颗粒感。屏幕的接口是标准的RGB 65K色16位色深RGB565格式并行接口。但模块的巧妙之处在于它并没有让Pico直接驱动这个并行接口那样会占用大量宝贵的GPIO引脚。2.2 驱动核心ST7789V与“降速”哲学模块的“大脑”是一颗ST7789V驱动芯片。这是一款非常经典的TFT LCD驱动器支持最高172320的分辨率和18位色深。在我们的模块上它被配置为驱动16080的屏幕。ST7789V本身功能强大但Pico LCD 0.96模块在设计上做了一个关键取舍为了节省Pico的GPIO引脚模块将ST7789V配置为使用4线SPI串行外设接口通信而非并口。这里就涉及到一个核心问题速度。SPI是串行通信一次只能传输一位数据而并口可以一次传输多位例如8位、16位。对于刷屏这种需要传输大量像素数据的操作SPI在理论上是慢的。但模块设计者非常聪明他们利用了ST7789V的一个特性它内部有一个显存GRAM。我们通过SPI发送的绘图指令和数据并不是直接“画”到屏幕上而是先写入到这片GRAM里。写入完成后再发送一个指令ST7789V就会自动、并以它自己的高速时钟将GRAM里的内容刷新到液晶面板上。这样一来SPI的带宽瓶颈主要影响的是我们向GRAM写数据的速度而不影响最终的屏幕刷新观感。对于160*80这种小分辨率以及大多数嵌入式应用并不需要极高帧率比如游戏的场景这个速度是完全够用的。注意很多新手会纠结于SPI的刷屏速度。实测在Pico上将SPI时钟频率设置到30-40MHz全屏填充一种颜色的速度可以达到每秒60帧以上绘制复杂图形或文字时帧率会下降但用于UI界面、数据显示等场景依然非常流畅。盲目追求极限帧率对于这类显示模块意义不大。2.3 接口与供电极简主义的胜利模块的PCB底板设计极致简洁。面向用户的一面除了屏幕只有一个电容和几个电阻。背面则是它的精髓一个标准的“邮票孔”封装引脚定义与树莓派Pico的GPIO完美对应。你只需要像插内存条一样将模块对准Pico的引脚插下去即可无需任何飞线。这大大降低了使用门槛和出错概率。主要用到的引脚如下SPI接口GPIO18(SCK),GPIO19(MOSI/TX)。注意这里只用了MOSI因为屏幕是只写的不需要从屏幕读数据MISO。控制引脚GPIO20(DC),GPIO21(CS),GPIO22(RST)。DC数据/命令引脚用于区分发送的是指令还是像素数据CS片选用于选中该SPI设备RST复位用于硬件复位屏幕。背光控制GPIO26。这是一个非常实用的设计允许我们通过PWM脉冲宽度调制来控制屏幕背光的亮度甚至实现呼吸灯效果对于电池供电的设备可以有效节能。电源直接使用Pico的3V3(OUT)和GND。这种“即插即用”的设计让硬件准备时间几乎为零开发者可以立刻专注于软件和功能的实现。3. 软件驱动与图形库选型硬件连接简单软件生态同样丰富。针对Pico LCD 0.96社区主要有几种驱动方式各有优劣。3.1 基础SPI驱动从零开始理解最底层的方式是直接操作Pico的SPI硬件和GPIO按照ST7789V的数据手册编写初始化序列和基本绘图函数。这个过程包括初始化SPI设置时钟频率、相位、极性等。初始化屏幕通过一系列特定的命令如设置扫描方向、颜色模式、打开显示等来配置ST7789V。实现基本函数如set_window(x, y, width, height)设置绘图区域、draw_pixel(x, y, color)、fill_rect(x, y, width, height, color)等。这个过程对于学习嵌入式显示原理非常有帮助但效率较低且功能单一。通常我们不会从头开始写而是以某个现有开源库为基础。3.2 LVGL嵌入式GUI的“重型武器”LVGLLight and Versatile Graphics Library是一个功能极其强大的开源嵌入式图形库。它支持动画、抗锯齿、透明效果、多种字体、主题、控件按钮、滑块、列表等几乎可以让你在单片机上实现类似智能手机的交互界面。将LVGL移植到Pico LCD 0.96上是一个经典项目。你需要提供LVGL所需的“显示驱动”和“输入设备驱动”接口。对于只有显示的模块就是实现一个flush_cb回调函数这个函数负责将LVGL绘制好的图像区域数据通过SPI写入到屏幕的GRAM中。优点功能无比强大适合制作复杂的用户界面。缺点资源消耗相对较大RAM和Flash对于只有264KB RAM的Pico来说需要精细配置学习曲线较陡如果只是显示些静态信息或简单动画有点“杀鸡用牛刀”。3.3 PicoGraphics来自官方的“轻量甜点”这是由树莓派官方Pimoroni团队为Pico生态开发的一个轻量级图形库。它被集成在Pico的MicroPython固件和SDK中与硬件结合得非常好。PicoGraphics的API非常直观易于上手并且针对RP2040的PIO可编程输入输出和DMA直接内存访问特性做了优化绘图效率很高。对于Pico LCD 0.96通常使用st7789驱动模块配合PicoGraphics。几行代码就能初始化屏幕并开始画图。它提供了点、线、矩形、圆、三角形等基本图元绘制位图显示以及字体渲染功能。虽然控件系统不如LVGL丰富但对于大多数信息显示、简单交互和创意可视化项目来说完全够用且性能与资源占用平衡得极好。# 基于MicroPython和PicoGraphics的示例代码片段 import st7789 import picographics from machine import Pin, SPI # 初始化SPI和屏幕 spi SPI(0, baudrate40000000, polarity1, phase1, sckPin(18), mosiPin(19)) display st7789.ST7789(spi, 80, 160, resetPin(22, Pin.OUT), dcPin(20, Pin.OUT), csPin(21, Pin.OUT), backlightPin(26, Pin.OUT)) graphics picographics.PicoGraphics(displaydisplay) # 设置颜色和绘图 BLACK graphics.create_pen(0, 0, 0) WHITE graphics.create_pen(255, 255, 255) graphics.set_pen(BLACK) graphics.clear() graphics.set_pen(WHITE) graphics.text(Hello Pico!, 10, 10, scale2) display.update(graphics)实操心得对于初学者和希望快速出效果的项目我强烈推荐从PicoGraphics入手。它的学习成本低社区支持好性能足够。当你的项目需要复杂的菜单系统、滑动列表等高级UI时再考虑挑战LVGL。不要一开始就追求大而全合适的就是最好的。4. 项目实战打造一个桌面系统监控器理论说再多不如动手做一个东西。我们用一个实际项目来串联所有知识点制作一个通过USB连接电脑实时显示电脑CPU、内存使用率的桌面小监控器。4.1 系统架构设计这个项目的核心思路是PC端Python脚本在电脑上运行一个Python脚本利用psutil库周期性地如每秒获取系统状态CPU%、内存%。通信链路将获取到的数据通过串口USB CDC发送给Pico。Pico通过USB连接到电脑会被识别为一个串行设备COM口或/dev/ttyACM0。Pico端MicroPythonPico上的程序持续监听串口收到数据后解析出CPU和内存的百分比。显示端使用PicoGraphics库将解析出的数据以进度条、数字和图表的形式美观地绘制在Pico LCD 0.96屏幕上。为什么选择串口因为它简单、通用、可靠几乎不需要额外配置非常适合这种小数据量、中低速率的双向通信。4.2 PC端数据采集与发送电脑端的Python脚本非常简单。你需要安装psutil和pyserial库。# pc_monitor_sender.py import psutil import serial import time import json # 配置串口端口名需要根据实际情况修改如‘COM3’(Windows)或‘/dev/ttyACM0’(Linux/Mac) ser serial.Serial(YOUR_PICO_COM_PORT, 115200, timeout1) try: while True: # 获取系统状态 cpu_percent psutil.cpu_percent(intervalNone) # 非阻塞式获取 memory_info psutil.virtual_memory() mem_percent memory_info.percent # 构建JSON格式数据 data { cpu: round(cpu_percent, 1), mem: round(mem_percent, 1) } json_str json.dumps(data) \n # 加换行符作为帧分隔符 # 通过串口发送 ser.write(json_str.encode(utf-8)) print(fSent: {json_str.strip()}) time.sleep(1) # 每秒发送一次 except KeyboardInterrupt: print(Monitor stopped.) finally: ser.close()注意务必找到正确的串口号。你可以在设备管理器中查看或者在Pico的代码里打印出来。波特率双方必须设置一致这里使用115200是一个兼顾速度和稳定性的常用值。4.3 Pico端数据接收与显示Pico端使用MicroPython编写。核心任务是解析JSON并动态更新显示。# main.py on Pico import json from machine import UART, Pin import st7789 import picographics import time # 1. 初始化屏幕 (同上文示例) spi SPI(0, baudrate40000000, polarity1, phase1, sckPin(18), mosiPin(19)) display st7789.ST7789(spi, 80, 160, resetPin(22), dcPin(20), csPin(21), backlightPin(26)) graphics picographics.PicoGraphics(displaydisplay) WIDTH, HEIGHT graphics.get_bounds() # 2. 初始化串口 (USB CDC) uart UART(0, baudrate115200, txPin(0), rxPin(1)) uart.init(baudrate115200, bits8, parityNone, stop1) # 3. 定义颜色和UI元素位置 colors { bg: graphics.create_pen(20, 20, 40), # 深蓝背景 text: graphics.create_pen(220, 220, 220), # 亮灰文字 cpu_bar: graphics.create_pen(0, 200, 255), # 青色CPU进度条 mem_bar: graphics.create_pen(255, 100, 0), # 橙色内存进度条 grid: graphics.create_pen(60, 60, 80) # 网格线颜色 } # 绘制静态界面只画一次 def draw_static(): graphics.set_pen(colors[bg]) graphics.clear() graphics.set_pen(colors[text]) graphics.text(CPU:, 5, 5, scale2) graphics.text(MEM:, 5, 45, scale2) # 画一个简单的网格背景 graphics.set_pen(colors[grid]) for x in range(0, WIDTH, 10): graphics.line(x, 0, x, HEIGHT) for y in range(0, HEIGHT, 10): graphics.line(0, y, WIDTH, y) display.update(graphics) # 绘制动态数据进度条和数字 def draw_dynamic(cpu_val, mem_val): # 清空动态区域进度条和数字区域可以用矩形填充背景色 graphics.set_pen(colors[bg]) graphics.rectangle(70, 5, 85, 25) # 覆盖CPU数字区域 graphics.rectangle(70, 45, 85, 25) # 覆盖MEM数字区域 graphics.rectangle(5, 30, 150, 10) # 覆盖CPU进度条 graphics.rectangle(5, 70, 150, 10) # 覆盖MEM进度条 # 绘制CPU进度条和数字 bar_width int(150 * (cpu_val / 100.0)) graphics.set_pen(colors[cpu_bar]) graphics.rectangle(5, 30, bar_width, 10) graphics.set_pen(colors[text]) graphics.text(f{cpu_val:.1f}%, 70, 5, scale2) # 绘制内存进度条和数字 bar_width int(150 * (mem_val / 100.0)) graphics.set_pen(colors[mem_bar]) graphics.rectangle(5, 70, bar_width, 10) graphics.set_pen(colors[text]) graphics.text(f{mem_val:.1f}%, 70, 45, scale2) # 更新显示 display.update(graphics) # 主循环 draw_static() # 绘制静态界面 last_cpu, last_mem 0, 0 while True: if uart.any(): # 检查串口是否有数据 try: # 读取一行JSON数据 line uart.readline().decode(utf-8).strip() data json.loads(line) cpu data.get(cpu, 0) mem data.get(mem, 0) # 只有数据变化时才刷新减少不必要的绘图操作 if abs(cpu - last_cpu) 0.1 or abs(mem - last_mem) 0.1: draw_dynamic(cpu, mem) last_cpu, last_mem cpu, mem except (UnicodeError, json.JSONDecodeError) as e: # 忽略解析错误继续下一轮循环 pass time.sleep(0.05) # 短暂延时降低CPU占用这个项目综合运用了串口通信、JSON解析、图形绘制和优化刷新等技巧。你将得到一个摆在桌面上实时跳动、颜值在线的系统监控小工具。5. 性能优化与深度调优技巧当你的项目变得复杂或者对流畅度有更高要求时基础的绘图方式可能会遇到性能瓶颈。以下是几个从实践中总结的优化策略。5.1 利用RP2040的PIO提升SPI速率RP2040的PIO是其秘密武器是可编程的状态机能独立于CPU处理I/O任务。我们可以用PIO来实现一个“硬件加速”的SPI释放CPU负担并可能达到更高的时钟频率。MicroPython的st7789驱动底层已经使用了PIO来驱动SPI这通常比纯软件模拟SPI快得多。在初始化时确保你的SPI波特率设置得足够高例如baudrate40000000即40MHz。这是最直接有效的提速方法。5.2 局部刷新与脏矩形技术全屏刷新display.update(graphics)会更新整个帧缓冲区到屏幕即使只改了一个像素。对于小屏幕全刷开销尚可接受但为了极致效率和降低功耗可以采用“脏矩形”技术。原理只记录屏幕上发生变化的矩形区域在更新时只向屏幕发送这个矩形区域内的像素数据。ST7789V的set_window(x, y, w, h)指令就是为此设计的。在PicoGraphics中虽然库本身不直接暴露脏矩形API但你可以通过组合使用set_clip设置裁剪区域和remove_clip然后调用update来模拟实现局部更新。不过这需要你手动管理哪些区域需要更新。对于UI变化不频繁的场景如我们的监控器在数据变化时才更新特定区域如进度条和数字区域就是一种简单有效的局部刷新。5.3 帧缓冲区与双缓冲更高级的优化是使用帧缓冲区。PicoGraphics本身维护着一个帧缓冲区在RAM中。我们所有的绘图操作都是在这个缓冲区里进行的。display.update()将这个缓冲区的数据搬运到屏幕。对于动态内容非常复杂的场景可以考虑“双缓冲”在内存中开辟两个图形缓冲区。在一个缓冲区后台缓冲区进行下一帧的绘制时屏幕显示当前帧前台缓冲区。绘制完成后交换两个缓冲区。这可以避免屏幕撕裂即看到一半新一半旧的图像。不过对于160x80x2字节约25.6KB的缓冲区双缓冲意味着需要约51.2KB的RAM这对Pico的264KB RAM来说是个不小的负担需要谨慎使用。PicoGraphics默认是单缓冲在大多数情况下已经足够。实操心得不要过早优化。首先让功能正确运行。当发现明显的卡顿比如动画不连贯时再分析瓶颈。通常最大的性能提升来自于1)减少不必要的绘制如我们的监控器只在数据变化时重绘2)使用高效的图元用rectangle填充代替多个pixel画点3)提高SPI时钟频率。这三板斧下去99%的性能问题都能解决。6. 常见问题与故障排查实录无论项目多简单踩坑总是难免的。下面是我在折腾Pico LCD 0.96过程中遇到的一些典型问题及解决方法。6.1 屏幕白屏或花屏这是最常见的问题通常与初始化序列或接线有关。排查步骤检查电源首先确认Pico的3.3V输出正常模块供电稳定。可以用万用表量一下模块VCC和GND之间的电压。检查接线确保模块与Pico的引脚对应关系完全正确没有虚焊或插反。特别注意有些模块的背光引脚BL默认需要高电平点亮而我们的示例代码中backlightPin(26, Pin.OUT)在初始化后可能默认为低电平需要手动拉高Pin(26, Pin.OUT).value(1)。检查SPI配置ST7789V通常需要SPI Mode 1或Mode 3即CPOL和CPHA的组合。示例中的polarity1, phase1对应Mode 3。如果屏幕出现规律条纹或颜色错乱可以尝试改为polarity0, phase0Mode 0或polarity1, phase0Mode 2。最可靠的方法是查阅你购买模块的具体资料或示例代码。检查复位时序确保RST引脚有正确的复位脉冲拉低至少10ms再拉高。驱动库通常会处理这个但如果自己写驱动时序不对会导致初始化失败。降低SPI速率如果以上都正确尝试将SPI波特率从40000000降低到10000000甚至更低排除因布线不良导致的高速通信错误。6.2 显示方向不对或颜色异常显示方向屏幕的显示方向0° 90° 180° 270°是通过发送特定的命令MX,MY,MV等给ST7789V来设置的。在驱动库的初始化函数中通常会有rotation参数。例如在st7789.ST7789初始化时可以传入rotation90来旋转90度。如果上下或左右颠倒调整这个参数即可。颜色异常偏色这几乎总是颜色格式不匹配导致的。ST7789V支持多种颜色格式如RGB565、RGB666等。我们的模块通常配置为RGB56516位色红5位绿6位蓝5位。如果你的代码发送的是24位RGB数据每个颜色8位或者字节顺序BGR vs RGB不对就会显示奇怪的颜色。确保你的图形库如PicoGraphics的颜色生成函数create_pen和屏幕驱动配置的颜色格式一致。6.3 通信不稳定或数据错误现象显示内容偶尔错乱、串口接收数据丢包。排查电源干扰这是嵌入式系统最常见的问题之一。当电机、继电器等大电流设备工作时可能导致电源电压波动影响微控制器和屏幕的稳定运行。确保为Pico和屏幕模块提供干净、稳定的电源必要时在电源入口处加一个100uF的电解电容并联一个0.1uF的瓷片电容进行滤波。接线过长或凌乱SPI是高速信号如果连接线过长比如超过10cm或者像“鸟巢”一样杂乱容易引入干扰和信号反射。尽量使用短而整齐的连线杜邦线不要散开。共地问题如果系统中存在多个设备如电脑、Pico、另一个传感器务必确保所有设备的GND地线连接在一起形成一个共同的参考电位否则通信电平会错乱。代码逻辑错误检查你的数据发送和接收代码是否有缓冲区溢出、没有处理异常、或解析逻辑有误。添加适当的错误处理try...except和调试打印print是快速定位问题的好方法。6.4 背光无法调节或控制现象背光常亮或常灭无法通过PWM调节亮度。解决确认背光控制引脚是否正确。有些模块的背光是高电平点亮有些是低电平点亮。查看模块原理图或商家说明。确认你的代码是否正确配置了该引脚为PWM输出。在MicroPython中需要先from machine import PWM然后pwm PWM(Pin(26))再设置频率和占空比pwm.freq(1000); pwm.duty_u16(32768)50%亮度。如果模块背光电路是简单的晶体管驱动PWM频率不宜过高通常500Hz到1KHz即可频率太高可能由于晶体管开关损耗导致无法有效调节。7. 创意扩展与项目思路掌握了基础这个小屏幕的潜力远不止显示几个数字。它的低功耗、小体积和彩色显示能力可以融入无数有趣的创意项目。1. 微型游戏机利用Pico的双核和PIO完全可以实现一些经典游戏的复刻比如贪吃蛇、打砖块、Flappy Bird。PicoGraphics足以绘制这些游戏的图形。你可以用几个按钮或者一个摇杆模块作为输入。2. 物联网信息站让Pico连接Wi-Fi通过ESP01-S等模块从网络API获取信息并显示如天气预报、股市行情、今日头条、待办事项列表。配合一个外壳就是一个精致的桌面信息终端。3. 智能传感器显示器将Pico LCD 0.96与各种传感器结合打造即插即用的显示单元。例如连接DHT11温湿度传感器做成一个带历史曲线图的环境监测仪连接空气质量传感器实时显示PM2.5和VOC数值。4. 音乐可视化工具利用Pico的ADC引脚采集音频信号经过简单的放大电路进行FFT快速傅里叶变换分析然后将频谱以动态柱状图或波浪的形式显示在屏幕上制作一个迷你的音频频谱分析仪。5. 自定义仪表盘为你的3D打印机、CNC机床或机器人小车制作一个状态仪表盘。显示当前坐标、速度、温度、进度等信息比单纯的串口打印直观得多。踩坑心得在构思扩展项目时一定要先评估Pico的资源边界。RP2040有264KB RAM和2MB Flash双核133MHz能力不弱。但如果你同时运行Wi-Fi、复杂的图形界面如LVGL和传感器数据处理内存可能会紧张。一个实用的技巧是使用MicroPython进行快速原型验证当功能稳定且需要更高性能时可以考虑移植到C/C SDK开发能更精细地控制内存和性能。对于绝大多数创意项目MicroPython的便利性和开发速度带来的优势远超过其性能上的一点损失。