news 2026/5/7 16:00:32

手把手教你用STM32F103ZET6的SPI点亮2.4寸TFT屏(附ILI9341初始化代码避坑指南)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你用STM32F103ZET6的SPI点亮2.4寸TFT屏(附ILI9341初始化代码避坑指南)

STM32F103ZET6 SPI驱动ILI9341 TFT屏实战全解析

第一次拿到2.4寸TFT屏时,看着五颜六色的排线,我完全不知道从何下手。屏幕背面印着"ILI9341"的型号标识,网上搜到的资料又零散不全。经过三天调试,当屏幕终于显示出清晰的图像时,那种成就感至今难忘。本文将分享从硬件连接到软件调试的全过程经验,特别是那些容易踩坑的细节。

1. 硬件连接与SPI配置

1.1 引脚定义与物理连接

ILI9341驱动的2.4寸TFT屏通常采用20pin排线接口,关键信号线包括:

屏引脚STM32F103ZET6连接备注
VCC3.3V电源正极
GNDGND电源地
CSPB11片选信号
RESETPB12复位信号
DC/RSPB10数据/命令选择
SDAPB15(MOSI)SPI数据线
SCLPB13(SCK)SPI时钟线
LEDPB9背光控制

常见接线错误

  • 将MOSI和MISO接反(TFT屏通常不需要MISO)
  • 忘记连接复位线导致屏幕无法初始化
  • 背光LED直接接3.3V导致无法关闭背光

1.2 SPI外设初始化

STM32F103的SPI2外设位于PB13~PB15引脚,初始化配置如下:

void SPI2_Init(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // 配置SPI引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // SPI参数配置 SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // 单线发送模式 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 主机模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8位数据 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 时钟极性 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 时钟相位 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 软件控制NSS SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 18MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;// 高位在前 SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); }

注意:SPI时钟不宜过高,初期调试建议设置为系统时钟的1/4(18MHz),稳定后可逐步提高。

2. ILI9341初始化序列详解

2.1 关键寄存器配置

ILI9341有数十个配置寄存器,以下几个最为关键:

  1. 0x36 - 内存访问控制

    • 控制显示方向、颜色顺序等
    • 典型值:0x48(竖屏,BGR顺序)
  2. 0x3A - 像素格式

    • 设置16位(0x55)或18位(0x66)颜色模式
    • TFT屏通常使用16位RGB565格式
  3. 0xB1 - 帧率控制

    • 设置刷新率,影响显示流畅度
    • 典型值:0x00, 0x1B(约70Hz)
  4. 0xC0/C1 - 电源控制

    • 配置内部电压调节器
    • 需要严格按照数据手册顺序设置

2.2 初始化代码优化

原始初始化序列往往包含大量冗余设置,经测试可简化为:

void LCD_Init(void) { LCD_Reset(); // 硬件复位 // 精简后的初始化序列 LCD_WR_REG(0xCF); LCD_WR_DATA(0x00); LCD_WR_DATA(0xC1); LCD_WR_DATA(0X30); LCD_WR_REG(0xED); LCD_WR_DATA(0x64); LCD_WR_DATA(0x03); LCD_WR_DATA(0X12); LCD_WR_DATA(0X81); LCD_WR_REG(0xE8); LCD_WR_DATA(0x85); LCD_WR_DATA(0x00); LCD_WR_DATA(0x78); LCD_WR_REG(0xCB); LCD_WR_DATA(0x39); LCD_WR_DATA(0x2C); LCD_WR_DATA(0x00); LCD_WR_DATA(0x34); LCD_WR_DATA(0x02); LCD_WR_REG(0xF7); LCD_WR_DATA(0x20); LCD_WR_REG(0xEA); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); // 电源控制 LCD_WR_REG(0xC0); LCD_WR_DATA(0x1B); // VRH LCD_WR_REG(0xC1); LCD_WR_DATA(0x12); // SAP LCD_WR_REG(0xC5); LCD_WR_DATA(0x32); // VCM控制 LCD_WR_REG(0xC7); LCD_WR_DATA(0XC0); // 对比度 // 内存访问控制 LCD_WR_REG(0x36); LCD_WR_DATA(0x48); // 竖屏模式 LCD_WR_REG(0x3A); LCD_WR_DATA(0x55); // 16位像素 // 显示控制 LCD_WR_REG(0xB1); LCD_WR_DATA(0x00); LCD_WR_DATA(0x1B); // 帧率 LCD_WR_REG(0xB6); LCD_WR_DATA(0x0A); LCD_WR_DATA(0xA2); // 显示功能 // Gamma校正 static const u8 Gamma_Sequence[] = { /* 省略具体数值 */ }; LCD_WR_REG(0xE0); for(u8 i=0; i<15; i++) LCD_WR_DATA(Gamma_Sequence[i]); LCD_WR_REG(0xE1); for(u8 i=0; i<15; i++) LCD_WR_DATA(Gamma_Sequence[i+15]); LCD_WR_REG(0x11); // 退出睡眠 delay_ms(120); LCD_WR_REG(0x29); // 开启显示 }

调试技巧:如果屏幕出现花屏,可尝试调整0x36寄存器的值,特别是MY/MX/MV这三个方向控制位。

3. 显示优化技巧

3.1 双缓冲机制实现

直接刷屏会导致明显的闪烁,采用双缓冲可大幅改善:

// 定义显存 u16 frame_buffer[2][320*240]; u8 current_buffer = 0; // 切换显示缓冲区 void LCD_SwitchBuffer(void) { LCD_SetWindows(0, 0, 239, 319); LCD_CS_CLR; LCD_RS_SET; for(u32 i=0; i<320*240; i++) { SPI_WriteByte(SPI2, frame_buffer[current_buffer][i]>>8); SPI_WriteByte(SPI2, frame_buffer[current_buffer][i]&0xFF); } LCD_CS_SET; current_buffer ^= 1; // 切换缓冲区 }

3.2 局部刷新优化

全屏刷新耗时长,针对动态区域可局部更新:

void LCD_UpdateRegion(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_SetWindows(x1, y1, x2, y2); LCD_CS_CLR; LCD_RS_SET; u16 width = x2 - x1 + 1; u16 height = y2 - y1 + 1; for(u16 y=0; y<height; y++) { for(u16 x=0; x<width; x++) { u16 color = frame_buffer[current_buffer][(y1+y)*320 + (x1+x)]; SPI_WriteByte(SPI2, color>>8); SPI_WriteByte(SPI2, color&0xFF); } } LCD_CS_SET; }

3.3 字体显示优化

嵌入式系统常用点阵字体,存储和渲染需特别处理:

// 字体结构定义 typedef struct { u8 width; // 字体宽度 u8 height; // 字体高度 u8 first_char;// 起始ASCII码 u8 char_num; // 字符数量 const u16 *data; // 字体数据 } FontType; // 显示一个字符 void LCD_ShowChar(u16 x, u16 y, u8 chr, FontType font, u16 color, u16 bgcolor) { u8 i,j; u8 temp; u16 x0 = x; chr -= font.first_char; const u16 *p = &font.data[chr * font.height]; for(i=0; i<font.height; i++) { temp = *(p+i); for(j=0; j<font.width; j++) { if(temp & (1<<(font.width-1-j))) { LCD_DrawPoint(x+j, y+i, color); } else if(bgcolor != color) { LCD_DrawPoint(x+j, y+i, bgcolor); } } } }

4. 常见问题排查指南

4.1 白屏问题分析

当屏幕只亮背光无显示时,按以下步骤排查:

  1. 检查电源

    • 测量VCC电压是否为3.3V
    • 确认GND连接可靠
  2. 验证复位时序

    • 复位信号需保持低电平至少10ms
    • 复位后需延迟100ms再初始化
  3. SPI信号测试

    • 用逻辑分析仪抓取SPI波形
    • 确认CS、DC信号变化正常
  4. 初始化序列

    • 确保发送了0x11(退出睡眠)和0x29(开启显示)
    • 检查0x36寄存器设置是否正确

4.2 颜色异常处理

颜色显示不正常时,重点关注:

  1. 像素格式设置

    • 确认0x3A寄存器设置为0x55(16位接口)
    • 检查SPI数据是否为RGB565顺序
  2. 内存访问控制

    • 0x36寄存器的BGR位决定颜色顺序
    • 典型设置:0x48(竖屏+BGR)
  3. Gamma校正

    • 不正确的Gamma值会导致颜色失真
    • 建议使用厂商提供的标准Gamma序列

4.3 性能优化建议

  1. SPI时钟优化

    • 初期使用较低时钟(如18MHz)
    • 稳定后可逐步提高至36MHz
  2. DMA传输

    • 使用DMA可释放CPU资源
    • 配置示例:
      void SPI2_DMA_Init(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)frame_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 320*240; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); }
  3. 屏幕旋转优化

    • 修改0x36寄存器实现硬件旋转
    • 避免软件旋转带来的性能损耗

调试ILI9341最耗时的部分是反复修改初始化参数。建议将初始化代码模块化,通过宏定义快速切换不同配置。实际项目中,我会先确保基本显示正常,再逐步添加高级功能。

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

教育科技项目利用 Taotoken 实现对学生问答机器人的多模型支持

教育科技项目利用 Taotoken 实现对学生问答机器人的多模型支持 在线教育平台的智能答疑系统&#xff0c;其核心在于能够准确、及时地响应学生提出的各类问题。随着大模型技术的多样化发展&#xff0c;不同模型在数学推理、代码生成、文科论述等任务上展现出各自的特性。直接对…

作者头像 李华
网站建设 2026/5/7 15:54:46

Redis分布式锁进阶第二十三篇

Redis分布式锁进阶第二十三篇&#xff1a;锁专项全链路压测实战落地 隐蔽瓶颈提前排雷 大促零翻车预检兜底全方案一、本篇前置衔接第二十二篇我们完成了锁安全攻防全维度加固&#xff0c;挡住外部恶意抢锁、篡改锁资源的各类攻击&#xff0c;守住了锁资源安全底线。前面二十二…

作者头像 李华
网站建设 2026/5/7 15:50:49

AI大模型落地难?昆仑联通十大真实案例,揭秘政企降本增效!

本文聚焦政企客户在AI转型中的困惑&#xff0c;介绍昆仑联通如何通过十大AI落地案例&#xff0c;帮助客户解决文档翻译、流程自动化、跨部门协同、IT运维、设备维护、供应链优化、政务智能服务等场景中的痛点&#xff0c;实现降本增效。案例涵盖制造业、家电、互联网、半导体等…

作者头像 李华
网站建设 2026/5/7 15:49:58

RHCE第三次 作业

实验一 正向解析&#xff08;一&#xff09;服务端1.安装binddnf install bind -y2.修改主配置文件3.区域声明文件4.创建区域数据文件5.重启named服务systemctl enable --now named(二)客户端实验二 反向解析1.在区域声明文件中反向解析声明2.在/var/named目录中实现区域数据文…

作者头像 李华