
F746Discovery这块板子很多人入手就是冲着那块480x272的RGB屏那不用TouchGFX做点界面确实可惜。上次1.1实验里我把串口和LED调通了这次直接进入图形界面环节用STM32CubeMX配合TouchGFX Designer做一次完整的移植把F746上的“屏幕”真正点亮成“界面”。这篇文章适合刚接触TouchGFX、想快速在STM32F746Discovery上出画面的人也适合有CubeMX基础但被TouchGFX各种版本配置绕晕的朋友。我会把工具链版本、外设配置、步骤顺序、踩坑点全部摊开讲跟着走一遍基本能少走我一个月的弯路。先说结论TouchGFX移植本身不难难的是移植前的配置和版本匹配。STM32CubeMX负责把芯片底层外设SDRAM、LTDC、DMA2D、FreeRTOS初始化好TouchGFX Designer负责生成界面框架和渲染引擎两者通过一个中间件对接。所以整个实验本质上就是“把外设配对、把对接打通、把界面跑起来”三件事。下面按实操顺序来。1. 环境准备与工具链搭建1.1 需要的软件和版本建议开始之前先把软件装齐别急着开CubeMX。我这边用的是Windows 11STM32CubeMX 6.10.0TouchGFX Designer 4.21.1STM32CubeF7固件包1.17.3IDE用的是STM32CubeIDE 1.14。这套组合实测下来没有遇到明显的兼容性问题。版本这里多说几句TouchGFX有个特点它跟CubeMX之间的联动是通过一个叫TouchGFX Generator的中间件实现的这个中间件在CubeMX的中断组件列表里能看到。不同版本的CubeMX自带的TouchGFX Generator版本不一样比如CubeMX 6.9之后开始默认集成了TouchGFX Generator的更新通道如果你用的是很老的CubeMX可能连TouchGFX Generator这个选项都没有。反过来TouchGFX Designer如果版本太老打不开新版CubeMX生成的.ioc文件会提示版本不兼容。所以我建议直接都装最新稳定版不要纠结“哪个版本最经典”新板的Bug修复和芯片支持都更完整。还有一个容易被忽略的东西STM32CubeF7的固件包。CubeMX生成代码的时候需要F7系列的HAL库如果不预先下载固件包CubeMX会让你在线下载那个速度看网络情况有时候能卡到你怀疑人生。我习惯在CubeMX的Help - Manage embedded software packages里预先装好F7系列或者在ST官网手动下载固件包后导入。F746Discovery的板载ST-Link驱动也需要装否则后面烧录识别不到芯片。1.2 关于汉化和登录这类细节问题装好之后很多人会搜“stm32cubemx中文汉化”“stm32cubemx中文版”这个我建议直接放弃。CubeMX的汉化只覆盖菜单栏和部分弹窗真正核心的配置界面——Pinout视图、Clock Configuration、中间件参数——还是英文而且汉化后出问题去搜英文报错信息反而不容易对应。我用英文界面用习惯了之后基本不会因为界面语言再看第二眼中文汉化反而容易误导你在找选项的时候按中文概念去猜但界面里还是英文来回切换更痛苦。还有个小坑是“stm32cubemx登录不了”。这个问题在TouchGFX Designer上更容易遇到在线资源库、账户中心需要登录ST账号有时候因为网络原因登录很慢或者登录失败。但这里要说明白本地工程创建、代码生成、编译、烧录都不需要登录账号。所以登录不上不用慌直接跳过在线内容本地操作完全不受影响。我在多个网络环境下试过TouchGFX Designer离线状态下打开模板工程、生成代码、配合CubeMX编译都没问题只是没法下载在线扩展包而已。注意如果你装完TouchGFX Designer之后CubeMX的Tools菜单里找不到TouchGFX Designer入口多半是安装路径或版本识别问题。最简单的办法是两边都重装一次先装TouchGFX Designer再装CubeMX让CubeMX在安装时自动识别到Designer。2. 用STM32CubeMX把F746的图形显示“地基”打好2.1 时钟树216MHz怎么配出来打开CubeMX新建工程选择STM32F746NGH6F746Discovery板载芯片就是这个型号。在System Core - RCC里把HSE设为Crystal/Ceramic Resonator因为板子的外部晶振是25MHz这个决定了后面的PLL倍频系数。时钟树配置是第一个容易出错的地方。TouchGFX本身对CPU主频没有硬性要求但帧缓冲写入、DMA2D搬运、图形渲染都吃CPU和总线的性能我的习惯是把主频拉到最高的216MHz。F746的时钟链是25MHz外部晶振 - PLL - SYSCLK。在Clock Configuration页面里把HCLK输入216CubeMX会自动帮你算好分频倍频系数前提是HSE填的是25。这里有个小细节SDRAM的时钟FMC和LTDC的像素时钟都是从时钟树里分出来的如果你把系统时钟改乱了LTDC的像素时钟可能超出屏幕规格画面就会闪烁或者干脆不亮。配完时钟看一眼APB1和APB2分频F746的多数外设都挂在APB1/APB2上默认分频关系CubeMX会处理不用手调。DMA2D挂在AHB1上这个不用专门配置时钟使能默认就有。2.2 FMC/SDRAM配置帧缓冲的家F746Discovery板载了一颗IS42S16400J容量16MB16位数据宽度行地址12位、列地址9位挂在FMC的Bank1 SDRAM区。TouchGFX的帧缓冲需要放在SDRAM里否则片内RAM不够用。这块配置是整个实验里最劝退人的地方但其实就是参数对齐的问题。在Categories里找到FMC打开SDRAM Bank1配置。关键参数如下参数项填写值说明BankSDRAM Bank 1片选信号对应NE1Number of Column Address Bits9 bits芯片列地址宽度Number of Row Address Bits12 bits芯片行地址宽度Number of Internal Banks4 BanksSDRAM内部bank数Data Bus Width16 bits板载SDRAM数据线宽度CAS Latency2这个我实测配2比配3稳定Write ProtectionDisabled关闭写保护SDRAM Timing参考时序表见下方说明时序参数是重点。我第一次移植时就是时序没配好界面偶尔花屏、跑着跑着HardFault排查了很久。IS42S16400J的tRCD约15nstRP约15nstRC约63ns在HCLK为216MHz时FMC时钟是HCLK/2108MHz一个周期大约9.26ns。以这些为基础我给出一组实测稳定的配置行预充电延时设为2个FMC时钟周期行激活延时设为2个周期恢复时间设为4个周期最小自刷新时间设为8个周期。这组值不是唯一的不同颗粒可能略有差异但F746Discovery板上这套参数直接用没问题。SDRAM的地址映射也要注意。F746的FMC SDRAM Bank1起始地址是0xC0000000TouchGFX的帧缓冲、桌面堆、纹理缓冲都会放在这个区域。配置完成后生成初始化代码后会用HAL_SDRAM_Init()做初始化后续访问直接按指针操作即可。判断SDRAM是否初始化成功最简单的方法是往地址0xC0000000写一个固定值再读出来读回来一致就说明初始化OK。2.3 LTDC与DMA2D屏幕显示通道LTDC是ST芯片上的LCD控制器负责把显存里的数据按行场时序推送到屏幕。F746Discovery板载屏幕是4.3寸480x272的RGB屏接口方式是从LTDC直接输出RGB888信号所以CubeMX里LTDC要配置成RGB888格式分辨率480x272。在LTDC配置界面里有几个核心参数H Sync、V Sync、H Back Porch、V Back Porch等。这些值跟屏幕的时序要求强相关F746Discovery板载屏的具体参数在ST官方文档里有但我印象比较深的是水平同步宽度约40像素垂直同步宽度约9行水平后肩约15像素垂直后肩约3行水平前肩约40像素垂直前肩约5行。这些值就算有一点偏移屏幕也能显示只是画面位置可能偏不会完全不亮。真正导致不亮的是LTDC的Pixel Clock设置480x272的屏刷新率60Hz左右像素时钟大约在9MHz到10MHz之间。在时钟树配置里把LTDC时钟设成这个范围太低了画面闪烁太高了屏幕会花屏甚至黑屏。图层配置上TouchGFX通常用Layer 0作为主显示层。在LTDC配置里把Layer 0打开窗口大小设为480x272像素格式ARGB8888背景色填黑色帧缓冲地址可以暂时留空等TouchGFX生成代码后会自动填充。DMA2D的配置其实不用单独配什么参数只要确认外设使能就行。TouchGFX在渲染的时候会自动调用DMA2D做快速搬运、混合和颜色填充如果DMA2D没使能界面能显示但性能会明显下降滑动动画卡到没法看。2.4 背光引脚和FreeRTOSF746Discovery的屏幕背光由一颗LED驱动芯片控制使能脚是PI12。在CubeMX里把PI12配成GPIO输出默认输出高电平点亮背光。很多人配置完LTDC发现屏幕亮了一点但看不到内容就是背光没打开因为LTDC只是输出信号屏幕物理背光得靠这个引脚控制。FreeRTOS的配置也很关键。TouchGFX官方建议在RTOS环境下运行因为GUI任务、渲染任务、触摸监测任务要分时调度裸机跑虽然能出画面但动画刷新率上不去。在Middleware里勾选FreeRTOSCMSIS_V2接口默认生成一个任务。TouchGFX Generator会自动创建一个名为TouchGFX_Task的任务配置它的栈大小、优先级要留够我习惯给这个任务分配2048字节栈单位是字不是字节CubeMX里要填2048字优先级在中上水平。另外SysTick默认被FreeRTOS占用后HAL_Delay会用其它定时器实现这个CubeMX会自动处理不用管。这里有个常见问题如果生成的TouchGFX任务栈太小程序跑起来后很快就会进入HardFault表现就是画面画一半就死机。所以别省栈空间宁可多给也不要少给。3. 与TouchGFX Designer联动生成界面工程3.1 进入TouchGFX Designer的两种方式CubeMX配置完成后在菜单里找到Tools - TouchGFX Designer点开回自动读取当前.ioc工程。如果你装了独立的TouchGFX Designer也可以先打开Designer然后导入CubeMX生成的.ioc文件。两种方式本质是一样的让Designer认识这个工程的芯片型号、外设配置和生成路径。这里要强调一个版本匹配问题Designer打开.ioc文件时如果版本比生成这个文件的CubeMX旧会报“The project was created with a different version of STM32CubeMX”之类的提示。应对方法就是前面说的把两边版本都升到最新不要一个最新一个新三年前的。3.2 模板选择与生成代码结构在Designer里新建Screen选择Simulator或F746的模板。为了直接下载到板子选Board带起的模板ST官方有F746Discovery对应的模板工程里面已经把TouchGFX的HAL层、显示驱动、帧缓冲管理都写好了。这样生成的代码里有两个核心目录TouchGFX和Core。Core目录下面是CubeMX生成的外设初始化代码包括FMC、LTDC、FreeRTOS等TouchGFX目录下面则是Designer生成的GUI框架代码包含MVP架构的Model/View/Presenter、触摸回调、帧缓冲管理器和渲染核心。生成完代码之后打开根目录下的.ioc文件路径会看到一个完整的STM32CubeIDE工程。我的建议是第一次先不要改任何东西直接编译下载先确认“默认工程能跑起来”这比后面边改边排查有效得多。3.3 快速做一个最简单的界面交互默认工程在板上运行起来后是一个TouchGFX自带的演示界面能看到很多控件和动画。这时候再进Designer新建一个Screen拖一个Button控件进去再拖一个Text Area放在旁边。给Button添加点击事件在业务逻辑里做一个计数器每次点击让Text Area的文本更新。这个交互就足够验证整个链路了触摸如果有触摸屏或者按键事件 - MVP回调 - 界面更新。F746Discovery这块板子本身不带触摸屏所以交互一般用板上的按键或者通过串口发送指令。没有触摸也不影响动画和控件显示TouchGFX的画面渲染、文字重绘、动画切换都能独立跑通。Generator生成的代码结构里View层的setupScreen()是界面初始化入口handleTickEvent()可以做周期性的动画逻辑Model层负责与后台任务交互这些模板都有了照着填就行。需要注意编译生成的工程文件里TouchGFX的库代码默认是编译好的静态库内核源码混合形态第一次编译会比一般工程慢不少几分钟都是正常的别以为卡死了。4. 编译烧录与结果验证4.1 编译运行与烧录用STM32CubeIDE打开生成的工程第一次编译时如果报缺头文件先在左侧项目树上右击选择Index - Rebuild让IDE的代码索引刷新一遍很多“找不到头文件”其实是索引没更新。编译配置建议用Release模式Debug模式虽然也能跑但TouchGFX在Debug下的优化较差画面帧率会明显下降。编译成功后用板载ST-Link烧录。在IDE的Run Configuration里选择ST-LINK板载ST-LINK烧录完成后按一下板上的Reset。正常情况下屏幕会亮起出现TouchGFX的欢迎界面或者你做的那个Button计数器界面。如果屏幕黑着大概率不是代码问题而是前面的LTDC或背光配置没通回到第2章对着查。第一次成功点亮后我强烈建议做个简单性能验证在TouchGFX界面上加一个FPS计数器Designer里有现成的Performance Monitor组件跑动画时观察FPS。F746在RGB565或ARGB8888下一般能达到60FPS。如果只有二三十帧检查一下是不是DMA2D没使能或者帧缓冲格式选了ARGB8888导致带宽吃紧换成RGB565会快不少。4.2 验证画面之外的东西画面出来之后还要验证一件事情掉电重启后程序是否能正常引导。F746Discovery板载有QSPI Flash很多Demo代码会把程序放到外部Flash启动但用CubeMX生成后默认烧录到内部Flash。确认一下BOOT引脚在Flash启动模式然后断电重新上电如果每次都稳定出现界面说明SDRAM的初始化时序是可靠的。如果偶尔白屏或者启动慢多半是SDRAM自刷新时序边缘化把恢复时间参数再加一个时钟周期再试试。5. 常见问题与排查技巧实录5.1 白屏、花屏类问题白屏是TouchGFX移植里出现频率最高的问题。排查顺序我一般固定为先确认背光有没有点亮再确认LTDC有没有输出信号然后确认SDRAM初始化是否成功最后确认帧缓冲地址是否指向SDRAM。这四个环节里最容易出错的是SDRAM时序尤其是恢复时间和自刷新时间的设置。遇到白屏不要急着调代码逻辑先用调试器看程序跑到哪一步再在SDRAM基地址0xC0000000处手动写读数据能读回来就说明硬件通道是通的。花屏则一般是时钟问题要么LTDC像素时钟过高要么SDRAM数据线时序不稳定。此时把LTDC的像素时钟降一点再看看效果。还有一种花屏是颜色格式不对Designer模板默认是RGB565但LTDC配成ARGB8888数据解释错位会导致颜色完全不对但轮廓清晰这时把两边的像素格式统一就行。5.2 编译链接问题“fatal error: touchgfx/....h: No such file or directory”这个问题也很常见。TouchGFX的头文件路径是在生成的工程里自动配好的如果出现这种情况检查两个点第一是否手改了工程的Include Paths第二是否移动过工程目录导致相对路径失效。第二个点特别注意CubeMX生成的工程挪位置后推荐用IDE直接把工程删掉重新导入不要手动改路径。如果遇到“undefined reference to touchgfx::xxx”的链接错误多半是TouchGFX库没有参与链接。查看链接脚本和库文件路径确认TouchGFX的lib文件在工程里存在。偶尔Designer生成不完整也会有这个问题重新在Designer里做一次Generate Code就好。5.3 运行死机与HardFault运行中不时HardFault大概率是SDRAM没有被正确初始化就被TouchGFX访问了或者是任务栈溢出。在使用FreeRTOS时把栈加大给TouchGFX任务2048字以上再不行就看看是不是中断优先级设置问题——FreeRTOS要求所有中断优先级不高于configMAX_SYSCALL_INTERRUPT_PRIORITY如果LTDC中断优先级配得太高可能在RTOS临界区里触发中断导致死锁。这块排查起来比较隐蔽建议直接按CubeMX默认的优先级来。5.4 常见问题速查表现象可能原因解决办法黑屏、屏幕完全不亮背光引脚未使能PI12配置为GPIO输出高电平黑屏但背光亮了LTDC像素时钟不对或时序极性问题核对LTDC时钟和行场极性参数白屏SDRAM未就绪或帧缓冲地址未生效检查FMC配置和0xC0000000读写花屏像素格式不匹配或SDRAM时序边缘统一RGB565/ARGB8888放宽时序编译找不到touchgfx头文件路径引用失效或索引未更新重新导入工程/重建索引链接报undefined referenceTouchGFX库未链接或生成不完整在Designer里重新生成代码跑动画卡顿明显DMA2D未使能或格式耗带宽打开DMA2D优先用RGB565HardFault栈溢出/SDRAM未初始化/中断优先级问题加大任务栈、确认SDRAM初始化顺序、调整优先级最后说点我自己的体会。TouchGFX移植这件事70%的坑集中在外设初始化和版本匹配上真正写界面逻辑反而很简单。我的建议是第一次移植不要改任何模板给的东西先把默认工程跑起来再一项一项加自己的控件和逻辑。如果你按这个流程走一遍还出不来画面多半是SDRAM时序或者LTDC信号极性这类细节回头把2.2和2.3那两张配置表对着检查一遍基本都能救回来。我在实际跑完这个实验之后又把颜色格式改成RGB565重新出过一次画面帧率比ARGB8888明显更稳做一个简单的仪表盘界面完全够用。后续如果你想做复杂一点的动画切换、多屏导航步骤都还是这套只是Designer里多加几个Screen和交互逻辑而已。