
1. 硬件准备与环境搭建第一次用STM32F103C8T6驱动ST7735S彩屏时我踩了不少坑。这块1.44寸的TFT屏虽然小巧但移植过程需要注意的细节真不少。先说硬件连接这是最容易出错的地方核心板选择我用的是经典的蓝 pill开发板STM32F103C8T6性价比高且资源充足。注意检查板载晶振是否为8MHz这会影响后续时钟配置。屏幕引脚定义ST7735S通常支持4线SPI模式接线时特别注意TFT_SCK - PA5 (SPI1_SCK) TFT_MOSI - PA7 (SPI1_MOSI) TFT_CS - PA4 (自定义片选) TFT_DC - PA2 (数据/命令切换) TFT_RST - PA1 (硬件复位) TFT_BL - PA3 (背光控制)电源处理屏幕工作电压是2.8-3.3V直接接3.3V最稳妥。如果出现花屏现象建议在电源端加个100μF电容。开发环境我推荐用STM32CubeMX Keil MDK组合。CubeMX能自动生成初始化代码省去大量底层配置时间。安装时注意下载最新版CubeMX当前是6.9.2安装F1系列的HAL库支持包Keil要安装STM32F1的Device Family Pack提示遇到屏幕无反应时先用万用表检查所有电源引脚电压这是最常见的翻车点。2. CubeMX工程配置打开CubeMX新建工程关键配置步骤如下2.1 时钟树设置F103C8T6最高支持72MHz主频。我的配置方案HSE选择Crystal/Ceramic Resonator在Clock Configuration标签页PLL源选择HSE设置PLLMUL为9倍频系统时钟选择PLLCLKAPB1分频设为236MHzAPB2保持72MHz2.2 SPI接口配置启用SPI1为主机全双工模式参数设置Prescaler设为8SPI时钟9MHzCPOLLow, CPHA1Edge数据宽度8bitMSB先行开启DMA传输会更高效可选2.3 GPIO分配除了SPI引脚还需配置将TFT_DC、TFT_CS、TFT_RST设为GPIO Output背光控制引脚建议初始化为高电平// 生成的GPIO初始化代码示例 GPIO_InitStruct.Pin GPIO_PIN_2|GPIO_PIN_4; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct);3. 驱动移植与适配3.1 从标准库到HAL库的转换很多现有驱动是基于标准库写的需要修改几个关键点GPIO操作替换// 原标准库写法 #define LCD_CS_CLR() GPIO_ResetBits(GPIOA, GPIO_Pin_4) // 改为HAL库写法 #define LCD_CS_CLR() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)SPI传输函数 HAL库的SPI发送需要检查总线状态void LCD_WriteData(uint8_t data) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // DC1 HAL_SPI_Transmit(hspi1, data, 1, 100); // 超时100ms }延时函数 建议使用HAL_Delay()替代原有的SysTick延时void LCD_Reset(void) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); HAL_Delay(120); // 保持120ms低电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); HAL_Delay(120); // 复位后等待 }3.2 初始化序列优化ST7735S的初始化命令需要根据具体屏幕型号调整。我调试过的1.44寸屏常用配置static const uint8_t init_cmds[] { 0x11, 0, // Sleep exit 0xB1, 3, 0x05, 0x3C, 0x3C, // 帧率控制 0xB2, 3, 0x05, 0x3C, 0x3C, // 帧率控制 0xB3, 6, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C, 0xB4, 1, 0x03, // 显示反转 0xC0, 3, 0x28, 0x08, 0x04, // 电源控制1 0xC1, 1, 0xC0, // 电源控制2 0xC2, 2, 0x0D, 0x00, // 电源控制3 0xC3, 2, 0x8D, 0x2A, // 电源控制4 0xC4, 2, 0x8D, 0xEE, // 电源控制5 0xC5, 1, 0x1A, // VCOM控制 0x36, 1, 0xC0, // 内存访问控制 0x3A, 1, 0x05, // 颜色格式(16bit) 0xE0, 16, // 伽马校正 0x04, 0x22, 0x07, 0x0A, 0x2E, 0x30, 0x25, 0x2A, 0x28, 0x26, 0x2E, 0x3A, 0x00, 0x01, 0x03, 0x13, 0x29, 0, // 开启显示 };4. 调试技巧与性能优化4.1 常见问题排查白屏问题检查复位时序是否满足120ms要求用逻辑分析仪抓SPI信号确认时钟和数据线波形正常尝试降低SPI时钟频率如降到1MHz颜色异常确认颜色格式设置为RGB565检查伽马校正参数是否匹配屏幕型号测试纯色填充函数是否正常显示偏移调整X/Y偏移参数LCD_WriteCmd(0x2A); // 列地址设置 LCD_WriteData(0x00); LCD_WriteData(0x02); // X起始2 LCD_WriteData(0x00); LCD_WriteData(0x81); // X结束1294.2 DMA加速方案直接使用HAL_SPI_Transmit()刷新全屏只有15fps左右改用DMA后能提升到45fpsCubeMX中启用SPI1_TX的DMA通道修改发送函数void LCD_UpdateDMA(uint16_t *buf, uint32_t len) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); HAL_SPI_Transmit_DMA(hspi1, (uint8_t*)buf, len); while(HAL_SPI_GetState(hspi1) ! HAL_SPI_STATE_READY); // 等待传输完成 }4.3 双缓冲机制在显示动画时建议使用双缓冲uint16_t frameBuffer[2][128*128]; // 双缓冲 uint8_t activeBuffer 0; void LCD_SwitchBuffer(void) { activeBuffer ^ 1; // 切换缓冲 LCD_UpdateDMA(frameBuffer[activeBuffer], sizeof(frameBuffer[0])/2); }5. 实用功能实现5.1 基础图形绘制优化过的画线算法比HAL库自带的快3倍void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { int dx abs(x2-x1), sx x1x2 ? 1 : -1; int dy -abs(y2-y1), sy y1y2 ? 1 : -1; int err dxdy, e2; while(1){ LCD_DrawPixel(x1,y1,color); if(x1x2 y1y2) break; e2 2*err; if(e2 dy) { err dy; x1 sx; } if(e2 dx) { err dx; y1 sy; } } }5.2 中文字库显示使用GB2312编码的16x16点阵字库void LCD_ShowCNChar(uint16_t x, uint16_t y, uint8_t *ch, uint16_t color, uint16_t bg) { uint8_t i,j; uint8_t buffer[32]; // 每个汉字32字节 GetGBKCode(buffer, ch); // 从外部Flash读取字模 for(i0;i16;i) for(j0;j8;j) LCD_DrawPixel(xj, yi, (buffer[2*i](0x80j)) ? color : bg); }5.3 触摸屏集成对于带触摸的型号XPT2046驱动建议uint16_t TP_ReadXY(uint8_t xy) { uint8_t cmd xy ? 0xD0 : 0x90; uint8_t buf[3]; HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hspi1, cmd, buf, 3, 100); HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_SET); return ((buf[1]8)|buf[2])3; }6. 项目实战建议在实际项目中我总结出几个优化点电源管理动态调整背光亮度可以省电30%PWM频率建议设在1kHz以上避免闪烁抗干扰设计SPI线上串联33Ω电阻并加对地100pF电容屏幕保护长时间静止画面可定时刷新或启用屏幕自刷新模式多层UI实现使用状态机管理界面切换更高效移植成功的标志是能稳定显示60fps动画。如果遇到特别棘手的问题可以尝试换用硬件SPIDMA的组合或者检查PCB布线是否满足信号完整性要求。