news 2026/5/23 18:13:06

手把手教你用STM32CubeMX配置STM32F103的SPI+DMA驱动ST7735S屏幕(附工程源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你用STM32CubeMX配置STM32F103的SPI+DMA驱动ST7735S屏幕(附工程源码)

STM32CubeMX实战:SPI+DMA驱动ST7735S屏幕全流程解析

在嵌入式开发领域,图形化界面的快速实现一直是开发者关注的焦点。ST7735S作为一款常见的TFT液晶驱动芯片,广泛应用于各种嵌入式显示场景。本文将详细介绍如何利用STM32CubeMX工具和HAL库,快速构建基于SPI+DMA的高效显示驱动方案。

1. 开发环境搭建与工程创建

首先需要准备以下硬件和软件环境:

  • 硬件准备

    • STM32F103系列开发板(本文以STM32F103C8T6为例)
    • ST7735S驱动的1.44寸TFT屏幕
    • 杜邦线若干
    • USB转TTL串口模块(用于调试)
  • 软件准备

    • STM32CubeMX 6.x或更高版本
    • Keil MDK-ARM或STM32CubeIDE
    • STM32F1xx HAL库

在CubeMX中新建工程时,选择对应的STM32型号,然后按照以下步骤配置:

/* 系统时钟配置示例(72MHz) */ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

2. SPI外设与DMA配置详解

在CubeMX中配置SPI接口时,需要注意以下关键参数:

  • SPI模式:选择全双工主模式
  • 时钟极性(CPOL):Low
  • 时钟相位(CPHA):1 Edge
  • 数据大小:8位
  • NSS信号:软件控制
  • 波特率预分频:根据屏幕规格选择(建议初始设置为8分频)

DMA配置表格:

参数配置值说明
DirectionMemory to Peripheral内存到外设传输
Increment AddressMemory内存地址自动递增
Data WidthByte传输数据单位为字节
ModeNormal非循环模式
PriorityHighDMA通道优先级

对应的CubeMX配置代码如下:

/* SPI1 init function */ void MX_SPI1_Init(void) { 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_8; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } }

3. GPIO引脚配置与屏幕控制信号

ST7735S屏幕除了SPI接口外,还需要控制以下几个关键信号:

  1. RESET:硬件复位引脚
  2. DC:数据/命令选择引脚
  3. CS:片选信号(可选,如果只有一个SPI设备可固定使能)

在CubeMX中配置这些GPIO时,建议:

  • 所有控制引脚设置为输出推挽模式
  • 初始电平根据屏幕规格设置
  • 输出速度设置为高速(50MHz)

典型引脚配置表:

引脚功能GPIO引脚初始状态备注
SPI_SCKPA5-SPI时钟线
SPI_MOSIPA7-SPI数据线
RESETPB0High复位信号
DCPB1High数据/命令选择
CSPA4Low片选信号

对应的初始化代码:

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hspi->Instance==SPI1) { __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 控制引脚初始化 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // DMA控制器时钟使能 __HAL_RCC_DMA1_CLK_ENABLE(); // SPI1 TX DMA配置 hdma_spi1_tx.Instance = DMA1_Channel3; hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPHERAL; hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_spi1_tx.Init.Mode = DMA_NORMAL; hdma_spi1_tx.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_spi1_tx); __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx); } }

4. ST7735S驱动实现与优化技巧

ST7735S的驱动实现主要包括初始化序列配置和显示数据发送两部分。以下是关键操作函数:

屏幕初始化序列

void ST7735_Init(void) { // 硬件复位 HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_RESET); HAL_Delay(120); HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET); HAL_Delay(120); // 发送初始化命令序列 ST7735_WriteCommand(ST7735_SLPOUT); // 退出睡眠模式 HAL_Delay(120); ST7735_WriteCommand(ST7735_FRMCTR1); // 帧率控制 ST7735_WriteData(0x01); ST7735_WriteData(0x2C); ST7735_WriteData(0x2D); // ... 其他初始化命令 ST7735_WriteCommand(ST7735_DISPON); // 开启显示 }

DMA传输优化

对于需要频繁刷新的场景,可以使用双缓冲技术进一步提升性能:

// 定义双缓冲 uint8_t buffer1[BUFFER_SIZE]; uint8_t buffer2[BUFFER_SIZE]; uint8_t* currentBuffer = buffer1; void ST7735_Refresh_DMA(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t* buffer) { // 设置显示区域 ST7735_SetAddressWindow(x1, y1, x2, y2); // 启动DMA传输 HAL_SPI_Transmit_DMA(&hspi1, buffer, BUFFER_SIZE); // 切换缓冲区 currentBuffer = (currentBuffer == buffer1) ? buffer2 : buffer1; } // 在DMA传输完成中断中处理 void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { // 可以在这里准备下一帧数据 }

5. 性能测试与常见问题解决

在实际应用中,我们通过以下方法测试驱动性能:

  1. 帧率测试

    • 实现简单的动画效果(如移动方块)
    • 使用定时器计算每秒刷新帧数
    • 典型结果:SPI+DMA可达50-60FPS(取决于SPI时钟和屏幕分辨率)
  2. 常见问题及解决方案

问题现象可能原因解决方案
屏幕无显示电源或信号连接错误检查所有连线,确认电压正常
显示花屏初始化序列不正确核对ST7735S规格书,调整初始化参数
刷新慢SPI时钟配置过低提高SPI时钟频率,优化DMA配置
DMA传输不完整缓冲区对齐问题确保缓冲区地址和大小符合DMA要求

性能优化建议

  • 根据实际需求调整SPI时钟分频
  • 使用内存中的显示缓冲区,减少实时计算
  • 合理规划屏幕刷新区域,避免全屏刷新
  • 利用STM32的硬件特性(如CRC校验)提高数据传输可靠性

6. 工程源码结构与扩展应用

完整的工程源码应包含以下模块:

/Drivers /STM32F1xx_HAL_Driver // HAL库文件 /CMSIS // 内核支持文件 /Inc stm32f1xx_hal_conf.h // HAL库配置 st7735.h // 屏幕驱动头文件 main.h /Src main.c // 主程序 stm32f1xx_it.c // 中断处理 st7735.c // 屏幕驱动实现 system_stm32f1xx.c // 系统初始化

扩展应用示例

  1. 实现GUI框架集成
  2. 添加触摸屏支持
  3. 开发动画效果
  4. 构建菜单系统

提示:在实际项目中,建议将屏幕驱动封装为独立的硬件抽象层(HAL),便于移植和维护。同时,对于需要更高性能的场景,可以考虑使用LTDC接口的屏幕或更强大的STM32系列芯片。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 18:11:46

Unity镂空遮罩实战:用Stencil Buffer实现UI与3D混合裁剪

1. 为什么“镂空遮罩”不是简单画个透明洞——从美术需求到渲染本质的错位 “游戏中实现镂空遮罩效果”,这行标题在Unity项目组的周会上被提出来时,我听见隔壁组两位美术同事小声嘀咕:“不就是做个带Alpha通道的贴图盖上去吗?”—…

作者头像 李华
网站建设 2026/5/23 18:07:07

GPT-4稀疏激活原理:2%参数背后的MoE工程真相

1. 项目概述:参数规模与稀疏激活的真相拆解 “GPT-4 Has 1.8 Trillion Parameters. It Uses 2% of Them Per Token.”——这句话过去两年在技术社区反复刷屏,常被当作“大模型已突破算力瓶颈”的佐证,也常被误读为“GPT-4只用360亿参数&#…

作者头像 李华
网站建设 2026/5/23 18:06:25

AI Agent运维效能跃迁路径(从POC到规模化投产的5个生死关卡)

更多请点击: https://kaifayun.com 第一章:AI Agent运维效能跃迁路径(从POC到规模化投产的5个生死关卡) AI Agent从实验室原型走向生产级规模化部署,并非线性演进,而是一场穿越多重结构性瓶颈的攻坚。五个…

作者头像 李华
网站建设 2026/5/23 17:57:41

Frida安卓逆向实战:从环境搭建到Java/Native层Hook

1. 这不是“教你怎么黑App”,而是安卓安全工程师每天在做的事Frida安卓逆向实战——这七个字背后,是无数安全研究员、渗透测试工程师、应用加固方案设计者、甚至合规审计人员的真实工作切口。它不等于“破解”“盗号”“越狱”,而是一套标准化…

作者头像 李华
网站建设 2026/5/23 17:54:04

写综述如何避免重复率过高?

写综述,重复率高几乎是“职业病”。因为综述天然就在干一件事:总结别人已经发表过的研究。所以很多人第一次写综述会崩:“我明明没抄,为什么查出来35%?”太正常了。综述本来就是论文里最容易爆重复率的类型。但能控。我…

作者头像 李华