
简介这份资源面向嵌入式初学者与需要快速上手彩屏显示的开发者围绕STM32F103RCT6驱动1.44英寸TFT液晶屏展开解决从引脚配置、SPI通信到屏幕初始化与图像刷新的完整实现问题。压缩包共86个文件约289KB以38个h头文件与32个c源文件为主体涵盖LCD驱动、GUI绘制、字库与图片数据、延时与LED等模块另含4个s启动文件、Keil工程文件及一个可直接烧录的hex固件便于对照工程结构理解各层代码分工。已有4053人学习下载说明其在同类彩屏入门实践中具有较高参考价值。读者可从中获得SPI接口下命令与数据发送、显示参数初始化、显存缓冲与刷新流程的具体实现并借助现成工程验证硬件连接与显示效果适合作为小型仪表盘、便携显示终端等图形界面项目的起步模板。1. 一块 1.44 寸屏点亮之前先把需求钉死STM32F103RCT6 配 1.44 寸 TFT是嵌入式课设和毕设里出现频率极高的一组搭配。但真正动手时多数人卡住的地方不是写不出显示代码而是需求没定清楚屏幕是 3.3V 还是 5V 供电、驱动芯片是 ST7735 还是 ST7735S、用硬件 SPI 还是软件模拟、要不要做中文字库、刷新率要求多少。这些问题在画板子之前不定后面返工的概率接近百分之百。这套方案面向的是要交一份完整课程设计或毕业设计的同学也适合需要快速搭一个显示原型的从业者。它要解决的核心问题只有一个用最小外设依赖把一块 1.44 寸 128×128 的 TFT 稳定驱动起来并且留出可扩展的图形接口。2. 硬件方案设计最小系统与屏幕接口的电气匹配2.1 主控与屏幕的引脚分配STM32F103RCT6 是 64 脚、256KB Flash、48KB RAM 的型号资源驱动一块 128×128 的屏幕绰绰有余。1.44 寸 TFT 常见驱动芯片是 ST7735 系列接口为四线 SPISCL、SDA、RES、DC外加 CS 和 BLK。我一般把硬件 SPI1 分配给屏幕引脚安排如下屏幕引脚STM32 引脚功能说明SCLPA5SPI1_SCK时钟SDAPA7SPI1_MOSI数据RESPB0复位低电平有效DCPB1数据/命令选择CSPA4片选低有效BLKPB5背光控制可 PWM这套分配的好处是 SPI1 的时钟和数据脚固定不用重映射初始化代码最少。DC 和 RES 用普通 GPIO 推挽输出即可速度要求不高。背光如果只做开关接一个 GPIO 输出高电平就行要做亮度调节把 BLK 接到带定时器的引脚上输出 PWM这一点在答辩时是个加分项因为能体现你对功耗和用户体验的考虑。2.2 电平与供电的坑1.44 寸 TFT 模块通常自带 3.3V 稳压和电平转换但市面上模块质量参差。血泪经验是拿到模块先看背面丝印确认 VCC 标的是 3.3V 还是 5V。如果模块没有电平转换芯片而你又用 5V 供电STM32 的 IO 耐不住轻则通信不稳重则烧引脚。稳妥做法是统一用 3.3V 供电逻辑电平天然匹配。另外屏幕背光电流在 20mA 到 40mA 之间不要直接从 STM32 的 IO 取电用三极管或 MOS 管驱动IO 只出控制信号。2.3 通信方式的选择硬件 SPI 和软件模拟 SPI 的取舍是这个项目里第一个需要想清楚的设计决策。硬件 SPI 速度快配置好之后一个字节的收发由外设完成CPU 占用低适合刷图、刷色块。软件模拟 SPI 灵活引脚随便挑调试时可以用逻辑分析仪逐位看波形但速度慢刷全屏明显能看出逐行扫描的痕迹。我的建议是正式方案用硬件 SPI把速率配到 18MHz 左右ST7735 手册标称最高可到 15MHz 以上实际跑 18MHz 多数模块能稳住如果遇到花屏先降到 9MHz 排除时序问题再逐步往上试。软件 SPI 留作备用方案写成一个宏开关调试阶段切过去定位问题。3. 驱动层实现从初始化序列到图形接口3.1 ST7735 初始化序列的写法ST7735 上电后需要一串命令完成复位、色彩格式、扫描方向、伽马校正等配置。这段初始化序列是整个驱动的地基写错一条后面全是花屏。下面是我常用的初始化骨架命令值来自 ST7735 数据手册参数按 128×128 屏的常见配置给/* ST7735 初始化命令 参数 延时逐条发送 */ static void TFT_InitSequence(void) { TFT_WriteCmd(0x01); /* 软件复位 */ TFT_Delay(120); TFT_WriteCmd(0x11); /* 退出睡眠 */ TFT_Delay(120); TFT_WriteCmd(0x3A); /* 色彩格式 */ TFT_WriteData(0x05); /* 16bit/pixelRGB565 */ TFT_WriteCmd(0x36); /* 扫描方向 */ TFT_WriteData(0x00); /* 行列不交换从上到下 */ TFT_WriteCmd(0x21); /* 开启反显按模块实际情况取舍 */ TFT_WriteCmd(0x13); /* 正常显示模式 */ TFT_WriteCmd(0x29); /* 开启显示 */ }这段代码的关键在三个参数。0x3A的0x05决定每个像素占 16 位也就是 RGB565红色 5 位、绿色 6 位、蓝色 5 位这是 1.44 寸屏最常用的格式显存占用和色彩表现平衡得最好。0x36的0x00控制扫描方向如果屏幕显示出来是镜像或旋转的改这个字节的低三位就能翻转行列和颜色顺序不用改接线。0x21是反显开关有些模块出厂默认需要反显才正常如果显示出来颜色整体反了把这条命令去掉或换成0x20试试。初始化里每个延时都不能省尤其是复位后的 120ms省了就会出现偶发不亮。3.2 底层读写函数的封装命令和数据的区分靠 DC 引脚DC 拉低写命令拉高写数据。把这两个动作封装成独立函数上层调用时不用关心引脚状态/* 写一个命令字节DC0CS0SPI 发送CS1 */ void TFT_WriteCmd(uint8_t cmd) { TFT_DC_LOW(); TFT_CS_LOW(); SPI_Transmit(cmd, 1); TFT_CS_HIGH(); } /* 写一个数据字节DC1其余同上 */ void TFT_WriteData(uint8_t data) { TFT_DC_HIGH(); TFT_CS_LOW(); SPI_Transmit(data, 1); TFT_CS_HIGH(); }这里有个容易忽略的细节CS 的拉低和拉高要包住整个字节传输不能每个位都翻转。ST7735 在 CS 上升沿锁存数据如果 CS 提前拉高最后一个位可能丢失表现为偶发的像素错位。另外连续写多个数据时可以把 CS 一直拉低、DC 保持高中间不释放片选这样刷屏速度能提升一截。我一般会再封装一个TFT_WriteDataBulk函数专门处理批量像素内部只拉一次 CS。3.3 绘图接口的分层设计驱动层之上要留一层图形接口把“画点、画线、画矩形、显示字符”这些操作暴露给应用层。分层的好处是应用代码不碰 SPI 和寄存器换屏幕型号时只改驱动层。画点函数是所有图形的基础/* 在 (x,y) 画一个 RGB565 颜色的点 */ void TFT_DrawPoint(uint16_t x, uint16_t y, uint16_t color) { if (x TFT_WIDTH || y TFT_HEIGHT) return; /* 边界保护 */ TFT_SetWindow(x, y, x, y); /* 设置 1x1 显示窗口 */ TFT_WriteCmd(0x2C); /* 写显存命令 */ TFT_WriteData(color 8); /* 高字节先发 */ TFT_WriteData(color 0xFF); /* 低字节后发 */ }TFT_SetWindow内部发的是0x2A列地址和0x2B行地址两条命令各带起止坐标。RGB565 是 16 位SPI 按字节传所以要先发高字节再发低字节顺序反了颜色会变成乱码。画线用 Bresenham 算法画矩形用四条线拼填充矩形则把窗口设成整个矩形区域然后连续写width*height个颜色值这样比逐点画快一个数量级。字符显示需要字模ASCII 用 8×16 点阵每个字符 16 字节中文用 16×16 点阵每个字 32 字节。字模数据放在单独的.c文件里用const修饰存到 Flash不占 RAM。4. 应用层与显示效果让屏幕真正“有用”4.1 界面布局与刷新策略128×128 的屏幕不大界面设计要克制。我一般把屏幕分成三个区域顶部 16 像素做状态栏显示标题或图标中间 96 像素做主显示区放数据、波形或菜单底部 16 像素做提示栏。刷新策略上全屏刷新只在切换页面时做平时只刷新变化的区域。比如显示一个温度值只重绘数字所在的矩形背景不动这样既快又不闪。如果整屏每秒刷几十次SPI 带宽吃满主循环里其他任务会被拖慢这是很多同学答辩时被问到的点。4.2 中文字库的取舍中文显示是这个项目里工作量弹性最大的部分。取模软件生成 16×16 字模每个字 32 字节常用 500 个字就是 16KBSTM32F103RCT6 的 256KB Flash 完全放得下。但要注意字模的扫描方式和取模软件的设置必须一致横向取模、字节倒序还是正序选错一个选项显示出来就是乱码方块。我的做法是先只取界面用到的几十个字验证显示正常后再批量补全避免一次性生成一大堆字模却不知道哪里配错。如果项目对中文要求不高用拼音或英文界面能省掉整个字库模块这也是答辩时可以主动说明的简化决策。4.3 一个可复用的菜单框架课程设计里经常要做按键菜单。把菜单抽象成结构体数组每项包含显示文本、图标索引和回调函数指针屏幕只负责根据当前选中项渲染高亮按键中断里改索引。这样加一页菜单只是往数组里加一项不用动显示逻辑。这个设计在答辩时很好讲因为它体现了数据与显示分离的思路比把所有界面写成一堆if-else要经得起追问。5. 避坑与排查调试阶段最容易翻车的五件事5.1 屏幕全白或全黑没有任何显示现象是上电后背光亮但屏幕无内容。原因通常是初始化序列没跑完或者复位时序不对。解决方法是先用万用表确认 RES 引脚在上电后有一个低电平脉冲如果没有检查复位代码里拉低和拉高的延时是否足够再确认 SPI 的时钟极性配置ST7735 要求空闲低电平、第一个边沿采样对应 SPI 模式 0配成模式 3 也能工作但部分模块会挑。最后用逻辑分析仪抓 SCL 和 SDA看初始化命令是否真的发出去了。5.2 显示内容整体偏移或只显示一部分现象是图像跑到屏幕外或者右下角缺一块。原因是0x2A和0x2B的窗口坐标没有按屏幕实际分辨率设置或者扫描方向字节和坐标计算不匹配。1.44 寸屏有些模块的可视区域在显存里不是从 (0,0) 开始而是有 1 到 2 像素的偏移。解决办法是在TFT_SetWindow里加一个偏移量宏试出正确值后固定下来。这个偏移量因模块批次而异换屏要重新确认。5.3 颜色不对红蓝互换或整体发灰现象是画红色出来是蓝色。原因是 RGB565 的字节序或位序配错。先确认发送时是高字节在前再检查0x3A参数是不是0x05。如果红蓝互换把颜色值的 R 和 B 分量对调即可不用改底层。整体发灰通常是反显没关或者伽马校正没配前者去掉0x21后者补上伽马命令。5.4 刷屏时程序卡死或看门狗复位现象是全屏填充时主循环停住。原因是逐点写显存时每次都拉 CS、发命令开销太大或者 SPI 传输用了阻塞等待且没有超时。解决办法是用批量写函数窗口设好后连续发数据同时检查 SPI 的while等待标志位有没有加超时计数防止外设异常时死等。如果开了看门狗刷屏前先喂一次狗。5.5 背光干扰通信现象是背光一亮屏幕就花。原因是背光电流大走线离 SPI 太近产生耦合或者背光控制引脚和 SPI 引脚相邻。解决方法是背光电源单独走线、加滤波电容软件上在初始化完成后再开背光避免上电瞬间的电流冲击影响 SPI 时序。6. 验收与答辩怎么证明这套显示方案是可靠的验收这块我一般按“功能清单 边界测试 现场演示”三步走。功能清单列清楚屏幕能点亮、能显示纯色、能显示 ASCII、能显示中文、能画线画矩形、能刷新动态数据每项对应一个可独立调用的测试函数答辩时按顺序跑一遍评委一眼能看出覆盖度。边界测试专门挑容易出问题的地方坐标传 (127,127) 看是否越界、颜色传 0x0000 和 0xFFFF 看黑白是否正常、连续刷屏十分钟看是否死机。现场演示最忌讳只放一张静态图准备一个按键切换页面的小交互再准备一个实时变化的数值显示能体现刷新策略的设计。答辩时被问得最多的是“为什么用硬件 SPI 不用软件模拟”和“刷新率是多少”。前一个问题按第 2 章的取舍逻辑答重点说 CPU 占用和批量传输后一个问题要能给出实测数字比如全屏填充耗时多少毫秒用定时器或示波器测一次记下来比背理论值有说服力。还有一个高频问题是“如果换一块不同驱动芯片的屏怎么办”这时候把驱动层和应用层分离的设计讲出来说明只需替换初始化序列和底层读写函数上层图形接口不动这个回答基本能拿满分。从那以后我每次做带屏的项目都会在画板子之前先把屏幕模块飞线点亮、把初始化序列跑通再定引脚和封装这个习惯帮我省掉了至少两次改板。希望帮到你。本文还有配套的精品资源点击获取