STM32CubeMX + HAL库搞定ST7735彩屏:从SPI配置到显示图片的保姆级教程

张开发
2026/4/17 13:17:11 15 分钟阅读

分享文章

STM32CubeMX + HAL库搞定ST7735彩屏:从SPI配置到显示图片的保姆级教程
ST32CubeMX与HAL库驱动ST7735彩屏全流程实战指南1. 开发环境搭建与工程创建在开始驱动ST7735彩屏之前我们需要先准备好开发环境。STM32CubeMX是ST官方推出的图形化配置工具能够极大简化STM32微控制器的初始化过程。以下是环境搭建的具体步骤安装STM32CubeMX从ST官网下载最新版本支持Windows、Linux和macOS平台安装HAL库通过STM32CubeMX的包管理器安装对应系列芯片的HAL库安装开发IDE推荐使用Keil MDK或IAR Embedded Workbench创建新工程时选择与你的开发板匹配的STM32型号。对于大多数STM32F1/F4系列芯片都能很好地支持ST7735驱动。关键配置点包括系统时钟配置通常设置为最大频率以获得最佳性能调试接口如SWD使能GPIO和SPI外设的基本配置提示初次使用CubeMX时建议先创建一个简单的GPIO控制工程熟悉工具链后再进行SPI设备驱动开发。2. SPI外设的详细配置ST7735屏幕通过SPI接口与MCU通信CubeMX中的SPI配置需要特别注意以下参数参数项推荐值说明ModeTransmit Only Master屏幕只需接收数据无需返回数据Data Size8-bitST7735命令和数据均为8位格式First BitMSB First通信协议要求高位在前Baud Rate5-20MHz根据屏幕规格和MCU性能调整Clock PolarityLowCPOL0时钟空闲时为低电平Clock Phase1 EdgeCPHA0数据在第一个时钟边沿采样在Connectivity选项卡中选择合适的SPI接口如SPI1按照上表配置参数。Prescaler分频系数需要根据系统时钟计算得出确保最终波特率在推荐范围内。除了SPI主接口还需要配置三个控制引脚RST复位信号低电平有效DC数据/命令选择高电平为数据低电平为命令CS片选信号低电平有效在Pinout视图中将这些引脚配置为GPIO_Output模式并建议使用有意义的标签命名如ST7735_RST、ST7735_DC等方便后续代码编写。3. ST7735驱动代码实现生成工程后我们需要添加ST7735的驱动程序。创建一个新的头文件st7735.h和源文件st7735.c实现以下核心功能// st7735.h 主要定义 #define ST7735_SPI_INSTANCE hspi1 // 与CubeMX配置一致 #define ST7735_WIDTH 128 // 屏幕宽度 #define ST7735_HEIGHT 160 // 屏幕高度 #define ST7735_ROTATION 0 // 显示方向 // 常用颜色定义 #define ST7735_BLACK 0x0000 #define ST7735_BLUE 0x001F #define ST7735_RED 0xF800 #define ST7735_GREEN 0x07E0 #define ST7735_WHITE 0xFFFF // 函数声明 void ST7735_Init(void); void ST7735_DrawPixel(uint16_t x, uint16_t y, uint16_t color); void ST7735_FillScreen(uint16_t color); void ST7735_DrawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *img);驱动实现的关键函数包括底层通信函数void ST7735_WriteCommand(uint8_t cmd) { HAL_GPIO_WritePin(ST7735_DC_GPIO_Port, ST7735_DC_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(ST7735_CS_GPIO_Port, ST7735_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(ST7735_SPI_INSTANCE, cmd, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(ST7735_CS_GPIO_Port, ST7735_CS_Pin, GPIO_PIN_SET); }初始化序列void ST7735_Init(void) { // 硬件复位 HAL_GPIO_WritePin(ST7735_RST_GPIO_Port, ST7735_RST_Pin, GPIO_PIN_RESET); HAL_Delay(100); HAL_GPIO_WritePin(ST7735_RST_GPIO_Port, ST7735_RST_Pin, GPIO_PIN_SET); HAL_Delay(100); // 发送初始化命令序列 ST7735_WriteCommand(0x11); // Sleep out HAL_Delay(120); ST7735_WriteCommand(0x3A); // Color mode ST7735_WriteData(0x05); // 16-bit/pixel // 更多初始化命令... }图形绘制函数void ST7735_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { uint8_t buff[2]; buff[0] color 8; buff[1] color 0xFF; ST7735_SetAddressWindow(x, y, xw-1, yh-1); ST7735_WriteCommand(0x2C); // Memory write for(uint16_t i0; ih; i) { for(uint16_t j0; jw; j) { HAL_SPI_Transmit(ST7735_SPI_INSTANCE, buff, 2, HAL_MAX_DELAY); } } }4. 高级功能实现与优化基础驱动完成后我们可以实现更丰富的显示功能4.1 文字显示要实现文字显示需要先定义字模数据。创建一个fonts.h和fonts.c文件包含常用字体的点阵数据。例如定义一个8x16的ASCII字体// fonts.h typedef struct { uint8_t width; uint8_t height; const uint16_t *data; } FontDef; extern const FontDef Font_8x16; // fonts.c const uint16_t Font8x16[] { // 各字符的点阵数据 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 空格 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0000, 0x0800, 0x0000, // ! // 更多字符... }; const FontDef Font_8x16 {8, 16, Font8x16};然后实现字符显示函数void ST7735_DrawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, const FontDef *font) { uint32_t charOffset (c - ) * font-height; for(uint8_t row0; rowfont-height; row) { uint16_t rowData font-data[charOffset row]; for(uint8_t col0; colfont-width; col) { if(rowData (1 (15-col))) { ST7735_DrawPixel(xcol, yrow, color); } else { ST7735_DrawPixel(xcol, yrow, bg); } } } }4.2 图像显示优化直接逐像素绘制图像效率较低可以采用以下优化方法使用DMA传输减少CPU占用void ST7735_DrawImage_DMA(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *img) { ST7735_SetAddressWindow(x, y, xw-1, yh-1); ST7735_WriteCommand(0x2C); HAL_GPIO_WritePin(ST7735_DC_GPIO_Port, ST7735_DC_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ST7735_CS_GPIO_Port, ST7735_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit_DMA(ST7735_SPI_INSTANCE, (uint8_t*)img, w*h*2); }双缓冲技术在内存中完成绘制后再一次性刷新到屏幕局部刷新只更新屏幕变化的部分4.3 性能调优技巧SPI时钟优化在屏幕规格允许范围内尽可能提高SPI时钟频率减少通信开销合并多个像素数据为一次传输使用硬件加速部分STM32型号支持SPI的硬件CRC和DMA电源管理在不需要显示时让屏幕进入睡眠模式5. 常见问题解决方案在实际开发中可能会遇到以下典型问题5.1 屏幕无显示或显示异常排查步骤检查硬件连接是否正确特别是电源和信号线确认SPI配置参数与屏幕规格一致使用逻辑分析仪抓取SPI信号验证通信时序检查复位序列是否正确执行5.2 颜色显示不正确可能原因及解决方法颜色顺序错误修改st7735.h中的ST7735_MADCTL_MODE为ST7735_MADCTL_BGR反色显示设置ST7735_INVERSE为1颜色格式不匹配确认使用RGB565格式5.3 显示内容错位调整方案修改ST7735_XSTART和ST7735_YSTART偏移量调整ST7735_ROTATION设置显示方向检查屏幕物理分辨率与代码中定义是否一致5.4 性能瓶颈分析当出现刷新率低、显示卡顿时使用定时器测量关键函数执行时间检查SPI实际传输速率是否达到预期分析是否存在不必要的内存拷贝操作考虑使用硬件加速或优化算法6. 项目进阶与扩展掌握了ST7735基础驱动后可以进一步扩展功能GUI框架集成移植LittlevGL、emWin等图形库触摸屏支持添加电阻/电容触摸功能多语言支持实现中文字库显示动画效果利用定时器实现流畅动画低功耗优化针对电池供电设备优化功耗例如集成LittlevGL的步骤// 初始化LittlevGL lv_init(); // 注册显示驱动 static lv_disp_buf_t disp_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; lv_disp_buf_init(disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); lv_disp_drv_t disp_drv; lv_disp_drv_init(disp_drv); disp_drv.buffer disp_buf; disp_drv.flush_cb my_flush_cb; // 实现刷新回调 lv_disp_drv_register(disp_drv); // 在my_flush_cb中调用ST7735驱动 void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { ST7735_DrawImage(area-x1, area-y1, area-x2-area-x11, area-y2-area-y11, (uint8_t*)color_p); lv_disp_flush_ready(disp_drv); }通过STM32CubeMX和HAL库的组合开发者可以快速构建ST7735显示屏的驱动框架再结合具体需求进行功能扩展和性能优化。这种开发模式不仅适用于ST7735也可推广到其他SPI接口的显示设备。

更多文章