STM32G030F6P6驱动0.96寸TFT彩屏(ST7735S)保姆级教程:从CubeIDE配置到显示字符
STM32G030F6P6驱动0.96寸TFT彩屏(ST7735S)保姆级教程:从CubeIDE配置到显示字符
1. 硬件准备与连接
在开始软件配置前,确保已完成以下硬件准备工作:
所需材料清单:
- STM32G030F6P6开发板
- 0.96寸TFT彩屏(ST7735S驱动)
- 杜邦线若干
- USB转TTL模块(用于调试)
引脚连接对照表:
| TFT引脚 | STM32引脚 | 功能说明 |
|---|---|---|
| VCC | 3.3V | 电源正极 |
| GND | GND | 电源地 |
| SCL | PA5 | SPI时钟线 |
| SDA | PA7 | SPI数据线 |
| RES | PA12 | 复位信号 |
| DC | PA6 | 数据/命令选择 |
| CS | PA4 | 片选信号 |
| BLK | PA11 | 背光控制 |
注意:部分模块的BLK引脚可能需要接高电平才能点亮背光
2. CubeIDE工程创建与配置
2.1 新建工程
- 打开STM32CubeIDE,选择
File > New > STM32 Project - 在MCU选择器中输入"STM32G030F6P6"并选择对应型号
- 设置工程名称(如
TFT_ST7735)并选择保存路径
2.2 时钟配置
在Clock Configuration标签页中:
- 设置HSI作为时钟源
- 配置PLL使系统时钟达到64MHz
- 确保APB1分频系数为1(无分频)
// 时钟树关键参数 System Clock = 64MHz APB1 Timer Clocks = 64MHz2.3 SPI外设配置
- 在
Pinout & Configuration视图中找到SPI1 - 配置为
Full-Duplex Master模式 - 参数设置:
- Prescaler: /4 (16MHz)
- Data Size: 8 bits
- First Bit: MSB First
- Clock Polarity: Low
- Clock Phase: 1 Edge
// SPI初始化代码片段(自动生成) 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; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;2.4 GPIO配置
配置以下GPIO为输出模式:
- PA4 (CS): Output Push Pull
- PA5 (SCK): Alternate Function Push Pull
- PA6 (DC): Output Push Pull
- PA7 (MOSI): Alternate Function Push Pull
- PA11 (BLK): Output Push Pull
- PA12 (RES): Output Push Pull
3. 驱动库移植与优化
3.1 驱动文件结构
在工程中创建以下文件:
/Drivers /ST7735 ├── st7735.h # 驱动头文件 ├── st7735.c # 驱动实现 └── fonts.h # 字库文件关键宏定义:
#define ST7735_WIDTH 80 #define ST7735_HEIGHT 160 // 颜色定义(RGB565格式) #define ST7735_BLACK 0x0000 #define ST7735_BLUE 0x001F #define ST7735_RED 0xF800 #define ST7735_GREEN 0x07E0 #define ST7735_WHITE 0xFFFF3.2 DMA传输优化
为提高刷新效率,配置SPI使用DMA传输:
- 在CubeMX中启用SPI1_TX的DMA通道
- 设置DMA为
Normal模式,优先级Medium - 在驱动代码中添加DMA发送函数:
void ST7735_WriteDataDMA(uint8_t* data, uint16_t length) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS低 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); // DC高 HAL_SPI_Transmit_DMA(&hspi1, data, length); }4. 显示功能实现
4.1 基础绘图函数
实现核心绘图功能:
// 设置显示窗口 void ST7735_SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { ST7735_WriteCommand(ST7735_CASET); ST7735_WriteData(x0 >> 8); ST7735_WriteData(x0 & 0xFF); ST7735_WriteData(x1 >> 8); ST7735_WriteData(x1 & 0xFF); ST7735_WriteCommand(ST7735_RASET); ST7735_WriteData(y0 >> 8); ST7735_WriteData(y0 & 0xFF); ST7735_WriteData(y1 >> 8); ST7735_WriteData(y1 & 0xFF); ST7735_WriteCommand(ST7735_RAMWR); } // 绘制单个像素点 void ST7735_DrawPixel(uint16_t x, uint16_t y, uint16_t color) { if(x >= ST7735_WIDTH || y >= ST7735_HEIGHT) return; ST7735_SetWindow(x, y, x, y); ST7735_WriteData(color >> 8); ST7735_WriteData(color & 0xFF); }4.2 字符显示实现
基于字库的字符显示函数:
void ST7735_DrawChar(uint16_t x, uint16_t y, char ch, FontDef font, uint16_t color, uint16_t bgcolor) { uint32_t i, b, j; for(i = 0; i < font.height; i++) { b = font.data[(ch - 32) * font.height + i]; for(j = 0; j < font.width; j++) { if((b << j) & 0x8000) { ST7735_DrawPixel(x + j, y + i, color); } else { ST7735_DrawPixel(x + j, y + i, bgcolor); } } } }5. 常见问题解决
5.1 FLASH空间不足
STM32G030F6P6仅有32KB FLASH,优化建议:
- 使用
-Os优化选项 - 移除不必要的库函数
- 压缩字库数据(如只保留ASCII字符)
链接脚本修改示例:
MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K }5.2 显示异常排查
若出现花屏或显示错位:
- 检查SPI时钟相位和极性设置
- 确认复位时序(RES低电平至少10ms)
- 验证颜色格式是否为RGB565
- 检查屏幕初始化命令序列
5.3 性能优化技巧
- 使用
__attribute__((section(".ccmram")))将帧缓冲区放在CCM RAM - 批量传输时使用DMA而非轮询
- 实现局部刷新而非全屏刷新
6. 进阶功能扩展
6.1 图形加速技巧
实现快速水平/垂直线绘制:
void ST7735_DrawHLine(uint16_t x, uint16_t y, uint16_t w, uint16_t color) { ST7735_SetWindow(x, y, x + w - 1, y); ST7735_StartData(); for(uint16_t i = 0; i < w; i++) { ST7735_WriteData(color >> 8); ST7735_WriteData(color & 0xFF); } }6.2 触摸功能集成
对于带触摸的模块,可添加XPT2046驱动:
uint16_t XPT2046_ReadADC(uint8_t channel) { uint8_t data[3] = {0}; data[0] = 0x80 | ((channel & 0x07) << 4); HAL_GPIO_WritePin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(&hspi1, data, data, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin, GPIO_PIN_SET); return ((data[1] << 8) | data[2]) >> 3; }7. 工程调试与验证
7.1 基础测试代码
在main.c中添加测试代码:
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_SPI1_Init(); ST7735_Init(); ST7735_FillScreen(ST7735_BLACK); // 显示测试图案 ST7735_DrawRectangle(10, 10, 70, 50, ST7735_RED); ST7735_FillCircle(40, 80, 20, ST7735_BLUE); ST7735_DrawString(5, 120, "STM32G0 Demo", Font_7x10, ST7735_GREEN, ST7735_BLACK); while(1) { // 添加动态效果 static uint16_t cnt = 0; ST7735_DrawNumber(50, 140, cnt++, Font_7x10, ST7735_WHITE, ST7735_BLACK); HAL_Delay(500); } }7.2 性能测试指标
- 全屏填充速度:约45ms (RGB565)
- 字符显示速度:约0.2ms/字符(16x16)
- 功耗数据:
- 背光关闭:1.2mA
- 背光全亮:15mA
8. 资源管理与优化
8.1 内存占用分析
使用arm-none-eabi-size工具查看编译结果:
text data bss dec hex filename 14256 356 2148 16760 4178 TFT_ST7735.elf8.2 电源管理
实现低功耗显示模式:
void ST7735_EnterSleepMode(void) { ST7735_WriteCommand(ST7735_SLPIN); HAL_Delay(120); // 等待屏幕进入睡眠 HAL_GPIO_WritePin(BLK_GPIO_Port, BLK_Pin, GPIO_PIN_RESET); } void ST7735_ExitSleepMode(void) { HAL_GPIO_WritePin(BLK_GPIO_Port, BLK_Pin, GPIO_PIN_SET); ST7735_WriteCommand(ST7735_SLPOUT); HAL_Delay(120); // 等待屏幕唤醒 }