驱动各种屏幕
屏幕分类
注:关于RGB跟DPI,豆包说DPI跟TTL RGB不是一个东西,而DeepSeek又说DPI就是常说的RGB屏,不知道谁对谁错。
├── I2C(独立总线,驱动小单色OLED;极少数小彩屏也有用I2C,但速度极差) ├── TTL RGB(通用并行RGB,不属于MIPI体系,市面标注“RGB接口屏”全是它,无内置GRAM,主控持续输出画面) └── MIPI体系 ├── DBI(自带片内GRAM,俗称MCU屏,单片机入门彩屏主力) │ ├── 8080(DBI Type-B并行,现在主流DBI并口) │ └── SPI(DBI Type-C串行,四线SPI彩屏,ST7789/GC9A01这类) ├── DPI(MIPI官方标准并行RGB,市面成品屏几乎绝迹,工程极少使用) └── DSI(高速差分串行,分1/2/3/4 Data Lane;商家口中“MIPI屏”默认就是DSI;手机、树莓派DSI口、掌机、高清小屏通用,部分DSI屏带内置GRAM、高端高清屏无GRAM)
SPI跟IIC几乎所有的单片机都支持;8080接口中端单片机才有,如STM32的FSMC接口,ESP32S3的I80控制其,其他的可通过GPIO软件模拟;RGB接口要中高端的单片机才支持,例如ESP32S3,几乎无法软件模拟;DSI接口,要高端的单片机才支持,例如ESP32P4。
注1:所有SPI屏幕的CS引脚都可以省略,节省一个引脚。屏幕的CS接地就是启用了。
注2:Arduino UNO硬件SPI驱动屏幕的时候,屏幕的VCC一定要连接Arduino的5V供电,否则会显示不正常
Arduino驱动屏幕比Linux方便多了,总共就分2大类,黑白点阵屏,灰阶,OLED用u8g2,彩色tft屏用TFT_eSPI,这2个库基本涵盖了绝大部分的屏幕。
硬件SPI除了MISO,MOSI,CLK,其他引脚可以随便改(有的设备支持引脚重映射,这几个引脚位置也不是固定的) ESP8266 硬件SPI #define TFT_MISO D6 //数据IN :Automatically assigned with ESP8266 if not defined #define TFT_MOSI D7 //或叫SDA,数据OUT: Automatically assigned with ESP8266 if not defined #define TFT_SCLK D5 //或叫SCK :Automatically assigned with ESP8266 if not defined #define TFT_CS D8 //Chip select control pin D8 #define TFT_DC D3 //或叫A0或RS: Data Command control pin #define TFT_RST D4 //Reset pin (could connect to NodeMCU RST, see next line) RP2040 硬件SPI0 #define TFT_MOSI 19 #define TFT_SCLK 18 #define TFT_CS 17 #define TFT_DC 21 #define TFT_RST 20 ESP32 暂时还没测速过硬件SPI,下面是软件SPI的,如果是软SPI,随便用哪个引脚都行 #define TFT_MISO 9 #define TFT_MOSI 14 #define TFT_CLK 11 #define TFT_CS 10 #define TFT_DC 12 #define TFT_RST 13 Arduino UNO 硬件SPI #define TFT_MOSI 11 #define TFT_SCLK 13 #define TFT_CS 10 #define TFT_DC 9 #define TFT_RST 8 AIR001 硬件SPI #define TFT_MOSI PA_7 #define TFT_SCLK PA_5 #define TFT_CS PA_4 #define TFT_DC PA_1 #define TFT_RST PA_0
Air001的引脚:

可通过以下方式修改默认SPI引脚: void setMISO(PinName miso) void setMOSI(PinName mosi) void setSCLK(PinName sclk) void setSSEL(PinName ssel) 注:一定要在begin前修改
ESP32S3的SPI:
官方文档好像说ESP32S3的引脚是可以随便映射的(通过 GPIO 交换矩阵连接),但是性能会有所下降,只能到400MHz,推荐用IO MUX 管脚,也就是默认的SPI3引脚,可以到800MHz(有4个SPI,前两个不能用,用SPI3就行)
IO MUX :外设直连引脚(部分外设如USB只能直连;部分外设如SPI可直连也可交换,但交换性能会降低;部分外设如PWM只能GPIO交换)
GPIO交换矩阵:外设可以随意分配引脚,但性能会下降
参考:ESP32-S3 引脚参考大全 - 小鹏STEM (xpstem.com)

注意:驱动的不同版本一般兼容,比如ST7789,ST7789V,ST7789V2,只是不同的屏幕分辨率,不同型号可能有某些参数不同,需要区别设置下
LCD1602:
这个比较简单,虽然接口多,单可以利用pcf8574模块通过i2c来简化接口,以树莓派为例子:
sudo apt install python3-smbus python3-dev
pip3 install RPLCD
from time import sleep import smbus from RPLCD.i2c import CharLCD # 初始化 LCD lcd = CharLCD('PCF8574', 0x20) # 使用合适的 I2C 地址,PCF8574的范围是0x20(3个电阻全焊上)-0x27(3个电阻全空) # 清除 LCD 上的内容 lcd.clear() # 在 LCD 上显示内容 lcd.write_string("Hello, World!") # 等待 2 秒 sleep(2) # 可以继续更新显示 lcd.clear() lcd.write_string("Raspberry Pi!")
Arduino:
库:Bonezegei_LCD1602_I2C(测试时1.0.4)
实例:随便,使用比较简单,只需要根据实际情况改下I2C的地址即可,例如:Bonezegei_LCD1602_I2C lcd(0x20);
SSD1306:
屏幕:
库:u8g2(测试时版本2.35.30)(推荐) 或 ESP8266 and ESP32 OLED driver for SSD1306 displays(测试时4.4.1)
实例:随便
设置:
U8G2: 硬件I2C:U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); 软件I2C:U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); ESP8266 and ESP32 OLED driver for SSD1306 displays: I2C: 附带的示例默认都是I2C的,随便打开一个示例,加入引脚设置,就可以直接运行: #define SDA 13 #define SCL 14 SPI: 先把I2C的注释掉: //#include "SSD1306Wire.h" //SSD1306Wire display(0x3c, SDA, SCL); 取消注释SPI的设置: #include "SSD1306Spi.h" #define CLK 10 #define RST 11 #define DC 12 #define CS 13 #define MOSI 14 SSD1306Spi display(RST, DC, CS); 注:SPI的没测过,只是看注释部分应该是这样用
ssd1327:
屏幕:【淘宝】https://m.tb.cn/h.5zn7evSrVPNgMbz?tk=gKI9WKREaD0 MF6563 「1.5寸日本进口 128128带灰阶oled屏 spi串口 有资料」

库:Adafruit SSD1327 或 u8g2
实例:随便
设置:
Adafruit_SSD1327: 修改SPI相关引脚,给硬件SPI取消注释,并且注释默认的I2C函数 #define OLED_CS D8 #define OLED_DC D3 #define OLED_RESET D4 // hardware SPI Adafruit_SSD1327 display(128, 128, &SPI, OLED_DC, OLED_RESET, OLED_CS); u8g2: 取消注释 U8G2_SSD1327_MIDAS_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ D8, /* dc=*/ D3, /* reset=*/ D4);
ili9341:
屏幕:【淘宝】https://m.tb.cn/h.5u0mXA8T7ooDhE7?tk=SYlrWP3iyCw HU0025 「全新2.8寸TFT液晶屏 SPI串口屏240*320 4线IO 驱动ILI934118PIN」
库:Adafruit_ILI9341
示例:graphicstest
设置:
在代码里添加引脚映射 #define TFT_MOSI 14 #define TFT_RST 13 #define TFT_DC 12 #define TFT_CLK 11 #define TFT_CS 10 #define TFT_MISO 9 根据是软SPI还是硬SPI,选择其中一个 //Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); //硬件SPI Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
st7565 / st7567 / uc1701:
屏幕:
st7565:老王3.6寸12864 SPI屏幕(已下架)
st7567:思迈微1.3寸12864lcd液晶SPI显示屏3.3VCOG模组12pin焊接LCM驱动ST7567黑白屏(图1)
st7567:老王96x32无背光屏(图2)
st7567:老王1.7寸128x64,14Pin(图3,4)



库:u8g2(测试时版本2.35.30)
示例:GraphicsTest
设置:
注:看自带的例子发现,u8g2的api分2种,一种是u8g2,一种是u8x8。其中u8g2比较全面,图形能力强,资源占用多,接口比较复杂。而u8x8使用简单,功能少,资源占用少,一般用于文本显示。
如果屏幕全白,或者全黑,看不清,可能是驱动不完美兼容,默认对比度问题,要在setup里的u8g2.begin();后面加一行u8x8.setContrast(对比度);设置一个合适的对比度(0-255) st7565:引脚 1.CS 2.RST 3.A0(DC) 4.SCK 5.SDA 6.VCC(3V) 7.GND 8.LED- 9.LED+(3V) st7567:引脚 1.CS 2.RST 3.A0(DC) 4.SCK 5.SDA 6.VCC(3V) 7.GND 8.NC 9.NC 10.NC 11.LED+ 12.LED- 搜索屏幕对应的行,取消注释,或直接复制粘贴下面的(其实st75xx系列的驱动很多可以共用,就是可能位置有偏移什么的,比如7567就能用7565的驱动,只是显示y轴偏移了) st7565,对比度200:U8X8_ST7565_LX12864_4W_HW_SPI u8x8(/* cs=*/ D8, /* dc=*/ D3, /* reset=*/ D4); st7567,对比度160:U8X8_ST7567_ENH_DG128064I_4W_HW_SPI u8x8(/* cs=*/ D8, /* dc=*/ D3, /* reset=*/ D4);
st7588i:
屏幕:老王3.6寸128x64黑底橙光iic屏15Pin

st7789:
屏幕:1.3寸st7789 240x240
库:TFT_eSPI(测试时版本2.5.34)
链接:GitHub - Bodmer/TFT_eSPI: Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
示例:随便
设置:
这个库的例子不需要改引脚,改为在库源码目录里修改。 C:\Users\jeaso\Documents\Arduino\libraries\TFT_eSPI\User_Setup.h 把45行注释,并且55行左右的注释去掉,声明要用7789的驱动,#define ST7789_DRIVER
切记,因为默认选择的是ili9341驱动,所以要把ili9341的那一行注释掉,否则同时选中两个驱动,虽然编译不会报错,但是默认用ili9341,神奇的是也能驱动屏幕,但是屏幕显示方向错误,并且颜色不正常。 把88行的屏幕分辨率设置一下 #define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320 #define TFT_HEIGHT 240 // ST7789 240 x 240 170行左右声明了引脚 #define TFT_MISO PIN_D6 // Automatically assigned with ESP8266 if not defined #define TFT_MOSI PIN_D7 // Automatically assigned with ESP8266 if not defined #define TFT_SCLK PIN_D5 // Automatically assigned with ESP8266 if not defined #define TFT_CS PIN_D8 // Chip select control pin D8 #define TFT_DC PIN_D3 // Data Command control pin #define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line) 至于PIN_DXX对应的是哪个物理引脚,可以在User_Setup_Select.h里末尾的地方看到,搜下关键字就找到了
默认SPI帧率是27MHz,可以改成40MHz,提高速度。如果是ESP32S3这种,还可以在硬件SPI的条件下改成80MHz
//#define SPI_FREQUENCY 27000000
#define SPI_FREQUENCY 40000000
但是不是越高越高,不少屏幕都有限制,像ili9341就推荐40,80会出现一些渲染错误(但实际测试,这块240x240的屏幕,在esp8266上,最高可以开到75MHz)
// With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
st7789v(这个库有BUG不支持8266?显示一点内容后就不断重启,以前记得不会)
屏幕:【淘宝】https://m.tb.cn/h.5Gmg01fUQypAIZp?tk=ybgWWPWSmDK CZ3452 「1.14寸TFT显示屏LCD彩色液晶屏 ST7789驱动135x240分辨率 高清IPS」库:st7789v-arduino(测试时版本0.1,该库没上arduino官方仓库)
链接:GitHub - deirvlon/ST7789v-Arduino: ST7789v Arduino Library - Tested on Arduino UNO and STM32 (Blue Pill)
例子:graphicsTEST.ino
设置:
先从github上下载仓库的zip文件,然后打开arduino -> 项目 -> 导入库 -> 添加.zip库,然后选择该库的示例文件即可
引脚跟上面一样配置 #define TFT_DC D3 #define TFT_RST D4 #define TFT_CS D8 // only for displays with CS pin #define TFT_MOSI D7 // for hardware SPI data pin (all of available pins) #define TFT_SCLK D5 // for hardware SPI sclk pin (all of available pins) 取消注释这一行,取代默认打开的那一行,ST7789v_arduino tft = ST7789v_arduino(TFT_DC, TFT_RST, TFT_CS); //for display 用硬件SPI的方式模拟 然后在setup里修改屏幕分辨率:tft.init(135, 240);
st7789v2(存疑,不知道测试屏幕是否真的为st7789v2)
屏幕:【淘宝】7天无理由退货 https://e.tb.cn/h.TI20V98RYMawHvv?tk=TLhgeio7UcW CA381 「2.8寸TFT液晶显示屏彩屏LCD屏5点电容触摸ILI9341串口并口ST7789」

库:Adafruit ST7735 and ST7789 Library(测试时版本1.10.3) 或者参考上面st7789的TFT_eSPI库(这个库最完美)也可以运行,上面st7789v的st7789v-arduino也能点亮,输出文字,但是设置有问题,不停重启屏幕
链接:GitHub - adafruit/Adafruit-ST7735-Library: This is a library for the Adafruit 1.8" SPI display http://www.adafruit.com/products/358 and http://www.adafruit.com/products/618
示例:graphicstest_st7789
设置:
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// 修改8266的引脚 #elif defined(ESP8266) #define TFT_CS D8 #define TFT_RST D4 #define TFT_DC D3 // 设置屏幕分辨率 // Use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT:
tft.init(240, 320); // Init ST7789 240x240
// 如果屏幕颠倒了旋转下
tft.setRotation(rotation)
// 如果屏幕刷新太快,可以手动设置下SPI的速度
gc9107
屏幕:gc9107 1.3寸 128x128

库:TFT_eSPI(测试时版本2.5.34)或 Adafruit ST7735 and ST7789 Library
示例:随便
tft_espi的st7789也能完美用,#define ST7789_DRIVER 分辨率改为128x128 需要改为BGR颜色,#define TFT_RGB_ORDER TFT_BGR tft_espi里的st7735理论上也是兼容的,但没测试 Adafruit ST7735 and ST7789 Library 里的st7735也兼容: tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab tft.setRotation(2);// 其他方向有偏移,暂不知道哪个api是设置屏幕偏移的,估计得去改源码 tft.invertDisplay(true);
st7735s
屏幕:
1.「0.96寸高清ips tft显示屏液晶屏st7735 0.96寸TFT全彩屏 液晶屏」
2.「1.77寸1.8寸TFT液晶显示屏4线SPI串口ST7735S电阻触摸IPS全视角」
3.1.44TFT显示屏SPI接口ST7735液晶小屏幕模块128*128全彩插接14pin

(图1:0.96寸80x160 图2:0.96的排针 图3:1.77寸128x160 图4:1.44寸128x128)
库:TFT_eSPI(测试时版本2.5.34)或 Adafruit ST7735 and ST7789 Library 或 Ucglib (1.5.2)
示例:随便
注:128x160那个屏幕,屏幕的电源引脚,一般是接3v3,但在arduino uno下要接5v,否则无法启动(不过看驱动初始化命令,貌似电源的初始化都是4.xV,不知道为啥在其他设备能3v3启动)
设置:
TFT_eSPI: 跟上面st7789的一样,要修改源码,不同的是: C:\Users\xx\Documents\Arduino\libraries\TFT_eSPI\User_Setup.h 1.驱动选 #define ST7735_DRIVER 2.#define TFT_WIDTH 80或128 #define TFT_HEIGHT 160或128 3.如果是160x80:选这个,#define ST7735_GREENTAB160x80
4.如果是128x128:选这个,#define ST7735_GREENTAB3 5.如果是128x160:选这个,#define ST7735_GREENTAB2,额外还需要开启颜色反转:#define TFT_INVERSION_ON 还需要修改像素偏移: C:\Users\xx\Documents\Arduino\libraries\TFT_eSPI\TFT_Drivers\ST7735_Defines.h 在59行左右,加入像素偏移的配置: #elif defined (ST7735_BLACKTAB) #define TAB_COLOUR INITR_BLACKTAB // 加入以下行 #define CGRAM_OFFSET 然后到:C:\Users\xx\Documents\Arduino\libraries\TFT_eSPI\TFT_Drivers\ST7735_Rotation.h 修改每个屏幕方向的像素偏移值,以0号方向为例: case 0: if (tabcolor == INITR_BLACKTAB) { writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER); // 加入以下两行 colstart = 2; rowstart = 1; Adafruit ST7735 and ST7789 Library: 跟上面一样,不同的是: 1.驱动选7735:Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 2.如果是160x80则选:tft.initR(INITR_MINI160x80_PLUGIN); // Init ST7735S mini display
3.如果是128x128则选:tft.initR(INITR_144GREENTAB); 4.如果是128x160则选:tft.initR(INITR_BLACKTAB),同时需要开启颜色反转,tft.invertDisplay(true),并且会发现边缘有一行显示不正常,去到源码里修改: C:\Users\xx\Documents\Arduino\libraries\Adafruit_ST7735_and_ST7789_Library\Adafruit_ST7735.cpp void Adafruit_ST7735::initR(uint8_t options) { commonInit(Rcmd1); if (options == INITR_GREENTAB) { ... } else { displayInit(Rcmd2red); // 加入以下两行 _colstart = 2; _rowstart = 1; } displayInit(Rcmd3)
另一种驱动方式,通过Miropython:
st7735:boochow/MicroPython-ST7735: ST7735 TFT LCD driver for MicroPython
sysfont:MicroPython/lib/sysfont.py at master · GuyCarver/MicroPython
from ST7735 import TFT from machine import SPI, Pin, PWM from sysfont import sysfont import time # 背光 bl = PWM(Pin(26)) bl.freq(1000) # 设置频率为1kHz bl.duty_u16(32768) # 设置占空比为50%(32768/65535) # 初始化SPI spi = SPI(0, baudrate=40000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(19)) tft = TFT(spi,21,20,17) tft.initb2() tft.rotation(0) tft.invertcolor(1) tft.rgb(False)#如果红蓝反色了则切换这个RGB/BGR
# 128*160屏幕:invertcolor(1),tft.rgb(True)
# 128*128屏幕:invertcolor(0),tft.rgb(False)
# 显示内容 tft.fill(TFT.BLACK) tft.text((10, 10), "Hello Pico!", TFT.WHITE, sysfont)
1块钱的st7789触摸屏
连线:注意,驱动屏幕的时候,Pin6跟Pin16的电源引脚一定要连。BL+-只是背光的,不能当作屏幕的电源。

触摸(FT5624G):
from machine import Pin, I2C import time # ---------------------------- # FT5624 配置 # ---------------------------- FT_ADDR = 0x38 # GPIO RST = Pin(2, Pin.OUT) INT = Pin(3, Pin.IN, Pin.PULL_UP) # I2C i2c = I2C( 0, scl=Pin(5), sda=Pin(4), freq=400000 ) # ---------------------------- # 复位 # ---------------------------- RST.value(0) time.sleep_ms(10) RST.value(1) time.sleep_ms(200) print("I2C Scan:", [hex(i) for i in i2c.scan()]) # ---------------------------- # 寄存器读写 # ---------------------------- def read_reg(reg, length=1): return i2c.readfrom_mem(FT_ADDR, reg, length) def write_reg(reg, value): i2c.writeto_mem(FT_ADDR, reg, bytes([value])) # ---------------------------- # 芯片信息 # ---------------------------- try: vendor = read_reg(0xA8)[0] chip = read_reg(0xA3)[0] print("Vendor ID :", hex(vendor)) print("Chip ID :", hex(chip)) except Exception as e: print("Read ID Failed:", e) # ---------------------------- # 获取触摸点 # 返回 None 或 (x,y) # ---------------------------- def get_touch(): try: td = read_reg(0x02)[0] & 0x0F if td == 0: return None data = read_reg(0x03, 4) x = ((data[0] & 0x0F) << 8) | data[1] y = ((data[2] & 0x0F) << 8) | data[3] return x, y except Exception: return None # ---------------------------- # 主循环 # ---------------------------- while True: p = get_touch() if p: print("Touch:", p[0], p[1]) else: print("No Touch") time.sleep_ms(30)
屏幕:
from machine import SPI, Pin import time # ====================== 屏幕配置 ====================== # 引脚定义 PIN_DC = 1 PIN_MOSI = 2 PIN_SCK = 3 PIN_CS = 4 PIN_RST = 5 # 屏幕参数 WIDTH = 170 HEIGHT = 320 OFFSET_X = 35 OFFSET_Y = 0 ROTATION = 0 # ST7789 命令定义 ST7789_NOP = 0x00 ST7789_SWRESET = 0x01 ST7789_RDDID = 0x04 ST7789_RDDST = 0x09 ST7789_SLPIN = 0x10 ST7789_SLPOUT = 0x11 ST7789_PTLON = 0x12 ST7789_NORON = 0x13 ST7789_INVOFF = 0x20 ST7789_INVON = 0x21 ST7789_DISPOFF = 0x28 ST7789_DISPON = 0x29 ST7789_CASET = 0x2A ST7789_RASET = 0x2B ST7789_RAMWR = 0x2C ST7789_RAMRD = 0x2E ST7789_PTLAR = 0x30 ST7789_VSCRDEF = 0x33 ST7789_MADCTL = 0x36 ST7789_COLMOD = 0x3A ST7789_MADCTL_MY = 0x80 ST7789_MADCTL_MX = 0x40 ST7789_MADCTL_MV = 0x20 ST7789_MADCTL_ML = 0x10 ST7789_MADCTL_RGB = 0x00 ST7789_RAMCTRL = 0xB0 ST7789_PORCTRL = 0xB2 ST7789_GCTRL = 0xB7 ST7789_VCOMS = 0xBB ST7789_LCMCTRL = 0xC0 ST7789_VDVVRHEN= 0xC2 ST7789_VRHS = 0xC3 ST7789_VDV = 0xC4 ST7789_FRCTRL2 = 0xC6 ST7789_PWCTRL1 = 0xD0 ST7789_RDID1 = 0xDA ST7789_RDID2 = 0xDB ST7789_RDID3 = 0xDC ST7789_RDID4 = 0xDD ST7789_GMCTRP1 = 0xE0 ST7789_GMCTRN1 = 0xE1 class ST7789V: def __init__(self, spi, dc, cs, rst, width=170, height=320, offset_x=35, offset_y=0, rotation=0): self.spi = spi self.dc = dc self.cs = cs self.rst = rst self.width = width self.height = height self.offset_x = offset_x self.offset_y = offset_y self.rotation = rotation self.dc.init(Pin.OUT, value=1) self.cs.init(Pin.OUT, value=1) self.rst.init(Pin.OUT, value=1) self.reset() self.init_display() def reset(self): self.rst.off() time.sleep_ms(20) self.rst.on() time.sleep_ms(20) def write_cmd(self, cmd): self.dc.off() self.cs.off() self.spi.write(bytes([cmd])) self.cs.on() def write_data(self, data): self.dc.on() self.cs.off() self.spi.write(data) self.cs.on() def init_display(self): self.write_cmd(ST7789_SWRESET) time.sleep_ms(150) self.write_cmd(ST7789_SLPOUT) time.sleep_ms(120) self.write_cmd(ST7789_PORCTRL) self.write_data(b'\x0c\x0c\x00\x33\x33') self.write_cmd(ST7789_GCTRL) self.write_data(b'\x35') self.write_cmd(ST7789_VCOMS) self.write_data(b'\x1F') self.write_cmd(ST7789_LCMCTRL) self.write_data(b'\x2C') self.write_cmd(ST7789_VDVVRHEN) self.write_data(b'\x01') self.write_cmd(ST7789_VRHS) self.write_data(b'\x12') self.write_cmd(ST7789_VDV) self.write_data(b'\x20') self.write_cmd(ST7789_FRCTRL2) self.write_data(b'\x0F') self.write_cmd(ST7789_PWCTRL1) self.write_data(b'\xA4\xA1') self.write_cmd(ST7789_GMCTRP1) self.write_data(b'\xD0\x08\x11\x08\x0C\x15\x39\x44\x51\x2B\x17\x18\x2A\x2F') self.write_cmd(ST7789_GMCTRN1) self.write_data(b'\xD0\x08\x10\x08\x06\x06\x39\x44\x50\x2B\x18\x17\x2A\x2E') self.write_cmd(ST7789_COLMOD) self.write_data(b'\x55') # 16bit RGB565 # 方向寄存器 rotation=0 # madctl = ST7789_MADCTL_MX # 增加 0x08(BGR) madctl = ST7789_MADCTL_MX self.write_cmd(ST7789_MADCTL) self.write_data(bytes([madctl])) # 新增这一行,开启反色 self.write_cmd(ST7789_INVON) self.write_cmd(ST7789_DISPON) time.sleep_ms(10) def set_window(self, x0, y0, x1, y1): x0 += self.offset_x x1 += self.offset_x y0 += self.offset_y y1 += self.offset_y self.write_cmd(ST7789_CASET) self.write_data(bytes([x0 >> 8, x0 & 0xff, x1 >> 8, x1 & 0xff])) self.write_cmd(ST7789_RASET) self.write_data(bytes([y0 >> 8, y0 & 0xff, y1 >> 8, y1 & 0xff])) self.write_cmd(ST7789_RAMWR) def fill(self, color): color_h = color >> 8 color_l = color & 0xff buf = bytes([color_h, color_l]) * (self.width * self.height) self.set_window(0,0,self.width-1,self.height-1) self.write_data(buf) def fill_rect(self, x, y, w, h, color): color_h = color >> 8 color_l = color & 0xff line = bytes([color_h, color_l]) * w self.set_window(x, y, x+w-1, y+h-1) for _ in range(h): self.write_data(line) # ====================== 测试入口 ====================== if __name__ == "__main__": # ESP32S3 硬件SPI2 spi = SPI(2, baudrate=40000000, sck=Pin(PIN_SCK), mosi=Pin(PIN_MOSI)) tft = ST7789V( spi=spi, dc=Pin(PIN_DC), cs=Pin(PIN_CS), rst=Pin(PIN_RST), width=WIDTH, height=HEIGHT, offset_x=OFFSET_X, offset_y=OFFSET_Y, rotation=ROTATION ) # 测试颜色 RED = 0xF800 GREEN = 0x07E0 BLUE = 0x001F WHITE = 0xFFFF BLACK = 0x0000 print("屏幕初始化完成") tft.fill(BLACK) time.sleep_ms(2000) tft.fill_rect(0,0,50,50,RED) tft.fill_rect(120,0,50,50,GREEN) tft.fill_rect(120,270,50,50,BLUE) tft.fill_rect(0,270,50,50,WHITE)

浙公网安备 33010602011771号