news 2026/9/16 2:54:16

1.44寸ST7735 LCD模块驱动实战:从引脚定义到C51/STM32/Arduino移植

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
1.44寸ST7735 LCD模块驱动实战:从引脚定义到C51/STM32/Arduino移植

简介:一套面向嵌入式学习与开发的1.44寸LCD串口模块(ST7735)软硬件资料包,覆盖C51、STM32、Arduino三大平台,主线清晰。资料提供各平台下的SPI驱动源码与接线说明,其中STM32硬件SPI测试代码区分中文、英文显示场景,C51源码适合入门练手,Arduino串口版本可快速验证模块效果;同时附有模块原理图、尺寸图、Altium封装库、芯片数据手册以及图片和文字取模软件,既能帮助初学者从零点亮屏幕,也能让开发者直接参考硬件设计、快速生成字库与图片数据,节省调试时间。压缩包整体约18MB,内部文件以工程源码、原理图、PDF手册、取模工具等为主,目录按平台和功能分类存放,结构一目了然。已有219人参与学习,适合学生、电子爱好者及嵌入式工程师作为ST7735屏幕驱动移植与硬件设计的参考资料。

1. 把“串口模块”当成UART接,大概率白屏一整晚

很多第一次拿到1.44寸LCD串口模块的人,都会被背面的“串口”两个字带偏,以为接上USB转串口就能发AT指令。实际上这块屏用的是SPI串行总线:SCL、SDA、DC、CS几根信号线协同工作,和TXD/RXD的UART完全不是一回事。真正决定它能不能亮的是屏内的ST7735控制芯片,而芯片版本、初始化序列、引脚电平,都会因同型号不同批次的模块悄悄改变。下面把这套屏从硬件原理图、封装库,到C51、STM32、Arduino三套驱动源码的常见做法讲一遍,目标是让你拿到任何一块1.44寸ST7735,都能在两小时内点亮并跑出稳定显示。

2. 1.44寸ST7735模块的引脚定义、原理图分析与封装库核查

市场上1.44寸模块绝大多数是8Pin:VCC、GND、SCL、SDA、RES、DC、CS、BL。不同商家会把排针顺序打乱,有的把电源放在左侧,有的放在右侧,所以接线前一定先看模块丝印,不要相信排线颜色顺序。

2.1 认识模块上的引脚:SDA/SCL并不是I2C

先给出一份常见的引脚定义与接线对照表,以STM32和Arduino Uno为例:

引脚方向功能STM32示例Arduino Uno示例
VCC电源3.3V供电3.3V3.3V
GND电源GNDGND
SCL输入SPI时钟SCKPA5D13
SDA输入SPI数据MOSIPA7D11
RES输入复位,低有效PB0D8
DC输入数据/命令选择PA4D9
CS输入片选,低有效PA3D10
BL输入背光控制PA1(PWM)D6(PWM)

注意这里的SCL/SDA命名确实容易和I2C搞混,但它们就是SPI的SCK和MOSI,这块屏只写不读,所以没有MISO。DC和CS是ST7735驱动中最重要的两根控制线:DC为低时,主机发送的字节被解释为命令;DC为高时,主机发送的字节被写入显存。如果STM32把CS接到了硬件NSS引脚,又没有把NSS配置成软件模式,片选会被SPI外设自动拉掉,屏幕就会出现时好时坏的诡异现象。

2.2 原理图里容易看走眼的背光、复位和逻辑电平

BL引脚控制背光LED,多数模块板载了限流电阻,IO给高电平背光亮,给低电平背光灭。自己画主板原理图时,建议用三极管或MOS管做背光开关,再用PWM引脚调亮度。PWM调亮度靠的是占空比而不是降低电压,频率在1kHz以上基本看不到闪烁。

C51平台没有硬件PWM时,用定时器中断翻转引脚即可,代码可以这样写:

// C51定时器0中断,约1kHz频率做背光PWM,BL_DUTY控制亮度 void Timer0_ISR(void) interrupt 1 { static unsigned char cnt = 0; TH0 = 0xFC; // 12MHz晶振下约256us重装 TL0 = 0x18; if (++cnt < BL_DUTY) { LCD_BL = 1; } else { LCD_BL = 0; } if (cnt >= 100) { cnt = 0; } }

这段代码里BL_DUTY的取值范围是0到100,代表一个PWM周期内高电平的百分比。TH0=0xFCTL0=0x18的初值需要根据主频微调,核心是让中断周期稳定在1ms以内,否则背光频闪会被眼睛察觉。STM32和Arduino平台直接用定时器PWM外设会更省事,只需把BL引脚映射到定时器通道。

复位电路方面,RES引脚在模块上通常有RC复位,MCU侧用GPIO控制更可靠。上电后先把RES拉低至少10us,再拉高,然后等待120ms让ST7735内部DCDC稳定。如果跳过复位直接初始化,偶发情况是第一次白屏、第二次正常,排查时容易误判为屏坏。

逻辑电平是另一个高频翻车点。ST7735本身工作电压在2.8V左右,多数模块板载了LDO或稳压电路,标称支持5V供电。C51平台用5V单片机时,SPI引脚输出的高电平明显超过3.3V,如果模块没有做电平转换,长期使用建议串100到220欧电阻限流,或者用74LVC4245这一类电平转换芯片。STM32和Arduino平台则直接按3.3V逻辑电平对待。

2.3 从硬件原理图到封装库:画板前必须核对的三项

拿到所谓的“软硬件资料”后,不要急着把封装往EDA里拖。常见做法是先打开原理图PDF,核对三处:模块接插件的引脚顺序、ST7735供电去耦电容的位置、PCB排线的安装方向。商家给的原理图库和封装库,多数是把座子画成2x4排针,实际打样时还经常遇到丝印方向和排线方向相反的问题。

封装库应用时重点检查三点:

  • 检查原理图符号的引脚编号,务必和实物丝印逐一对应,引脚交换只在封装内部处理;
  • 检查封装焊盘间距,标准排针间距是2.54mm,但部分模块把排针做成了1.27mm,封装不匹配会直接插不进去;
  • 检查机械层丝印,给屏幕排线和固定孔留出空间,避免元器件与屏幕FPC干涉。

封装库里的位号、丝印和3D模型只是参考,真正决定能否装配的是排针间距、PCB外形和屏幕排线长度。画完板子再拿游标卡尺量一次实物,比反复看PDF更有价值。

3. ST7735初始化序列:从寄存器到一行能显示的驱动协议

ST7735是单芯片LCD控制器,内部GRAM对应132列162行,1.44寸屏实际使用的是128x128区域。每像素在RGB565模式下占16bit,算下来全屏缓冲是128乘以128乘以2字节,等于32KB。这个数字在后面讨论帧率和内存占用时会反复出现。

3.1 关键寄存器与初始化顺序

上电后的固定流程是:硬件复位、软件复位、Sleep Out、等待、像素格式、帧率、内存数据访问控制、正负伽玛校正、显示开启。任何一步顺序错乱都可能花屏,最常见的是跳过Sleep Out之后的120ms延时,导致首屏显示噪点。

下面是ST7735初始化过程中最关键的一组寄存器:

指令含义参数说明
SWRESET0x01软件复位无参数
SLPOUT0x11退出睡眠模式无参数,随后需延时约120ms
COLMOD0x3A像素格式0x05表示RGB565 16bit
MADCTL0x36内存数据访问控制高两位控制行列扫描,BIT3控制RGB/BGR
FRMCTR10xB1正常模式帧率三个参数,设置时钟与分频
INVCTR0xB4反色控制0x07为常见值
RAMWR0x2C写显存每个像素16bit,高字节在前
DISPON0x29显示开启无参数

3.2 一套通用的ST7735初始化代码

下面这段初始化代码不依赖具体平台,把DC和CS的翻转封装在命令和数据函数里,移植到C51、STM32、Arduino时只需要改底层的SPI_WriteByte

static void LCD_WriteCmd(uint8_t cmd) { LCD_DC_LOW(); // 命令模式 LCD_CS_LOW(); // 拉低片选 SPI_WriteByte(cmd); LCD_CS_HIGH(); } static void LCD_WriteData(uint8_t dat) { LCD_DC_HIGH(); // 数据模式 LCD_CS_LOW(); SPI_WriteByte(dat); LCD_CS_HIGH(); } static void LCD_Init(void) { LCD_RST_LOW(); // 硬件复位 delay_ms(20); LCD_RST_HIGH(); delay_ms(120); LCD_WriteCmd(0x01); // 软件复位 delay_ms(150); LCD_WriteCmd(0x11); // 退出睡眠 delay_ms(120); LCD_WriteCmd(0x3A); // RGB565 16位色 LCD_WriteData(0x05); LCD_WriteCmd(0xB1); // 帧率配置 LCD_WriteData(0x01); LCD_WriteData(0x2C); LCD_WriteData(0x2D); LCD_WriteCmd(0x36); // 行列扫描方向 LCD_WriteData(0xC0); LCD_WriteCmd(0x29); // 显示开启 }

0x36写入的0xC0设置了MY和MX位,让扫描方向从上到下、从左到右,同时保持RGB色序。不同模块的FPC走线可能不同,屏幕镜像或上下颠倒时优调这个字节,而不是怀疑屏坏。0x3A设为0x05后,后续所有写显存的数据都按RGB565高字节先行发送,CRAM地址由CASET和RASET决定。

3.3 初始化后花屏、白屏的排查顺序

初始化完屏幕全白、全黑或花屏,按下面顺序排查:

  • 先量VCC电压,模块上如果是LDO供电,输入5V时输出应在3.3V附近,低太多会白屏;
  • 再用示波器抓RES引脚,确认低电平保持时间超过10us,释放后延时够不够;
  • 然后核对SPI模式,ST7735要求CPOL=0、CPHA=0,也就是Mode0,有些STM32库默认Mode3会直接采错数据;
  • 最后检查DC接线,命令阶段DC必须为低,接反的表现为屏幕有背光但一直不显示内容。

这里还有一个隐藏坑:ST7735有多个版本,绿色FPC和红色FPC对坐标原点定义不同。128x128的1.44寸屏通常没有偏移,但用CASET/RASET做局部刷新时,坐标原点和窗口偏移量不对,会出现内容错位。这个问题放到第6章具体讲。

4. C51、STM32、Arduino三平台驱动移植:从SPI字节到显示函数

4.1 先统一SPI接口抽象层

写驱动时不要把SPI细节和画点函数揉在一起。把底层抽象成三个函数:SPI_WriteByte负责一个字节的时序,LCD_DC(LOW/HIGH)LCD_CS(LOW/HIGH)负责控制线,再加上LCD_RSTLCD_BL,上层的画点、画线、刷屏就只调同一套接口。

这样做的直接好处是:C51上验证过的初始化序列,迁到STM32时只需要替换SPI_WriteByte的实现;Arduino平台如果不想用现成库,也可以套同一套逻辑。

4.2 C51平台:IO模拟SPI,注意位序和IO模式

C51平台最常用的是STC89C52这类8位单片机,没有SPI外设或者引脚不够时,直接用普通IO模拟。下面这个函数是完整可用的:

sbit LCD_SCL = P1^0; sbit LCD_SDA = P1^1; sbit LCD_DC = P1^2; sbit LCD_CS = P1^3; sbit LCD_RST = P1^4; void SPI_WriteByte(unsigned char dat) { unsigned char i; for (i = 0; i < 8; i++) { LCD_SCL = 0; // 时钟拉低,准备改变数据 if (dat & 0x80) { LCD_SDA = 1; } else { LCD_SDA = 0; } dat <<= 1; // MSB先行 LCD_SCL = 1; // 上升沿,从机采样 } }

这段代码的核心是“先拉低SCL,再放数据,最后拉高SCL”,ST7735在SCL上升沿锁存SDA上的电平。数据位顺序必须是MSB first,dat <<= 1每次把最高位移走,配合dat & 0x80判断当前位。STC89C52的P1口是准双向口,输出高电平驱动能力偏弱,接ST7735这种需要一定灌电流的芯片时,优先用P0口加外部上拉,或者换STC15系列的推挽输出。

Keil5里同时安装C51和ARM芯片包,同一个IDE就能维护C51小项目和STM32大工程,这个组合在开发多屏项目时很顺手。但要注意,模拟SPI的频率由每条C语句编译出的汇编周期决定,12MHz晶振下SCK大约在几百kHz级别,全屏刷新会明显偏慢,所以C51平台更常见的用法是显示静态字符、小图标和数字仪表。

4.3 STM32平台:硬件SPI外设换帧率

STM32平台建议直接用硬件SPI,F103这类芯片的SPI外设跑4到9MHz很轻松,刷屏速度和IO模拟不在一个量级。基于HAL库的SPI1初始化如下:

SPI_HandleTypeDef hspi1; hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL=0 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA=0,对应Mode0 hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; HAL_SPI_Init(&hspi1);

这里的CLKPolarity和CLKPhase合起来就是Mode0,与ST7735要求的空闲低电平、第一个边沿采样一致。NSS设成SOFT后,CS引脚完全由GPIO控制,避免硬件自动片选带来的干扰。BaudRatePrescaler_8在72MHz主频下得到9MHz SCK,这已经是很多模块稳定性上限,遇到大花屏或偶发错位,先把分频调到16甚至32,SCK降到4.5MHz以下再说。

SDA接PA7,SCK接PA5,DC、CS、RES用三个普通GPIO。在意刷屏速度时,可以把整帧数据放到缓冲区,用HAL_SPI_Transmit_DMA异步发送,发送期间CPU去准备下一帧或处理按键。DMA传输过程中不要动CS,否则ST7735会把中途的字节当成新命令。

4.4 Arduino平台:现成库和自驱动两条路

Arduino平台最省事的是Adafruit_ST7735加Adafruit_GFX组合:

#include <Adafruit_GFX.h> #include <Adafruit_ST7735.h> #define TFT_CS 10 #define TFT_DC 9 #define TFT_RST 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); void setup() { tft.initR(INITR_144GREENTAB); // 1.44寸,ST7735S,绿色FPC tft.fillScreen(ST7735_BLUE); } void loop() { tft.drawChar(0, 0, 'A', ST7735_WHITE, ST7735_BLUE, 1); delay(1000); }

INITR_144GREENTAB是Adafruit库预置的初始化参数,包含延时和偏移量,只对绿色FPC的1.44寸屏有效。如果你的模块花屏,尝试换成INITR_BLACKTAB,或者在库源码里直接修改_colstart_rowstart。U8g2库的字体支持更好,显示中文和混合字符时比Adafruit方便,但占用的Flash也更大。

Arduino Uno的硬SPI引脚固定为D13、D11、D10,分别对应SCK、MOSI、CS。如果SD卡和其他SPI设备共用了这几个引脚,每次访问屏幕前要重新设置CS,否则总线竞争会显示乱码。

4.5 三平台驱动方案对比

平台SPI来源典型SCK内存占用适用场景
C51GPIO模拟约500kHz极小,需省RAM静态仪表、字符显示
STM32SPI外设+DMA4-9MHz可外扩帧缓冲动态图形、中等帧率
ArduinoSPI库4-8MHz库本身占几KB快速原型、教学验证

STM32和Arduino的选择主要看实时性和内存;C51的优势在低成本、低功耗,劣势是全屏刷新慢。对C51来说,局部刷新不是优化手段,而是唯一可行的方案。

5. 软硬件资料里的原理图与封装库:怎么核对、怎么整理、怎么复用

网上解压出来的资料包通常有几十个文件夹,命名混乱,真正能用的可能只有原理图PDF、几个驱动源码文件和封装库压缩包。第一步不是打开源码,而是先整理资料。

5.1 拿到资料包先做三件事

第一,把资料按docs、libs、firmware三类分开;第二,打开原理图PDF只看三张图:系统框图、接口电路、封装尺寸图;第三,核对封装库的引脚和模块实物丝印是否一致。

原理图里重点看BL和RES是否直接连到GPIO,有没有串二极管或限流电阻。如果BL线上已经有一路三极管驱动,主板上的IO就只负责给高电平或PWM,不需要再加驱动。反过来,如果原理图上BL直接悬空,模块可能默认不亮,需要外部上拉。

5.2 封装库导入时的细节

封装库导入时不要只拖PCB封装。先导入原理图符号,PDF标注的模块引脚和原厂符号经常对不上,需要手动改引脚名。然后是PCB封装,注意排针类型,1.44寸模块8P单排居多,间距2.54mm,也有双排2x4的设计。封装画错最常见的是丝印画到屏幕排线正下方,结果装机时FPC没有空间弯折。

各EDA之间也存在差异:立创EDA导入Altium的封装库时,部分焊盘属性和3D模型会丢失,需要重新关联;Altium导入立创EDA的封装则要检查丝印层和机械层的映射。无论从哪个方向转,最终都要拿数据手册里的封装尺寸图核对一遍。

5.3 建议的工程目录结构

一个能长期复用的资料目录是这样的:

lcd_1in44_st7735/ ├── docs/ │ ├── ST7735_datasheet.pdf │ ├── Module_schematic.pdf │ └── 1in44_mechanical.pdf ├── libs/ │ ├── ST7735_1in44.schlib │ ├── ST7735_1in44.pcblib │ └── README.txt ├── firmware/ │ ├── c51_lcd_demo/ │ ├── stm32_lcd_demo/ │ └── arduino_lcd_demo/ └── tools/ └── lcd_test.py

docs里放数据手册和机械图,libs里放原理图库、封装库和说明,firmware下放三个平台的驱动源码,tools里放字模生成和测试脚本。这样的组织方式在后续画板、改板、换平台时都能直接复用。

5.4 用字模生成脚本替代手敲点阵

驱动源码里最繁琐的是中文字模和ASCII字模。手工按位填十六进制数组容易错位,常见做法是写脚本生成。下面这段Python脚本可以从点阵字库读取字符并输出C数组:

def read_glyph(ch, w=8, h=8): # 按GB2312或Unicode定位字库中的位图数据 # 返回一个长度为h的整数列表,每个整数代表一行的bit pass def glyph_to_c(ch, w=8, h=8): rows = read_glyph(ch, w, h) return ", ".join(f"0x{row:02X}" for row in rows) print(glyph_to_c('A'))

用FreeType或点阵字库生成出来的数组,可以直接粘贴进C51的code区或STM32的const数组。比起手敲点阵,脚本生成快且不会错位。这里还有一个常见误用:直接把8x8字模塞进16位色LCD,字形会显得很小,建议放大两倍或改用12x12、16x16字模。

配合本地仿真工具或逻辑分析仪调试时,资料包的整洁程度直接影响排查速度。同一批买的屏,厂家给出的初始化代码可能只适配其中某一批FPC,保留好每批模块的偏移量记录,比反复刷固件更高效。

6. 点亮之后:用逻辑分析仪验证ST7735时序,再用局部刷新榨干小屏性能

屏幕能亮只是开始。判断驱动是否真的健康,靠逻辑分析仪抓SPI总线是最快的方式。CLK接模块SCL,MOSI接SDA,CS和DC同时采样,触发方式设成CS下降沿。上电后第一帧数据里应当能看到0x11、0x3A、0x36、0x29这一串命令,且每条命令前的DC为低,数据前的DC为高。SCK频率超过模块标称时,波形上会出现台阶或间距不均匀,这就是偶发花屏的来源。

验证完以后,最值得做的优化是局部刷新。ST7735支持CASET和RASET设定矩形窗口,向RAMWR写数据时只填充窗口区域:

void LCD_SetWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { LCD_WriteCmd(0x2A); // 列地址 LCD_WriteData(0x00); LCD_WriteData(x0 + XOFF); LCD_WriteData(0x00); LCD_WriteData(x1 + XOFF); LCD_WriteCmd(0x2B); // 行地址 LCD_WriteData(0x00); LCD_WriteData(y0 + YOFF); LCD_WriteData(0x00); LCD_WriteData(y1 + YOFF); LCD_WriteCmd(0x2C); // 开始写显存 }

显示时钟或百分比数字时,只需要更新数字所在的小窗口。128x128全屏刷新要写32KB数据,窗口宽度20、高度16时只有640字节,C51平台也能稳定跑到每秒几次更新。XOFF和YOFF由屏幕FPC版本决定,绿色FPC多为0,红色FPC常见值为2和1,颜色偏移时先换这两个偏移量。

用逻辑分析仪观察局部刷新时,窗口设置帧和写显存帧之间不能夹带其他SPI传输,否则坐标会被写乱。点亮后如果出现噪点,优先检查0x36的RGB/BGR位,而不是怀疑硬件损坏。

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

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

AI训练师能力体系:数据闭环、模型迭代与业务对齐

1. 这不是一张证书&#xff0c;而是一套可落地的AI工程能力验证体系“阿里巴巴达摩院人工智能训练师&#xff08;高级&#xff09;”——听到这个名称&#xff0c;很多人第一反应是“又一个企业认证”&#xff0c;甚至下意识归类为“培训结业证”或“内部考核标签”。但在我连续…

作者头像 李华
网站建设 2026/9/16 2:52:14

固定长度滑动窗口经典题:子数组最大平均数 I 全解析

先回答一个不少刷题新手都问过的问题&#xff1a;力扣上那道“子数组最大平均数 I”&#xff08;LeetCode 643&#xff09;&#xff0c;标签是简单题&#xff0c;但为什么很多人一上来就写错&#xff1f;我见过不少人在评论区吐槽&#xff0c;说自己用双重循环暴力解&#xff0…

作者头像 李华
网站建设 2026/9/16 2:51:10

2026企业AI知识库选型核心:领域适配、权限粒度与三元协同

1. 为什么2026年企业不能再凭感觉选AI知识库——从三个真实崩盘现场说起去年Q3&#xff0c;我陪一家中型制造企业的IT负责人做知识库升级选型。他们花三个月时间测试了四家主流平台&#xff0c;最后上线两周就遭遇文档解析失败率超68%、多轮对话上下文丢失、权限颗粒度仅支持“…

作者头像 李华
网站建设 2026/9/16 2:50:17

PC端绿色工具集合:无需安装的Windows效率基线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 2:49:24

NPP趋势分析:Theil-Sen与Mann-Kendall的Python实现全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 2:49:02

鸿蒙版微信实测:高清低码通话与拍摄输入成独家亮点

你有没有发现&#xff0c;身边用鸿蒙手机的人越来越多了&#xff0c;但很多人拿到手机后的第一件事&#xff0c;反而是去应用市场搜“微信能不能装”。搜完之后有人惊喜&#xff1a;不仅能用&#xff0c;而且有些功能连安卓、iPhone上都没有。作为从Mate 40用到Mate 70、中间还…

作者头像 李华