news 2026/9/9 1:13:55

ESP8266 MicroPython ST7735 TFT屏硬件SPI驱动与刷新提速指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESP8266 MicroPython ST7735 TFT屏硬件SPI驱动与刷新提速指南

简介:面向嵌入式开发者的ESP8266与MicroPython联合开发资源包,围绕ST7735驱动芯片的TFT屏幕展开,核心目标是解决模拟SPI方式刷新过慢、直接切换硬件SPI后速度依旧不理想的问题。作者从画点、铺色、显示字符串等基础绘图函数入手逐项重写,优化底层数据写入与传输方式,让屏幕刷新速度获得明显提升。资源中特别提醒MicroPython环境下ESP8266设有两个硬件SPI,其中一个被Flash占用无法供用户使用,因此实际可用的硬件SPI只有一个;若改用软件SPI,则需注意spi.write函数必须传入bytes类型,且SPI相位和极性要依据芯片数据手册时序图正确配置。压缩包为zip格式,大小仅4KB,共3个py文件,涵盖LCD屏幕驱动、功能加载与主程序入口,代码精简、结构清晰,便于移植到其他工程。目前已有535人浏览学习,适合正在调试TFT显示、希望提高屏幕刷新效率的嵌入式开发爱好者参考。 如果你在ESP8266上用MicroPython做过TFT屏幕显示,大概率经历过这样一个场景:屏幕能亮,但全屏刷个图就像在慢放,一行一行往下爬,肉眼能清楚看到扫描过程。稍微复杂一点的界面,刷一次等得人心烦。

这个问题多半不是代码逻辑有毛病,而是数据传输通路选错了。把单片机引脚当成人肉SPI时钟,用Python一句一句去翻转GPIO,速度当然上不去。想让ESP8266配合ST7735这类彩屏跑出比较体面的刷新效果,正确做法是走硬件SPI——让芯片内部的移位寄存器帮你去发时钟和数据,CPU只需要把数据塞给外设就行,速度完全不在一个量级。

这篇内容我按自己实际调这块屏幕的经验来写,从硬件SPI和软件SPI的差异讲起,把接线、固件准备、驱动文件、初始化参数和各类坑一次说完。适合刚入手ESP8266开发、准备给项目配一块小巧TFT屏的朋友参考,也适合已经在用软件SPI刷屏、觉得卡顿想换硬件SPI提速的开发者。

1. 为什么非要用硬件SPI:软件GPIO刷屏是真的难受

1.1 从一次全屏刷新说起

先算一笔账。ST7735常见的分辨率是128x160,颜色深度一般是16bit,也就是每个像素占用2字节。一屏完整数据量是128x160x2 = 40960字节,约40KB。

如果是软件SPI,每发送一个字节,流程是:拉低时钟、在MOSI上设置电平、拉高时钟、再重复8次。在MicroPython的解释环境下,每次GPIO翻转差不多要1~3us,加上循环判断、函数调用开销,发一个字节的耗时能走到30~50us甚至更慢。按50us算,40KB就是40960x50us,约2秒。就算优化一点,也差不多要1秒以上。这个速度意味着,你写个简单的动画,刷新一次至少一秒,界面必然肉眼可见地卡顿。

硬件SPI就不一样了。时钟信号由外设电路产生,MicroPython只需要把数据块交给SPI外设,它会自动按设定的波特率同步输出。以20MHz为例,理论上发完40KB只需要16.4ms,是软件方案一个量级以上的提升。实际项目里因为还要发命令、切换DC电平、处理绘图开销,全屏刷新在几十毫秒级别是能达到的。我的板子上实测,20MHz硬件SPI下执行一次整屏填充大约在40~80ms,跟软件的“秒级”完全是两种体验。

1.2 ESP8266硬件SPI的引脚和一些认知误区

ESP8266在MicroPython环境下的用户可操作硬件SPI只有一个,就是machine.SPI(1),引脚是固定的三根:SCK在GPIO14、MOSI在GPIO13、MISO在GPIO12。和某些单片机不一样,ESP8266的硬件SPI引脚不能随意映射,想在代码里写“SCK=GPIO5”这种操作在硬件SPI下行不通。

这里有个容易误会的点:很多人一听“硬件SPI”,怕引脚太死板,下意识还是去用软件SPI。实际上ST7735这块屏本身只需要SPI的写方向,读取操作基本用不上,所以MISO那个脚不接任何设备也无所谓。但MicroPython构造硬件SPI对象时,有些固件版本还是要求你指定miso引脚,那就把GPIO12填进去,让这个脚悬空或做普通IO处理即可,不影响写屏幕。

还有一个误区是觉得硬件SPI一定比软件SPI难配置。梳理清楚了就知道,两者在MicroPython里的API差别不大,硬件SPI只是额外限制了一组固定引脚,换来的是几十倍的性能提升。用屏幕这种数据吞吐量大的设备,选硬件SPI是必须的,而不是可选项。

2. ST7735模块接线与供电细节

2.1 引脚对照与选脚避坑

市面上的ST7735模块虽然卖家不同,但接口基本是统一的,常见引脚有VCC、GND、CS、RESET、A0(有些标DC)、SDA(MOSI)、SCK、LED(背光)。对照ESP8266,接线可以这样规划:

ST7735模块引脚ESP8266引脚说明
VCC3.3V模块供电,不要接5V
GNDGND共地
SCKGPIO14硬件SPI时钟
SDAGPIO13硬件SPI MOSI
CSGPIO5片选,普通GPIO即可
A0/DCGPIO4数据/命令选择,普通GPIO
RESETGPIO16复位,普通GPIO即可
LED3.3V背光,可常亮或GPIO控制

选GPIO的时候有讲究。ESP8266启动时会检查几个特殊引脚的状态:GPIO0、GPIO2上电必须为高,GPIO15上电必须为低,否则会进入错误的启动模式。如果把这些特殊引脚用来接外部模块,并且模块在上电瞬间把电平拉反,就有可能导致板子启动异常。稳妥起见,CS、DC、RST这类信号引脚尽量挑GPIO4、GPIO5、GPIO16这种没有额外启动约束的脚位。我自己喜欢用GPIO5做CS、GPIO4做DC、GPIO16做RST,跑了好几个项目都很稳定。

MISO那根线再次强调:SPI构造时需要指定GPIO12,但硬件上可以不连。如果你买的模块引出了MISO,留着悬空或者接到GPIO12都行,代码里只写屏不读屏,完全无所谓。

2.2 供电与干扰问题

ST7735模块上的VCC丝印虽然是5V兼容的样子,但很多小模块板载稳压和电平转换并不完善,习惯上还是按3.3V供电最稳。背光LED如果直接接3.3V,模块自带限流电阻,常亮没问题;如果想让背光可以软件控制,就接一个GPIO,但要注意GPIO驱动能力有限,最好通过一个三极管或MOS管去控制背光的开关。

供电这块经常有人忽略,却最容易出花屏和闪屏的毛病。ESP8266在开启WiFi后电流尖峰很猛,瞬间可能冲到几百毫安,如果和TFT屏共用一颗小功率LDO,很容易在WiFi收发瞬间把3.3V电压拉低,屏幕就会随机花屏甚至重启。我的习惯是在电源输入端并联一颗100uF到470uF的电解电容,再在屏的VCC脚附近加一颗0.1uF陶瓷电容。别小看这两颗电容,能把很多“莫名其妙花屏”的问题挡在发生之前。

3. 烧录固件并准备驱动文件

3.1 ESP8266的MicroPython固件烧录

如果板子还是出厂自带的AT固件,第一步是烧录MicroPython。去MicroPython官网下载ESP8266对应的固件bin文件,注意选择匹配你板子Flash容量的版本,常规NodeMCU一般是4MB。烧录工具用esptool,先完整擦除Flash,再写入固件:

esptool.py --port COM3 erase_flash esptool.py --port COM3 --baud 460800 write_flash -fm dio -fs 4MB 0x0 esp8266-20220618-v1.19.1.bin

Windows的串口是COMx,Linux下一般是/dev/ttyUSB0,改成自己实际看到的端口即可。先擦除再写入这个顺序别跳,如果旧固件残留,MicroPython启动后文件系统可能挂载失败,出现莫名其妙的重启循环。

烧录完可以用PuTTY或Thonny连接REPL,看到>>>提示符说明固件已经正常跑起来了。

3.2 上传ST7735驱动和main.py

MicroPython本身没有内置ST7735驱动,需要把驱动文件放到设备上。社区里常见的做法是下载一份现成的st7735.py,放到ESP8266的文件系统,然后在main.py里import使用。上传工具有很多,最省事的是Thonny,图形界面里直接右键上传文件,对新手非常友好。也可以用ampy走命令行:

ampy --port COM3 put st7735.py ampy --port COM3 put main.py

拿到驱动文件后,别急着运行,先打开源码扫一眼构造函数。ST7735驱动的开源版本很多,接口细节有差异,有的版本初始化时直接在驱动内部创建SPI对象,有的版本要求你从外面传一个SPI实例进来。标题这里强调“使用硬件SPI”,所以我们要用的是后一种方式:外部创建machine.SPI(1),再把SPI对象传给显示设备类。如果下载的驱动是内部创建SPI的写法,需要微调一下,把驱动里创建SPI那段代码替换为接收外部传入的SPI参数。很多人在这一步卡住,其实把源码打开对比几行就看明白了。

4. 核心代码与参数调优

4.1 初始化硬件SPI和显示屏

下面这段是典型的外部传入SPI实例的写法,细节可能因驱动版本略有不同,但思路一致:

from machine import Pin, SPI import st7735 spi = SPI(1, baudrate=20000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) cs = Pin(5, Pin.OUT) dc = Pin(4, Pin.OUT) rst = Pin(16, Pin.OUT) cs.value(1) tft = st7735.ST7735(spi, cs, dc, rst, rotation=0, offset=(0, 0), bgr=True, invert=True) tft.init() tft.fill(0xFFFF)

baudrate=20000000就是20MHz。先别一上来就追求极限,这个速率能保证大部分模块稳定工作。等整屏显示正常了,再试着改到40MHz,如果出现花屏、条纹就降回去。网上有一种说法是ST7735数据手册里写的最大写周期约15MHz,20MHz已经算超频,实际很多模块配合杜邦线短距离连接也能跑,但不要因此忽略线材质量。杜邦线太长、接触不良,都会影响高速SPI的波形。

代码中polarity=0, phase=0对应SPI Mode 0,ST7735一般工作在Mode 0。firstbit=SPI.MSB表示高位先出,这是SPI设备的常规要求。如果你的固件不支持firstbit这个参数,去掉即可,不影响默认行为。

csdcrst三个引脚初始化成输出后,记得把CS先拉高,避免初始化前SPI总线上有其他干扰信号被屏幕误解析成命令。rstinit()内部会自己拉低再拉高完成复位,外部不需要额外处理。

4.2 几个最影响显示效果的参数

驱动初始化里最折磨人的三个参数是:rotationbgrinvert。这三者配置不对,屏幕能亮,但显示效果千奇百怪。

rotation控制旋转方向,取值范围通常是0到3,对应0度、90度、180度、270度。改了旋转方向后,如果屏幕显示区域偏移了,还需要配合offset参数调整起点位置。很多模块不是标准的128x160全屏可视区域,比如有些80x160或128x128的屏,安装方向不同,坐标偏移也不同。出现显示内容不在屏幕中心的时候,就是offset该派上用场的时候。

bgr控制RGB还是BGR颜色顺序。这个参数错了,最典型的表现是红色和蓝色互换。比如你画一个红色矩形,屏幕显示出来是蓝色。遇到这种状况,把bgr从True改成False,或者反过来,问题立刻解决。

invert是颜色反相。有的ST7735面板需要开启反色,否则显示效果像相片底片一样,整个世界都是反色的。这个参数没有绝对标准,跟具体面板的初始化序列有关,最好的方法就是写一个纯白填充和纯红填充的测试程序,多试几次True/False,选显示正常的那组。

最后还有一个隐性参数是MADCTL,也就是ST7735寄存器0x36,控制扫描方向、RGB/BGR顺序和行列交换。rotationbgr从根本上说都是在帮你设置这个寄存器。有些驱动把这两个参数封装好了,而有的驱动需要你直接改源码里的MADCTL值,原理明白后看到相关代码就不会懵。

4.3 刷新性能优化思路

显示大面积图形时,绘制和刷屏要配合好。ST7735控制芯片内部自带GRAM,我们可以一次性把所有像素数据推给屏幕,让控制器自己管理刷新。问题在ESP8266的内存很紧张,128x160x2的完整帧缓冲需要40KB,而MicroPython环境能稳定使用的大块连续内存没那么多,直接分配很容易MemoryError

实际项目里我一般用“行缓冲+分块刷新”的方式:不需要一整个40KB的buffer,先绘制一小块区域到内存,然后立刻通过SPI刷出去,再绘制下一块。比如用bytearray(128*2)先准备一行数据,绘制完一行就推一行。这样做内存占用小,效果上也几乎看不出差别。如果是显示静态界面,可以算好一个区域,用fill_rect配合局部刷新,比整屏重绘高效得多。

如果确实需要整屏缓冲,那么在程序启动早期、文件系统加载完但还没开启WiFi时分配,成功率会高一些。分配之前先执行gc.collect()整理堆内存,减少碎片。分配完就不要再频繁创建大对象,否则后期内存碎片会越来越严重。

5. 踩坑实录与排查清单

5.1 常见问题速查表

把这段时间用ST7735碰到的典型问题整理成了一张表,排查的时候对照着看能省很多时间:

现象大概率原因解决办法
全屏白屏复位时序不对、SPI速率太高、供电不足检查RST引脚接线,降低baudrate,电源并电容
全屏花屏、横条纹电源干扰或SPI速度过高加强滤波电容,逐步降低SPI速率测试
颜色红蓝互换bgr参数不对切换bgr的True/False
显示像底片反色invert参数不对切换invert的True/False
内容偏移/显示不全offset或rotation不对修改offset坐标,测试不同rotation
背光不亮但屏幕有显示背光引脚没接对LED引脚接3.3V,或确认GPIO控制电平
上电后板子反复重启Flash固件没擦干净重新完整erase_flash再烧录
刷新时WiFi偶尔掉线SPI中断与WiFi争抢资源降低SPI速率,减少整屏刷新频率

5.2 几个容易被忽略的坑

第一个坑是RST复位等待时间。有些驱动初始化序列里Sleep Out之后只等待几十毫秒,个别ST7735面板需要更长时间才能稳定。我的做法是在init()里的0x11命令之后主动加一个time.sleep_ms(200),宁可多等一下也不要让屏幕带着半睡状态就开始收数据,能明显减少白屏概率。

第二个坑是GPIO初始状态。CS、DC、RST在初始化SPI之前就应该明确设置成输出并给到正确电平。尤其CS,如果不小心悬空或默认拉低,上电瞬间芯片可能把GPIO上的噪声当成片选信号,导致屏幕吃进一堆垃圾命令。养成习惯:cs = Pin(5, Pin.OUT); cs.value(1),初始化屏幕之前CS保持高,需要通信时才拉低。

第三个坑是SPI速率并非越高越好。我测试过40MHz下刷新速度确实更快,但MicroPython在推大块数据时会长时间占用CPU和SPI外设,此时如果WiFi正在收发数据,两边可能互相拖累,表现为屏幕撕帧、WiFi偶发断连。很多场景下20MHz的稳定性比40MHz的极限速度更重要。如果你做的是传感器数据展示这种低频刷新场景,20MHz完全够用。

第四个坑是绘图坐标和屏幕物理方向的组合。常见的小屏幕安装方向五花八门,有的屏接口在左边,有的在右边,有的排线朝下。rotation参数调好后,务必用英文和中文混合文本、矩形框、实心圆各画一遍,确认上下左右没有镜像或偏移,再写正式界面代码。一次调好,后面省心很多。

我自己在实际项目中还习惯把显示刷新和业务逻辑分离:WiFi联网、传感器采集走一个流程,屏幕刷新走另一个流程,用标志位控制,避免两者在同一时间片里抢CPU。这样即使SPI偶发耗时较长,也不会导致整个系统卡死。这个思路在ESP8266这种资源受限的板子上尤其重要,屏幕只是显示终端,不能让它拖垮主逻辑。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 1:11:57

SSM到SpringBoot平滑升级:求职招聘小程序后端架构实战

简介:一套基于微信小程序与SSM(可升级Spring Boot)架构的求职招聘系统完整设计源码,覆盖求职者、商户和管理员三类角色,适用于毕业设计、课程设计及Java全栈学习;小程序端支持微信授权登录、完善资料、兼职…

作者头像 李华
网站建设 2026/9/9 1:10:52

C#中调用HALCON引擎:HDevEngine脚本集成与工程实践

简介:这是一份面向C#开发者的HALCON联合编程示例工程,定位于解决在.NET环境中调用HALCON引擎进行图像处理与模板匹配的实际问题。资源通过可运行的示例代码,演示了引入HalconDotNet命名空间、创建HInstance实例、加载match_template算子、执行…

作者头像 李华
网站建设 2026/9/9 1:10:13

跨领域静态配置实战:从静态路由到静态托管的综合实验

很多网络工程专业的学生和刚入行的运维朋友,都绕不开“静态配置”这道坎。无论是华为ensp里的静态路由、静态NAT,还是Linux下改个静态IP地址,又或者是给网站做伪静态,这些操作散落在各个技术栈里,看起来毫无关联&#…

作者头像 李华
网站建设 2026/9/9 1:07:00

C#上位机通过Modbus控制信捷伺服驱动器完整方案

简介:这是一套C#编写的信捷伺服驱动器Modbus速度及位置控制上位机源码,面向工业自动化开发者与需要学习Modbus通信编程的工程师,解决通过上位机对伺服驱动器进行实时控制与监控的问题。资源包为rar压缩包,共95个文件,体…

作者头像 李华
网站建设 2026/9/9 1:04:28

探索ponytail:基于CLI的前端工程化“技能包”自动化工具

1. 项目概述:从一行命令到AI原生的工程化思维先别急着被标题骗了,我在这里说的"ponytail"不是扎头发的橡皮筋,而是一个最近在开发者圈子里悄悄传开的前端工程化工具包。它的名字确实很容易让人联想到"马尾辫"&#xff0c…

作者头像 李华
网站建设 2026/9/9 0:58:32

UVM 1.2寄存器模型镜像同步与验证环境实操指南

简介:本资源是面向数字芯片验证工程师与SystemVerilog进阶学习者的UVM1.2源码实践平台,聚焦SoC验证核心能力培养,解决UVM框架理解浅、组件调用生、源码阅读难等典型痛点。压缩包共482个文件,主体为227个.sv验证组件源码与143个.sv…

作者头像 李华