简介:STM32F103RCT6与1.44英寸TFT屏幕的完整工程包,面向需要快速实现彩色显示的嵌入式开发者,也适合学习SPI通信和LCD驱动原理的入门者。工程已配置好Keil MDK项目文件,包含标准外设库初始化、LCD驱动、GUI图形显示、字库与图片资源等模块,覆盖从引脚定义、SPI时钟配置到屏幕刷新显示的完整链路,支持128×128分辨率显示,可直接在开发板上编译运行。资源包共86个文件,以C源码和头文件为绝对主体,另有启动文件、hex固件、Keil工程配置文件、烧录脚本及说明文档,压缩后仅289KB,体积小巧,便于存储和分享。已有4000余人学习下载,readme与JLink配置能帮助快速验证硬件连接;无论是调试SPI时序、LCD初始化序列,还是学习图形界面设计,这份工程都能提供可直接参考的完整代码与排错思路,适合直接迁移到同类彩屏项目中。
1. STM32F103RCT6 + 1.44TFT 屏幕显示:一颗芯片和一块小屏能玩到什么程度
STM32F103RCT6 + 1.44TFT 屏幕显示这个项目,看起来就是个入门点屏例程,但实际上手你会发现,能点亮和能长期稳定显示之间,隔着一层 ST7735S 驱动芯片的脾气。这块 128x128 分辨率的 1.44 寸彩屏,是市面上最常见的 SPI 接口小屏,几乎每个做嵌入式的人都买过一块,也都为它的白屏、花屏、偏色折腾过。这个项目适合两类人:第一类是刚学完寄存器操作、想找一块屏练手的新手,第二类是手里有现成 256KB Flash 的 F103RCT6、想快速搭一个带彩色界面产品原型的开发者。说白了,这不是那种复杂到需要大作业的生产级项目,但它是你从“点灯”走向“人机交互界面”最划算的一步。
2. 工程结构和硬件接线:先看清引脚,再谈刷屏
2.1 源码包里的目录大概长什么样
这种 1.44TFT 工程的源码包,最常见的组织方式是把代码分成User、System、Hardware、Core和Project几个目录。User里放 main.c 和中断处理,Hardware里放 lcd.c、lcd.h、gpio.c 这些跟屏幕直接相关的驱动,Project下是 Keil 工程文件。不同的发货商打包习惯不太一样,有的会把驱动直接摊在User下,有的会叫BSP,但核心文件始终是那几个:lcd.c、lcd.h、st7735.c、spi.c,找到 main.c 就找到了程序的入口。
打开工程后第一件事不是点编译,而是确认工程配置的芯片型号确实是 STM32F103RCT6。如果这个选项不对,程序能编译过,但下载之后跑起来的行为会很奇怪,尤其是当工程里用了RCC_APB2Periph_AFIO这类重映射功能时,外设可能根本没接到你想让它们待的引脚上。我一般会先在Device目标选项里看一眼,顺手把Flash大小改成 256K,避免 debug 时出现校验错误。
2.2 硬件接线表:七个引脚,一个都不能错
1.44 寸 TFT 屏模块背后一般都排着 8 根引脚,从上到下通常是VCC、GND、CS、RESET、DC/RS、MOSI/SDA、SCLK/SCK、LED。其中LED是背光控制脚,有的模块写着BLK,有的直接叫LEDA,这一脚很多人接错,后面会单说。
| 屏引脚 | 对应 STM32 GPIO | 说明 |
|---|---|---|
| VCC | 3.3V | 一定要用 3.3V,不要接 5V,ST7735S 不是 5V 容忍芯片 |
| GND | GND | 和单片机共地,不能只靠下载器的地 |
| CS | PA4 | 片选,低电平选中 |
| RESET | PA3 | 复位,低电平有效 |
| DC/RS | PA2 | 命令/数据选择,低电平写命令,高电平写数据 |
| MOSI/SDA | PA7 | SPI2 MOSI |
| SCLK/SCK | PA5 | SPI2 SCK |
| LED | 3.3V 或 PB0 | 背光控制,接 3.3V 常亮,GPIO 控制可调 |
我见过不少人在屏幕能显示但亮度很暗时怀疑背光坏了,结果万用表一量发现LED引脚悬空。这个引脚的驱动能力其实很弱,直接接 3.3V 点亮没问题,但最好串一个 10Ω 电阻限流,别直接怼到 5V 上去。如果你的屏模块默认带电阻,直接短接也能用,但手头有电阻就串上,费不了多少事。
2.3 从下载到点亮的完整流程
接线完成后,先不要急着插电脑,先把 BOOT0 跳线帽的状态确认一下。很多板子出厂时 BOOT0 默认接高电平,这样会从系统存储器启动,程序根本不会跑,屏幕自然也没反应。把 BOOT0 拨到低电平,然后用手按一下复位,这是让芯片从 Flash 启动的最基本操作,但也是新板子翻车的第一大原因。
把下载器接到 SWD 四线接口:SWDIO、SWCLK、GND、3.3V各占一头。Keil 里在Debug设置中选择对应下载器型号,然后在Flash Download勾选Reset and Run,这样烧录完成后会自动复位运行。编译下载后,如果屏幕先闪了一下花屏然后显示出色块或彩条,说明你的 SPI 通信已经通了,接下来再去折腾显示内容。
提示:第一次点亮屏幕看到花屏并不是故障,这是正常的。ST7735S 上电后 RAM 里的值是随机的,只有初始化序列跑完,它才会进入可控状态。
3. 核心驱动拆解:ST7735S 初始化序列和 SPI 通信
3.1 为什么是 SPI2 而不是模拟 GPIO 时序
STM32F103RCT6 有 3 个 SPI 外设,这个工程里几乎毫无争议地使用 SPI2,因为 F103 的 SPI2 可以被重映射到不同引脚组,而 PA5、PA7 这组引脚在多数小板上直接引出,不用飞线。另一个原因是,屏幕要刷新 128x128 像素的 RGB565 数据,一帧就是 32768 字节,如果用 GPIO 模拟时序,单是刷一帧就需要几十万次翻转,CPU 全部耗在上面,啥事都干不了。用硬件 SPI 加 DMA,能把刷屏时间从几十毫秒压缩到几毫秒,CPU 可以腾出来跑别的逻辑。
SPI2 的时钟源来自 APB1,F103 的 APB1 默认最高 36MHz,所以 SPI2 的波特率不能超过 18MHz。实际工程里一般把分频设成 4 或 8,也就是 9MHz 或 4.5MHz。1.44TFT 的 ST7735S 标称最高支持 15MHz SPI 时钟,但实际用 9MHz 是最稳的,信号线稍长一点也不会翻车。
3.2 GPIO 和 SPI 初始化:这段代码你要逐行看
以下是这个工程里 GPIO 和 SPI 初始化的核心代码,我按最常用的标准外设库风格来写。如果你手里是 HAL 库版本,逻辑完全一样,只是函数名换成HAL_SPI_Transmit而已。
void LCD_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // MOSI(PA7) 和 SCK(PA5) 复用推挽输出,速率 50MHz GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // CS(PA4) RESET(PA3) DC(PA2) 普通推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 背光控制脚接 PB0,也可以直接接 3.3V GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } void LCD_SPI_Init(void) { SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // 屏幕不需要回传,只写 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8 位数据宽度 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 时钟空闲高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 第二个边沿采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 软件管理片选 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); }这段代码值得注意的点有两个。第一,SPI_Direction_1Line_Tx意味着 SPI2 只工作在单线发送模式,MISO 引脚被释放出来可以做别的用途,因为 ST7735S 根本不回传数据,读出来的 ID 也没啥用。第二,SPI_CPOL_High和SPI_CPHA_2Edge是 ST7735S 手册上明确要求的 SPI Mode 3,如果你在初始化时把这个搞成了 Mode 0,屏幕大概率白屏,这是新手最容易踩的坑。
写命令和写数据的区分,靠的是硬件上 DC 引脚的电平,软件里就是一条语句的事:
#define LCD_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define LCD_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4) #define LCD_DC_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_2) #define LCD_DC_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_2) void LCD_Write_Cmd(uint8_t cmd) { LCD_CS_LOW(); LCD_DC_LOW(); // 命令模式 SPI2_SendByte(cmd); LCD_CS_HIGH(); } void LCD_Write_Data(uint8_t data) { LCD_CS_LOW(); LCD_DC_HIGH(); // 数据模式 SPI2_SendByte(data); LCD_CS_HIGH(); }LCD_Write_Cmd和LCD_Write_Data是驱动里调用频率最高的两个函数,ST7735S 的初始化序列和后续所有绘图指令都建立在它们之上。需要特别说明的是,片选引脚 CS 用软件控制,每次发送前后都要拉低拉高,不能偷懒不拉高。如果 CS 一直处于低电平,多个 SPI 设备挂在同一条总线上时会互相干扰,哪怕你只接了这一个屏,也建议养成这个习惯。
3.3 ST7735S 初始化序列:每一条命令都在干什么
初始化序列是让屏幕从“上电混沌”进入“可寻址状态”的关键代码,也是最容易出玄学问题的地方。完整序列有二十多条命令,我这里抽出最核心的几条,拆开讲清楚:
void LCD_Init(void) { LCD_RESET_Init(); // 硬复位 GPIO_ResetBits(GPIOA, GPIO_Pin_3); delay_ms(20); GPIO_SetBits(GPIOA, GPIO_Pin_3); delay_ms(20); // 软复位 LCD_Write_Cmd(0x01); // SWRESET delay_ms(120); // 这里必须等够时间 LCD_Write_Cmd(0x11); // SLPOUT,退出睡眠模式 delay_ms(120); // 退出睡眠后也要延时 LCD_Write_Cmd(0xB1); // FRMCTR1,设置帧率 LCD_Write_Data(0x01); LCD_Write_Data(0x2C); LCD_Write_Data(0x2D); LCD_Write_Cmd(0x20); // INVOFF,关闭颜色反转 LCD_Write_Cmd(0x3A); // COLMOD,设置像素格式 LCD_Write_Data(0x05); // 16 位 RGB565 LCD_Write_Cmd(0x2A); // CASET,列地址设置 LCD_Write_Data(0x00); LCD_Write_Data(0x00); LCD_Write_Data(0x00); LCD_Write_Data(0x7F); // 128 像素 LCD_Write_Cmd(0x2B); // RASET,行地址设置 LCD_Write_Data(0x00); LCD_Write_Data(0x00); LCD_Write_Data(0x00); LCD_Write_Data(0x7F); // 128 像素 LCD_Write_Cmd(0x29); // DISPON,打开显示 delay_ms(20); }初始化序列里最容易忽略的是延时。SWRESET之后,ST7735S 需要最少 120ms 才能完成内部状态机的恢复;SLPOUT之后同样需要 120ms 才能真正进入工作模式。很多精简驱动里把延时缩短到 10ms,结果就是屏幕偶尔亮偶尔不亮,或者亮起来颜色不对。经验做法是在这两个命令后都留给 120ms,不要省。
3.4 画点、画线和填充矩形:显示内容的地基
屏幕初始化完毕,接下来就是往显存里写数据。ST7735S 的写入方式是先设置一个地址窗口,然后连续写入,像素宽度是 16bit 的 RGB565 颜色值。最小的显示原语是画点函数:
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color) { if (x >= LCD_WIDTH || y >= LCD_HEIGHT) return; LCD_Write_Cmd(0x2A); // CASET 列地址 LCD_Write_Data(x >> 8); LCD_Write_Data(x & 0xFF); LCD_Write_Data(x >> 8); LCD_Write_Data(x & 0xFF); LCD_Write_Cmd(0x2B); // RASET 行地址 LCD_Write_Data(y >> 8); LCD_Write_Data(y & 0xFF); LCD_Write_Data(y >> 8); LCD_Write_Data(y & 0xFF); LCD_Write_Cmd(0x2C); // RAMWR 写显存 LCD_Write_Data(color >> 8); LCD_Write_Data(color & 0xFF); }这个函数每次调用都要传输 8 个地址参数,效率很低,一帧画面如果 32768 个像素全部调用它,光传参就要浪费大量时间。所以实际画图时会用一个更高效的方式:先设置一次地址窗口覆盖整个屏幕,然后连续写入所有像素数据。画线函数可以在画点基础上用 Bresenham 算法或直接进行线性插值,对于 128x128 的小屏,即使是最朴素的直线方程法性能也已经足够。
填充矩形是刷背景最常用的函数,它的核心是只设置一次窗口然后循环写颜色。如果你要做一个进度条或者按钮背景,这个函数会是调用最多的工具。进阶一点的玩法,是把屏幕的一整块区域用 DMA 连续发送,这才是 F103 相对 GPIO 模拟时序最大的优势所在。
3.5 DMA 刷屏:让 CPU 从搬运工变成监工
SPI 发送一个字节需要 CPU 全程参与,CPU 每写一次 DR 寄存器就要等 TXE 标志位,这时 CPU 基本都在傻等。刷一帧 32768 字节的数据,如果等一个字节一个字节送,哪怕 9MHz 波特率也浪费大量算力。DMA 模式的做法是把数据在内存里的起始地址告诉 DMA 控制器,然后让它自动往 SPI2 的 DR 寄存器搬数据,搬完触发一次中断通知 CPU。
void LCD_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)frame_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = LCD_WIDTH * LCD_HEIGHT * 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); } void LCD_DMA_Start(void) { DMA_Cmd(DMA1_Channel4, ENABLE); while (!DMA_GetFlagStatus(DMA1_FLAG_TC4)); // 等待传输完成 DMA_Cmd(DMA1_Channel4, DISABLE); }DMA1 的 Channel4 是 SPI2_TX 的专用通道,这个映射关系是芯片手册固定的,不能随意改。DMA_PeripheralDataSize和DMA_MemoryDataSize都设为 Byte,因为 SPI2 的 DR 寄存器虽然按 32 位地址访问,但每次有效数据是低 8 位,如果设成 HalfWord 反而容易出错。DMA_M2M必须关闭,否则 DMA 会走内存到内存模式,完全绕过 SPI 外设,这也是新手常犯的错。有了 DMA,刷一屏的时间大概能缩短到原来的三分之一以下,CPU 几乎完全腾出手来处理按键、传感器这些真正的业务逻辑。
4. 常见问题排查:白屏、偏色、花屏、下载失败的现场还原
4.1 白屏:第一反应先查驱动芯片而不是代码
现象:初始化序列跑完,屏幕一点反应没有,整个屏白得发亮,背光是亮的。
原因:90% 的情况是驱动 IC 不匹配。1.44 寸屏存在两个完全不同的驱动芯片方案,ST7735S 是主流,但也有一些老批次用的是 ILI9341 或者两颗芯片级联方案,它们的初始化命令完全不同。如果你拿了一份为 ST7735S 写的工程,插到 ILI9341 上,初始化序列根本执行失败,自然白屏。另外,SPI 模式搞错也会白屏,ST7735S 要求 Mode 3,如果你配置成了 Mode 0,数据在错误的时钟沿被采样,同样白屏。
解决:先用放大镜看模块背后的丝印,确认驱动型号。如果是 ST7735S,再检查 SPI 模式是不是 Mode 3。两手都做完还白屏,拿万用表量 VCC 和 GND 之间有没有 3.3V,很多时候是杜邦线接触不良导致电压跌落。
4.2 偏色:红色变蓝色,蓝色变绿色,问题在 RGB 顺序
现象:屏幕能显示内容,但颜色明显错乱,比如红色像素显示成蓝色,或者整体色调偏青偏黄。
原因:ST7735S 内部有一个颜色过滤器顺序控制位,默认可能是 RGB 顺序,也可能是 BGR 顺序。不同批次屏幕在出厂时这个配置不一样,如果驱动里没设置,或者设置的方向和屏本身相反,RGB 三通道就会被交换。
解决:在初始化序列里补上0x36(MADCTL)寄存器设置。这个寄存器同时控制扫描方向和 RGB/BGR 顺序。如果你发现颜色反了,把0x36后面写入的数据里的 RGB 位取反即可,通常是从0x00改成0x08,或反过来。改一次就知道你的屏要的是哪个值。
4.3 花屏和横纹:这不是程序问题,是电源纹波问题
现象:屏幕能显示但画面有细密横纹,或者大面积色块区域里随机出现闪烁的杂色点。用手摸一下电源线位置,画面会明显变化。
原因:这是最典型的电源噪声问题。1.44 屏内部没有大电容,ST7735S 的电源引脚对纹波非常敏感。如果你用 5V 转 3.3V 的 AMS1117 供电,且输出端只有一个 0.1uF 小电容,负载一波动,电压就会抖。
解决:在屏幕 VCC 和 GND 之间就近并一个 10uF 电解电容,再加一个 0.1uF 陶瓷电容去耦。另外检查背光 LED 是否和驱动芯片共用 3.3V,如果是,建议把背光单独供电或串电阻降低电流。很多时候加一颗电容就解决了。
4.4 下载失败:SWD 引脚被复用或者 BOOT0 没接对
现象:点击下载后 Keil 报错,提示无法连接目标设备,要么是Cannot access target,要么是RDDI-DAP Error。
原因:F103 的 PA13、PA14 是 SWDIO 和 SWCLK,如果你在程序里把这些引脚初始化成了普通 GPIO 输出,下载器就连不上芯片了。另一种情况是 BOOT0 跳线帽被设置在高电平,芯片上电进入系统存储器模式,SWD 接口不响应连接。我见过很多次,程序里跑飞了把 GPIO 全部配置成了推挽输出,把 SWD 占用了,最后只能按住复位键的瞬间抢着点下载。
解决:按住板子复位键,在 Keil 提示连接失败前的瞬间松开,利用复位后那一段短暂时间完成握手。如果还不行,把 BOOT0 拉高再上电,然后用串口 ISP 方式擦除整片 Flash,之后再拨回 BOOT0 低电平。这个方法虽然笨,但非常可靠。从那以后,我写任何 F103 工程都会先把 SWD 引脚相关代码备注清楚,并保留一个 5 秒延时,给下载器留出连接窗口。
5. 二次开发改造:从点屏到真正能用的小型人机界面
5.1 改造思路一:把静态画面改成温湿度仪表盘
屏幕点亮只是开始,真正让项目变成产品的是界面逻辑。最常见的改造方向是给它接一个 DHT11 或 AHT20 传感器,把温度和湿度显示在屏幕上。这里的关键不是怎么写传感器驱动,而是怎么设计刷新策略。
我的做法是先划出界面的静态区域和动态区域。静态区域包括背景色、标题文字、边框,这些只需要在初始化时画一次。动态区域是温度和湿度数字所在的那一小块矩形,每两秒更新一次。更新时不需要整屏重绘,只需要把数字所在区域用背景色填掉,再写新数字即可。这样每帧只重画几十个像素,而不是整个 32768 像素,CPU 占用率几乎是零。
void UI_Update_Temperature(int16_t temp) { char str[16]; uint16_t x = 20, y = 40; // 温度显示区域左上角 // 先清掉旧内容 LCD_Fill(x, y, x + 60, y + 16, COLOR_BLACK); // 格式化字符串后写入 sprintf(str, "%d.%d C", temp / 10, temp % 10); LCD_Show_String(x, y, str, &Font16x24, COLOR_WHITE, COLOR_BLACK); }这个片段展示了一个原则:先清后写。如果不先清除旧内容,数字从“25.3”变成“25.1”时,残留的笔画会把界面搞得很脏。LCD_Fill 只填充几十个像素,耗时基本可以忽略。如果你要显示的内容频繁变化,也可以用“脏矩形”思路,把多个变化区域合并成一个更大的矩形,减少地址窗口设置次数。
5.2 改造思路二:按键交互和页面切换
给屏幕加两个按键,就能做成简单的菜单系统。我在这类小屏上用的方案是维护一个current_page变量,按键中断里只修改变量,主循环里检测变量变化后重新绘制界面。页面的切换只重绘新页面的静态元素,中间用全屏填充做一次过渡,这样视觉上不会觉得卡顿。
有一个细节要提醒:按键消抖不能全放中断里做。F103 的外部中断如果响应太快,抖动会被当成多次按键,这时候用定时器扫描方式做 10ms 消抖,比中断方式稳定得多。小屏界面的设计还有一个原则——不要放太多元素上去,128x128 分辨率下,一个页面最多放 3 到 4 个信息块,超过这个数量,字就小得没法看。
5.3 改造思路三:显示图片和自定义字库
如果你想在屏幕上显示一张图片或者公司的 logo,需要先把图片转换成 RGB565 格式的数组。转换工具很多,原理都是一样的:把图片缩放到 128x128,输出一个 C 语言数组,每一像素占 2 字节,高字节在前。在驱动里就是先设置全屏窗口,然后把整个数组用 DMA 一次性发出去。转换时要注意,如果图片原本是 24 位色深,转换到 16 位色深会丢失一些色彩细节,出现颜色过渡带,这是正常的,不需要惊讶。
字库方面,中文显示需要取模,常用 16x16 点阵显示一个汉字。取模工具里要选“横向取模、高位在前”,这和 ST7735S 的显存写入顺序严格对应。输出数组后,把显示函数封装成LCD_Show_Chinese(x, y, font_index, color, bgcolor)的形式,后续做任何菜单界面都会方便很多。不要小看这一层封装,它决定你要不要为每个页面重新写一遍文字绘制逻辑。
5.4 一条我踩过很多次的改动经验
我拆过很多份这种点屏工程,每次改动最怕的不是驱动本身,而是驱动文件里夹杂的大量硬件相关的宏定义。改板子引脚时,如果只改了 GPIO 初始化却忘了改宏映射,就会出现“线明明接对了,屏幕却不亮”的灵异现象。所以我现在拿到一个新屏工程,第一件事就是把所有引脚映射全部收拢到 lcd.h 头文件顶部的宏定义区,用类似#define LCD_SCK_PIN GPIO_Pin_5的方式统一管理。从那以后我每次换板子、换屏都会强制自己走一遍这个流程,把硬件相关的东西从业务代码里剥离开,再也不会出现改一处漏一处的惨案。希望能帮到你,也祝你这次点屏一次点亮。
本文还有配套的精品资源,点击获取