给嵌入式新手的ST7789驱动避坑指南:从SPI模式到RGB565显示的完整配置流程

张开发
2026/4/24 21:08:16 15 分钟阅读

分享文章

给嵌入式新手的ST7789驱动避坑指南:从SPI模式到RGB565显示的完整配置流程
给嵌入式新手的ST7789驱动避坑指南从SPI模式到RGB565显示的完整配置流程第一次接触ST7789液晶驱动芯片时面对厚厚的数据手册和复杂的时序图很多嵌入式新手都会感到无从下手。本文将带你一步步拆解ST7789的驱动过程从SPI模式配置到RGB565显示实现避开那些让初学者头疼的坑。1. 理解ST7789的基本工作原理ST7789是一款常见的TFT液晶驱动芯片支持262K色显示最大分辨率可达240x320。它通过SPI接口与主控芯片通信采用RGB565色彩格式16位/像素进行数据传输。关键特性支持3线/4线SPI接口内置显存GRAM可编程显示方向低功耗模式提示在开始编码前建议先通读数据手册的Features章节对芯片能力有个整体认识。2. SPI接口配置模式与时序ST7789通常使用4线SPI接口SCK, MOSI, DC, CS其中DC线用于区分命令和数据。这是第一个容易出错的地方——SPI模式必须与芯片要求严格匹配。根据数据手册ST7789的SPI时序要求CPOL 0空闲时SCK为低电平CPHA 0数据在第一个边沿采样在STM32 HAL库中的配置示例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 hspi1.Init.NSS SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_4; hspi1.Init.FirstBit SPI_FIRSTBIT_MSB; hspi1.Init.TIMode SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial 10;常见问题排查屏幕无反应检查SPI时钟极性/相位设置显示乱码确认数据位序MSB/LSB通信失败验证GPIO引脚配置是否正确3. 关键寄存器配置详解ST7789通过一系列命令寄存器控制显示行为以下是几个最关键的配置项3.1 显示方向控制0x36这个寄存器控制屏幕的旋转和镜像#define MADCTL_MY 0x80 // 行地址顺序 #define MADCTL_MX 0x40 // 列地址顺序 #define MADCTL_MV 0x20 // 行列交换 #define MADCTL_ML 0x10 // 垂直刷新顺序 #define MADCTL_RGB 0x00 // RGB顺序 #define MADCTL_BGR 0x08 // BGR顺序 // 正常方向RGB格式 uint8_t madctl MADCTL_RGB; LCD_WriteCmd(0x36); LCD_WriteData(madctl, 1);3.2 像素格式设置0x3AST7789支持多种像素格式对于RGB565显示// 设置16位/像素RGB565格式 uint8_t pixel_format 0x55; // 0x55对应RGB565 LCD_WriteCmd(0x3A); LCD_WriteData(pixel_format, 1);3.3 显示开关控制芯片上电后需要依次发送退出睡眠模式0x11打开显示0x29// 退出睡眠模式 LCD_WriteCmd(0x11); HAL_Delay(120); // 需要等待120ms // 打开显示 LCD_WriteCmd(0x29);4. 显存操作与图像显示ST7789内置了一块GRAM图形内存我们需要通过特定命令来操作它。4.1 设置显示窗口在写入像素数据前必须先定义写入区域void LCD_SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { LCD_WriteCmd(0x2A); // 列地址设置 LCD_WriteData((uint8_t*)x0, 2); LCD_WriteData((uint8_t*)x1, 2); LCD_WriteCmd(0x2B); // 行地址设置 LCD_WriteData((uint8_t*)y0, 2); LCD_WriteData((uint8_t*)y1, 2); LCD_WriteCmd(0x2C); // 内存写入 }4.2 填充颜色清屏函数示例void LCD_Fill(uint16_t color) { LCD_SetWindow(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); uint32_t total_pixels LCD_WIDTH * LCD_HEIGHT; for(uint32_t i0; itotal_pixels; i) { LCD_WriteData((uint8_t*)color, 2); } }4.3 显示图像显示一张240x320的RGB565图像void LCD_ShowImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *img) { LCD_SetWindow(x, y, xwidth-1, yheight-1); LCD_WriteData(img, width*height*2); // 每个像素2字节 }5. 常见问题与调试技巧5.1 显示颜色不正确可能原因像素格式设置错误检查0x3A命令颜色顺序错误RGB/BGR配置数据传输位序错误MSB/LSB5.2 显示偏移或错位解决方法检查显示窗口设置是否正确确认行列地址参数顺序调整偏移量某些屏幕需要5.3 SPI通信失败调试步骤用逻辑分析仪抓取SPI波形检查时钟频率是否过高验证CS和DC信号时序6. 性能优化建议使用DMA传输大幅提高图像刷新速度HAL_SPI_Transmit_DMA(hspi1, buffer, length);双缓冲机制减少屏幕闪烁局部刷新只更新变化区域合理设置SPI时钟平衡速度与稳定性在STM32F4上使用硬件SPIDMA刷新全屏240x320可以做到约30fps的性能。如果发现显示有撕裂现象可以考虑在垂直消隐期间更新显存。7. 进阶功能探索掌握了基础显示后可以尝试ST7789的更多功能局部刷新通过设置小窗口提高刷新效率睡眠模式降低功耗gamma校正改善显示效果撕裂效应控制用于视频同步例如实现垂直滚动void LCD_SetScroll(uint16_t top, uint16_t scroll_lines, uint16_t bottom) { LCD_WriteCmd(0x33); LCD_WriteData((uint8_t*)top, 2); LCD_WriteData((uint8_t*)scroll_lines, 2); LCD_WriteData((uint8_t*)bottom, 2); }调试ST7789时逻辑分析仪是最得力的工具。通过观察实际的SPI波形可以快速定位是配置问题还是时序问题。另外建议将常用操作封装成函数库方便后续项目复用。

更多文章