STM32F103ZET6驱动4.3寸TFTLCD触摸屏:FSMC配置与触摸校准实战

发布时间:2026/11/4 21:27:05
STM32F103ZET6驱动4.3寸TFTLCD触摸屏:FSMC配置与触摸校准实战 简介这份资源面向使用STM32F103ZET6进行嵌入式显示与触控开发的工程师及学习者提供4.3英寸TFT LCD彩色液晶触摸屏的完整驱动例程解决从裸机并口驱动到触摸交互的工程落地问题。例程中TFT LCD采用16位8080并口驱动芯片NT35510触摸部分通过I2C总线对接GT968/GT1151触摸芯片并将正点原子KEIL工程移植到STM32CUBEIDE环境便于习惯CubeIDE的开发者直接编译调试。压缩包为rar格式整体约73.02MB文件类型明细上游暂未提供但可预期包含工程源码、驱动文件与配置资源适合按模块对照学习。目前已有962人学习下载说明该方案在同类开发中具备一定参考价值。读者可从中获得并口时序配置、NT35510初始化流程、I2C触摸读取与坐标处理等可复用代码并借助CubeIDE工程结构快速搭建自己的显示触控原型减少底层驱动调试时间。1. 一块 4.3 寸屏点亮之后我才算真正摸到 STM32 的边去年帮一个做工业面板的朋友看代码他丢过来一个压缩包说屏能亮但触摸坐标死活对不上让我帮忙看看。解压之后发现是 STM32F103ZET6 驱动 4.3 寸 TFTLCD 触摸屏的完整工程从底层 FSMC 时序到触摸校准全在里面。这类资源对刚上手 STM32 的人来说价值很直接它不是一个点灯 Demo而是一条从 GPIO 到 FSMC 到触摸采样的完整链路能让你看清一块屏是怎么被 MCU 一步步驱动的。适合谁适合已经会写基础 GPIO 程序、想搞明白外部总线怎么用、想给项目加一块彩屏交互界面的开发者。下面我按自己拆工程的顺序把这份资源讲透。2. 工程结构与技术选型为什么是 FSMC 而不是软件模拟2.1 目录骨架与文件职责解压后典型的工程目录长这样不同 IDE 版本会有细微差异但核心分层基本一致STM32F103ZET6-TFTLCD-TOUCH-4.3INCH/ ├── CORE/ # 内核启动文件、core_cm3 相关 ├── HARDWARE/ │ ├── LCD/ # 屏幕驱动初始化、画点、字符、图片 │ ├── TOUCH/ # 触摸驱动采样、校准、坐标转换 │ └── LED/ # 板载指示灯调试用 ├── SYSTEM/ │ ├── delay/ # 延时函数SysTick 实现 │ ├── sys/ # 系统时钟配置 │ └── usart/ # 串口打印调试信息 ├── USER/ │ ├── main.c # 主流程 │ └── stm32f10x_it.c # 中断服务 └── STM32F10x_FWLib/ # 标准外设库这个分层是标准库时代的经典写法HARDWARE 放外设驱动SYSTEM 放系统级支撑USER 放业务。好处是移植时只动 HARDWARE 和 USERSYSTEM 基本不用碰。我一般接手这类工程先看 main.c 和 HARDWARE 下的头文件能快速判断驱动接口设计得干不干净。2.2 选 FSMC 的底层逻辑4.3 寸屏常见分辨率 480×800 或 480×272像素点动辄几十万。如果用 GPIO 软件模拟并口时序刷一屏要几十毫秒甚至上百毫秒刷新率低到肉眼可见撕裂。STM32F103ZET6 自带 FSMC灵活静态存储控制器可以把屏幕的 8080 并口映射成一块外部 SRAM 地址写数据就是往固定地址写一个 16 位值硬件自动拉时序速度差一个数量级。工程里通常这样定义屏幕的基地址/* LCD 的 FSMC 地址映射A6 作为 RS 信号线 */ #define LCD_BASE ((u32)(0x6C000000 | 0x0000007E)) #define LCD ((LCD_TypeDef *) LCD_BASE) typedef struct { u16 LCD_REG; /* 写命令 */ u16 LCD_RAM; /* 写数据 */ } LCD_TypeDef;0x6C000000是 FSMC 的 Bank1 区域0x7E是地址偏移利用 A6 地址线区分命令和数据。这样LCD-LCD_REG cmd就是发命令LCD-LCD_RAM data就是发数据编译器生成的存储指令直接触发 FSMC 硬件时序CPU 不参与拉线。参数上要盯住 FSMC 的读写时序配置后面避坑章节会细说。2.3 触摸部分为什么单独成模块触摸和显示是两套独立硬件显示走 FSMC 并口触摸走 SPI 或模拟采样取决于屏的触摸芯片。工程把 TOUCH 单独拆出来是因为触摸需要校准——出厂坐标和屏幕像素坐标不是线性对应的必须采几个点算出比例系数和偏移量。这个校准结果通常存到 Flash 或 EEPROM下次上电直接读。模块拆开之后换屏只改 TOUCH 的采样函数校准逻辑不用动。3. 核心驱动拆解从 FSMC 初始化到画出一个像素3.1 FSMC 时序配置参数错一个就白屏这是整个工程最关键的初始化也是最容易翻车的地方。标准库写法大致如下void LCD_FSMC_Init(void) { FSMC_NORSRAMInitTypeDef init; FSMC_NORSRAMTimingInitTypeDef timing; GPIO_InitTypeDef gpio; /* 使能 FSMC 和 GPIO 时钟 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE); /* 数据线 D0~D15 配成复用推挽 */ gpio.GPIO_Mode GPIO_Mode_AF_PP; gpio.GPIO_Speed GPIO_Speed_50MHz; gpio.GPIO_Pin GPIO_Pin_All; GPIO_Init(GPIOD, gpio); GPIO_Init(GPIOE, gpio); /* 控制线NOE/NE/NWE 等 */ gpio.GPIO_Pin GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_Init(GPIOG, gpio); /* 读写时序单位是 HCLK 周期 */ timing.FSMC_AddressSetupTime 0x02; timing.FSMC_AddressHoldTime 0x00; timing.FSMC_DataSetupTime 0x05; timing.FSMC_BusTurnAroundDuration 0x00; timing.FSMC_CLKDivision 0x00; timing.FSMC_DataLatency 0x00; timing.FSMC_AccessMode FSMC_AccessMode_B; init.FSMC_Bank FSMC_Bank1_NORSRAM1; init.FSMC_DataWidth FSMC_DataWidth_16; init.FSMC_ExtMode FSMC_ExtMode_Disable; init.FSMC_MemoryType FSMC_MemoryType_SRAM; init.FSMC_MemoryDataWidth FSMC_MemoryDataWidth_16; init.FSMC_BurstAccessMode FSMC_BurstAccessMode_Disable; init.FSMC_WaitSignalPolarity FSMC_WaitSignalPolarity_Low; init.FSMC_WrapMode FSMC_WrapMode_Disable; init.FSMC_WaitSignalActive FSMC_WaitSignalActive_BeforeWaitState; init.FSMC_WriteOperation FSMC_WriteOperation_Enable; init.FSMC_WaitSignal FSMC_WaitSignal_Disable; init.FSMC_WriteBurst FSMC_WriteBurst_Disable; init.FSMC_ReadWriteTimingStruct timing; init.FSMC_WriteTimingStruct timing; FSMC_NORSRAMInit(init); FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); }AddressSetupTime和DataSetupTime是重点。前者是地址建立时间后者是数据保持时间单位都是 HCLK 周期。72MHz 主频下一个周期约 13.9ns。屏的 datasheet 里会写最小建立/保持时间比如地址建立 10ns、数据保持 50ns换算下来AddressSetupTime至少 1DataSetupTime至少 4。工程里给 2 和 5 是留了余量。如果屏能亮但花屏、闪屏先怀疑这两个值偏小如果完全白屏先查片选和 RS 线接没接对。3.2 写命令与写数据一个地址偏移的事有了上面的结构体映射底层读写就两行/* 写寄存器地址命令 */ void LCD_WR_REG(u16 regval) { LCD-LCD_REG regval; } /* 写寄存器数据 */ void LCD_WR_DATA(u16 data) { LCD-LCD_RAM data; } /* 读数据用于读 ID 或读显存 */ u16 LCD_RD_DATA(void) { return LCD-LCD_RAM; }逻辑很直白往LCD_REG地址写触发 RS0往LCD_RAM地址写触发 RS1FSMC 自动完成并口时序。参数regval是屏控制器的寄存器编号data是要写入的值。读操作要注意部分屏控制器读数据前需要插入 dummy 读工程里如果读 ID 不对先看是不是少了这一步。3.3 画点函数所有图形的地基/* 在指定坐标画一个颜色点 */ void LCD_DrawPoint(u16 x, u16 y, u16 color) { LCD_SetCursor(x, y); /* 设置光标位置 */ LCD_WR_REG(0x2C); /* 写显存命令 */ LCD_WR_DATA(color); /* 写入颜色值 */ } /* 设置光标不同控制器命令号不同这里以常见 ILI9486 为例 */ void LCD_SetCursor(u16 x, u16 y) { LCD_WR_REG(0x2A); /* 列地址设置 */ LCD_WR_DATA(x 8); LCD_WR_DATA(x 0xFF); LCD_WR_REG(0x2B); /* 行地址设置 */ LCD_WR_DATA(y 8); LCD_WR_DATA(y 0xFF); LCD_WR_REG(0x2C); /* 准备写显存 */ }0x2A和0x2B是列/行地址寄存器0x2C是显存写入。颜色是 RGB565 格式16 位一个像素。画点函数被字符显示、画线、画矩形全部复用所以它的正确性决定整个显示层。如果点画出来位置偏移多半是行列地址的起始偏移没设对有些屏的显存比可视区域大需要加 offset。3.4 触摸采样与校准坐标对不上的根因触摸模块通常先读原始 AD 值再套校准系数/* 读一次触摸原始坐标返回是否按下 */ u8 TP_Read_XY(u16 *x, u16 *y) { u16 xtemp, ytemp; if (!TP_Is_Pressed()) return 0; /* 没按下直接返回 */ xtemp TP_Read_Ad(0x90); /* 读 X 通道 */ ytemp TP_Read_Ad(0xD0); /* 读 Y 通道 */ *x xtemp; *y ytemp; return 1; } /* 用四点校准算出的系数做线性变换 */ void TP_Convert(u16 raw_x, u16 raw_y, u16 *px, u16 *py) { *px (u16)((float)raw_x * tp_xfac tp_xoff); *py (u16)((float)raw_y * tp_yfac tp_yoff); }tp_xfac、tp_xoff这些系数由校准流程算出屏幕上依次显示四个十字用户点中后记录原始 AD 值用最小二乘或简单比例算出斜率和截距。校准结果一般写进 Flash 指定页上电先读读不到再进校准。这里最常见的坑是 X/Y 方向反了或者镜像了本质是屏的安装方向和触摸芯片的坐标轴定义不一致改系数符号就能解决。4. 跑起来编译、下载与第一次点亮4.1 环境准备与工程打开这份工程基于标准外设库常见用 Keil MDK 打开。需要确认三件事装好对应芯片的器件支持包工程里引用的标准库路径没丢下载器配置成 SWD。打开工程后先编译一次看有没有缺头文件的报错缺的话检查 Include Paths 里 HARDWARE 和 SYSTEM 的路径是否都在。# 如果用的是命令行编译链大致流程如下 # 1. 确认 arm-none-eabi-gcc 可用 arm-none-eabi-gcc --version # 2. 进入工程目录按 Makefile 编译 make clean make # 3. 用 openocd 下载 openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \ -c program build/firmware.elf verify reset exit用 Keil 的话直接点 Build 再 Download 即可。下载前确认 BOOT0 接地否则可能进不了用户程序。4.2 上电自检顺序第一次跑建议按这个顺序验证出问题好定位串口先初始化打印一行版本信息确认 MCU 活着。读屏 ID和预期控制器型号比对读不到说明 FSMC 或接线有问题。全屏刷一个纯色确认显存写入通路正常。画几个字符和矩形确认坐标和颜色。进触摸校准点四个十字看坐标是否跟手。每一步失败对应的排查方向不同别一上来就怀疑屏坏了。我见过不少情况是排线没插紧或者背光没供上屏本身是好的。4.3 关键参数速查参数典型值说明主频72MHzF103 标准配置FSMC 数据宽度16 位RGB565 一个像素地址建立时间2 周期偏小易花屏数据保持时间5 周期偏小易闪屏触摸采样通道X:0x90 Y:0xD0随芯片不同校准存储位置Flash 末页掉电不丢5. 避坑与排查那些让我熬夜的现场问题5.1 白屏但背光亮现象上电背光正常屏幕全白串口能打印。原因多半是 FSMC 片选或 RS 线接错或者FSMC_WriteOperation没使能。解决先用万用表量片选脚在写操作时有没有拉低再确认结构体里FSMC_WriteOperation_Enable已设置。如果读 ID 返回 0xFFFF 或 0x0000基本可以锁定通信没通。5.2 花屏、闪屏、局部错位现象能显示但颜色错乱或者刷新时闪烁。原因通常是 FSMC 时序偏紧DataSetupTime不够。解决把DataSetupTime从 5 加到 8 甚至 10 试AddressSetupTime从 2 加到 3。另外检查 HCLK 分频如果系统时钟不是 72MHz时序周期会变参数要重算。5.3 触摸坐标反了或偏移现象点左上角光标跑到右下角。原因是触摸芯片坐标轴和屏幕方向不一致。解决在校准系数上做处理X 方向取反就tp_xfac -tp_xfac镜像就调整偏移量。更稳的做法是校准前先判断原始值随点击位置的变化趋势自动决定符号。5.4 校准数据每次上电丢失现象每次重启都要重新校准。原因是校准结果只存在 RAM 里没写 Flash。解决在TP_Adjust结束后调用 Flash 写函数把系数写到指定页上电时先读该页校验魔数正确才使用。注意 Flash 写之前要解锁写完再上锁。5.5 刷屏慢到肉眼可见现象整屏填充要好几秒。原因可能是逐点写没有用连续写模式或者每次画点都重设光标。解决填充时设一次光标区域然后连续往LCD_RAM写利用地址自增或者开 DMA 搬运。F103 的 FSMC 配合连续写整屏刷新能压到几十毫秒级。6. 二次开发把这份工程改成你自己的界面框架拿到能跑的工程只是起点真正要用起来得做几件事。第一把 LCD 驱动抽象成统一接口比如lcd_draw_point、lcd_fill_rect、lcd_draw_text上层业务只调接口换屏时只改底层。第二触摸校准结果做成配置项支持多点校准提升精度我一般会采 5 个点做最小二乘比四点更稳。第三加一个简单的图层或脏矩形机制只刷变化区域别整屏重绘这在低主频 MCU 上差别很大。改造时有个验证习惯值得坚持每改一层驱动先跑一个固定测试图案——四角标记加中心十字加渐变条肉眼能快速判断坐标、颜色、刷新是否正常。下面这个自检函数我几乎每个屏项目都会留一份/* 屏幕自检四角 中心 边框快速定位坐标和颜色问题 */ void LCD_SelfTest(void) { u16 w LCD_GetWidth(); u16 h LCD_GetHeight(); LCD_Clear(WHITE); LCD_DrawRect(0, 0, w - 1, h - 1, BLACK); /* 边框 */ LCD_DrawPoint(2, 2, RED); /* 左上 */ LCD_DrawPoint(w - 3, 2, GREEN); /* 右上 */ LCD_DrawPoint(2, h - 3, BLUE); /* 左下 */ LCD_DrawPoint(w - 3, h - 3, YELLOW); /* 右下 */ LCD_DrawLine(w / 2 - 20, h / 2, w / 2 20, h / 2, BLACK); LCD_DrawLine(w / 2, h / 2 - 20, w / 2, h / 2 20, BLACK); }LCD_GetWidth和LCD_GetHeight从屏参数宏里取改屏只改宏。四角颜色固定一眼能看出有没有镜像或偏移中心十字验证画线函数。这个函数跑通说明显示链路基本没问题再去调触摸。触摸这块的改造重点是校准流程的健壮性。我踩过的坑是校准过程中手指抖动导致采点偏差后来在采点前加了多次采样取中值并且要求连续几次读数稳定才记录。校准系数算完先做一次回代验证误差超过阈值就提示重校别直接存 Flash。这套流程写进TP_Adjust里后面换任何电阻屏都能复用。最后说个习惯每次改完 FSMC 时序或者换屏我一定先跑自检函数再跑业务代码绝不直接上业务界面调试。因为显示层的问题会伪装成业务 bug浪费的时间远多于多跑一次自检。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询