ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

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寸模块绝大多数是8PinVCC、GND、SCL、SDA、RES、DC、CS、BL。不同商家会把排针顺序打乱有的把电源放在左侧有的放在右侧所以接线前一定先看模块丝印不要相信排线颜色顺序。2.1 认识模块上的引脚SDA/SCL并不是I2C先给出一份常见的引脚定义与接线对照表以STM32和Arduino Uno为例引脚方向功能STM32示例Arduino Uno示例VCC电源3.3V供电3.3V3.3VGND电源地GNDGNDSCL输入SPI时钟SCKPA5D13SDA输入SPI数据MOSIPA7D11RES输入复位低有效PB0D8DC输入数据/命令选择PA4D9CS输入片选低有效PA3D10BL输入背光控制PA1PWMD6PWM注意这里的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频率做背光PWMBL_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周期内高电平的百分比。TH00xFC、TL00x18的初值需要根据主频微调核心是让中断周期稳定在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退出睡眠模式无参数随后需延时约120msCOLMOD0x3A像素格式0x05表示RGB565 16bitMADCTL0x36内存数据访问控制高两位控制行列扫描BIT3控制RGB/BGRFRMCTR10xB1正常模式帧率三个参数设置时钟与分频INVCTR0xB4反色控制0x07为常见值RAMWR0x2C写显存每个像素16bit高字节在前DISPON0x29显示开启无参数3.2 一套通用的ST7735初始化代码下面这段初始化代码不依赖具体平台把DC和CS的翻转封装在命令和数据函数里移植到C51、STM32、Arduino时只需要改底层的SPI_WriteBytestatic 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要求CPOL0、CPHA0也就是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_RST和LCD_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 firstdat 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平台建议直接用硬件SPIF103这类芯片的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; // CPOL0 hspi1.Init.CLKPhase SPI_PHASE_1EDGE; // CPHA0对应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甚至32SCK降到4.5MHz以下再说。SDA接PA7SCK接PA5DC、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.pydocs里放数据手册和机械图libs里放原理图库、封装库和说明firmware下放三个平台的驱动源码tools里放字模生成和测试脚本。这样的组织方式在后续画板、改板、换平台时都能直接复用。5.4 用字模生成脚本替代手敲点阵驱动源码里最繁琐的是中文字模和ASCII字模。手工按位填十六进制数组容易错位常见做法是写脚本生成。下面这段Python脚本可以从点阵字库读取字符并输出C数组def read_glyph(ch, w8, h8): # 按GB2312或Unicode定位字库中的位图数据 # 返回一个长度为h的整数列表每个整数代表一行的bit pass def glyph_to_c(ch, w8, h8): rows read_glyph(ch, w, h) return , .join(f0x{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接模块SCLMOSI接SDACS和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位而不是怀疑硬件损坏。本文还有配套的精品资源点击获取
返回列表