免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

STM32F746 Discovery+TouchGFX图形界面移植实战:从CubeMX配置到屏幕点亮

STM32F746 Discovery+TouchGFX图形界面移植实战:从CubeMX配置到屏幕点亮 如果你跟我一样第一次把STM32F746G-DISCO从包装里拿出来随手插上USB线第一个想法很可能是这块板能不能把图形界面刷得像手机一样顺滑。答案是肯定的而且比想象中容易达成——只要把STM32CubeMX、STM32F746Discovery和TouchGFX这三样东西组合起来半小时内就能点亮一块带触摸的图形界面。我前前后后帮同事和网友排过不少相关的问题发现大多数移植不成功的案例问题并不在TouchGFX本身而是栽在CubeMX的时钟、SDRAM和LTDC配置上。这篇就把一次完整的移植过程完整记录下来从零开始到界面跑起来每一步都说明原因和操作方式希望能帮你少走点弯路。这个实验适合正在学习STM32图形界面开发的嵌入式工程师尤其是刚接触Cortex-M7、对LTDC外设还不熟悉的人。即使你之前完全没碰过TouchGFX只要跟着把环境装好、配置走一遍也能在F746 Discovery板上跑通第一个UI。1. 为什么是F746 Discovery TouchGFX这套组合的背景与硬件账1.1 一个被问过很多次的问题M7核跑GUI到底谁更合适接触过STM32的人应该都有印象F1、F4系列做界面通常要外挂屏和显存或者靠SPI屏慢慢刷效果离流畅两个字有点远。到了F746这一代情况发生了本质变化Cortex-M7内核、216MHz主频片内集成了LTDC液晶控制器、DMA2D图形加速器和FMC外部存储控制器。这意味着MCU可以直接驱动RGB接口的LCD不需要额外买带控制器的屏幕模组帧缓冲也可以放到外扩SDRAM里画质和刷新率都不是SPI屏能比的。而F746 Discovery板也就是我们常说的STM32F746G-DISCO板载资源几乎是为图形界面量身定做的一块4.3寸480x272的RGB LCD、一个电容触摸屏、16MB外扩SDRAM、4MB QSPI Nor Flash、板载ST-Link调试器。这个配置放到今天仍然是学习TouchGFX的黄金搭档因为板子上的BSP代码在官方仓库里几乎是现成的我们要做的只是用CubeMX把这些资源串起来。1.2 TouchGFX不是普通库而是一套完整GUI框架很多新手容易把TouchGFX理解成类似u8g2那样的绘图库实际上它的定位要高得多。TouchGFX包含了一整套渲染引擎负责图形绘制、字体渲染、图像格式解码、动画管理、控件事件分发还自带PC模拟器可以在电脑上先预览界面效果。它和CubeMX深度绑定只要在CubeMX里启用TouchGFX Generator组件生成代码时会自动把HAL层、BSP层、渲染引擎都接好我们只需要用TouchGFX Designer设计界面就行。相比之下LVGL在开源社区更热门也支持STM32但它的移植通常要自己适配底层驱动从零搭一套显示和触摸的桥接代码。TouchGFX的优势在于闭源免费、和ST工具链深度集成、以及针对ST的DMA2D做深度优化。如果你用的是ST自家芯片尤其是F7/H7这种带LTDC和DMA2D的型号TouchGFX的工程效率确实高很多。1.3 板子上的关键外设心里要有数动手配置之前先把F746 Discovery板上的关键资源理清后面配置时才知道每一步在干什么外设用途在TouchGFX移植中的角色LTDCRGB LCD控制器直接驱动480x272屏负责把帧缓冲数据刷新到屏幕DMA2D2D图形加速器做颜色填充、图像混合、块拷贝大幅提升渲染速度FMC SDRAM外扩16MB内存存放帧缓冲和UI运行时缓存是TouchGFX离不开的显存I2C1 FT6206电容触摸触摸输入TouchGFX通过I2C读取触点坐标CRC循环冗余校验单元TouchGFX生成器会用到构建字体缓存时需要QSPI Flash4MB Nor Flash可选存放图片、字体等大块资源这些外设里LTDC、SDRAM、DMA2D是最核心的三块。F746的LTDC支持两层叠加显示我们可以把背景层和前景UI层分开方便做透明效果。DMA2D则能在不占用CPU的情况下把图像数据搬来搬去这是TouchGFX能流畅跑动画的硬件基础。2. 开工前的准备工具链版本、固件包与扩展组件安装2.1 版本搭配是第一个容易翻车的地方TouchGFX移植最常见的失败原因之一就是工具版本不对。STM32CubeMX、STM32CubeF7固件包、TouchGFX Designer这三者必须能协同工作。我的建议是全部使用ST官网当前最新稳定版本不要为了省事用网上流传的旧绿色版CubeMX。具体分版本来说STM32CubeMX建议用6.x以上因为从某个版本开始TouchGFX Generator已经作为独立的软件包来管理旧版本界面和流程差别较大。STM32CubeF7固件包也要在CubeMX的“Manage embedded software packages”里装好这是开发板支持包没有它连选型页都找不到F746 Discovery。TouchGFX Designer从4.13版之后基本是独立安装的安装完成后CubeMX会自动识别它生成代码后可以直接打开设计器。STM32CubeMX的安装本身没什么好说的安装向导一路下一步就行。要注意的是第一次打开时它可能需要访问ST的服务器去拉取固件包国内网络环境下经常超时。如果遇到下载失败别反复重试了直接去ST官网手动下载对应的固件包压缩包放到CubeMX的Repository目录下解压后重新打开CubeMX就能识别。这招比挂什么网络工具都管用。2.2 安装TouchGFX Generator扩展组件新版CubeMX里TouchGFX Generator不是默认就有的需要在软件包管理器里手动添加。打开CubeMX后在Help菜单下找到Manage embedded software packages在软件列表中搜索TouchGFX把STMicroelectronics.TouchGFX这个包勾选安装。安装完成后新建工程时在Software Packs选项卡里就能看到TouchGFX Generator组件点击Add即可添加到当前工程。这一步如果找不到多半是CubeMX版本太旧或者软件包列表没有刷新。另外部分版本安装TouchGFX包时需要ST账号登录如果登录页死活打不开可以先检查ST账号密码是否正确再不行就从TouchGFX官网单独下载安装包。安装好TouchGFX Designer之后CubeMX通常会自动关联不需要额外配置环境变量。2.3 从板卡选择器创建工程不要从芯片选择器手动建我见过不少人在第一步就给自己挖了大坑新建工程时选择“STM32F746NGHx”芯片然后手动配置引脚。F746 Discovery板的引脚映射是官方精心设计过的LTDC的R、G、B数据线分别接在哪些引脚、SDRAM挂在哪个Bank这些细节你手动查原理图配一遍不仅费时还很容易配错。正确做法是新建工程时切换到Board Selector选项卡在搜索框输入F746G-DISCO选择对应开发板CubeMX会自动加载这块板的默认引脚和初始化配置。这才是“快速移植”的关键所在。基于板卡模板创建工程后原本需要手动配的一大堆引脚都会自动分配好我们只需要在上面的基础上调整时钟和使能TouchGFX Generator。顺带提一句CubeMX界面语言不需要纠结中文汉化包对使用帮助不大菜单、配置项都是专业术语用英文界面反而更容易在网上搜到解决方案。3. CubeMX里的核心配置时钟、外部存储、显示与触摸3.1 时钟树216MHz主频与LTDC像素时钟的计算CubeMX在创建工程后默认的时钟配置是HSI必须先切到外部晶振并配置PLL。F746 Discovery板上焊的是25MHz外部晶振这是和Nucleo板常用8MHz晶振不一样的地方配置时钟树时千万不要照搬网上的8MHz教程。需要配置两条时钟链路一条给CPU和总线另一条给LTDC。CPU这条比较简单HSE 25MHz经过PLL倍频到216MHzAHP、APB1、APB2总线分频按默认即可。LTDC的像素时钟来自PLLSAI这个参数直接影响屏幕刷新率和稳定性。480x272分辨率的面板典型的像素时钟范围在9MHz到27MHz之间TouchGFX官方示例通常配置在25MHz到30MHz左右。PLLSAI的R分频器输出一般设成27.x MHz我实测下来刷屏稳定画面没有闪烁感。一个典型的配置参数是PLLSAI_N 192PLLSAI_P 4PLLSAI_Q 4PLLSAI_R 7这样PLLSAI_R的输出大约是25MHz乘以192除以7再除以2算出来约等于27.4MHz。具体倍频值和分频值在CubeMX图形界面上可以直接拖拽UI会实时显示计算出的频率值。要注意的是像素时钟不是越高越好超过面板规格上限后会出现花屏或同步异常遇到这种情况先回来降频率。3.2 SDRAM配置TouchGFX帧缓冲的家F746 Discovery的16MB SDRAM挂接在FMC外设上。CubeMX的板卡模板会自动把FMC的SDRAM Bank1配置好并分配引脚。我们要做的事主要是确认两个地方一个是SDRAM的时序参数另一个是内存地址。地址方面FMC的Bank1 SDRAM区域起始地址是0xC000000016MB SDRAM覆盖0xC0000000到0xCFFFFFFF。TouchGFX的帧缓冲就放在这个区域。时序参数在CubeMX的FMC配置界面里SDRAM型号不同参数会有差异板卡模板默认的时序值通常是可用的。如果把时序配得太紧SDRAM读写偶尔出错UI上表现就是花屏、闪屏而且问题时有时无很难排查。启动顺序也很重要SDRAM必须在主循环运行之前完成初始化否则TouchGFX一启动就往0xC0000000地址写数据就会直接HardFault。CubeMX生成代码后MX_SDRAM_Init()的调用顺序在main函数里是排在外设初始化阶段的这块不用太担心。3.3 LTDC时序与引脚确认LTDC的配置界面里有几个关键参数面板尺寸、同步脉冲宽度、前后肩、数据格式、图层格式。对于F746 Discovery自带的LCD板卡模板通常会直接填好这些参数。如果没有480x272屏幕的典型参数是HSYNC宽度41像素VSYNC宽度10行HBP为2像素HFP为2像素VBP为2行VFP为2行。这些数值可以在TouchGFX官方例程对应的BSP文件里找到直接照抄即可。数据格式部分是重中之重。F746 Discovery的LCD接口是RGB888也就是24位色。TouchGFX侧支持多种帧缓冲格式为了显示效果最好建议在LTDC里配置24位RGB像素格式并在TouchGFX Generator里把帧缓冲格式也选成RGB888两边保持一致否则会出现颜色错乱。还要确认LTDC的图层。TouchGFX通常只用Layer0Layer1可以留空。Layer0的窗口位置设为(0,0)尺寸设为480x272像素格式和帧缓冲格式对齐。只要Layer的起始地址指向SDRAM中已经分配好的帧缓冲区域即可。3.4 DMA2D、CRC与触摸I2C的配置DMA2D在CubeMX里使能即可不需要额外配置复杂的参数。它是TouchGFX渲染加速的重要帮手在所有图像块传输、颜色填充操作中都会被调用。如果这里没有使能TouchGFX虽然也能跑但性能会明显下降动画掉帧。CRC外设是单次配置后永远运行的小模块。TouchGFX在运行时需要用到CRC单元来做图像数据的校验计算不配置它会导致程序启动阶段直接断言失败。很多人在这一步翻车明明显示和触摸都正常程序却跑不起来打开调试器发现卡在touchgfx_assert里往前查才发现CRC没开。触摸部分板载FT6206接在I2C1上地址是0x38。CubeMX板卡模板会把I2C1的引脚和速度配好确认一下I2C时钟频率在400kHz左右即可。TouchGFX生成的BSP代码会自行通过I2C读取触摸芯片我们不需要写任何底层驱动但前提是I2C外设必须使能并初始化。3.5 TouchGFX Generator参数设置前面的外设都配好后进入Software Packs选项卡点击TouchGFX Generator组件开始配置集成参数。这个页面看起来选项很多实际只需要关注几个Application Name保持默认TouchGFX即可。Display接口选LTDC。Framebuffer Location选择SDRAM这是让TouchGFX把帧缓冲放到0xC0000000区域的关键。Framebuffer Format选RGB888和LTDC颜色格式一致。RTOS Integration按需选择。如果要在UI中跑FreeRTOS任务可以选FreeRTOS如果只是跑裸机选None即可。我的建议是先用None跑通后续再加RTOS分开调试问题范围更清晰。这些参数设置完成后生成代码时CubeMX会自动完成一系列事情把TouchGFX的核心库文件复制到工程目录生成HAL层初始化代码创建TouchGFX Designer工程所需的结构。我们要做的只剩下打开设计器画界面。4. 生成代码后的迁移与集成从CubeMX到TouchGFX Designer4.1 生成之后的工程结构CubeMX默认生成的工程目录不管你是用STM32CubeIDE还是Keil都会在当前目录下创建一堆子目录。加入TouchGFX Generator后会多出一个TouchGFX目录里面是UI项目的完整结构generated子目录存放自动生成代码gui子目录是设计器生成的界面代码target子目录里是HAL层的适配文件。打开CubeIDE后如果你看到touchgfx目录下的源文件没有参与编译不要慌先去工程属性的Paths and Symbols里确认头文件路径。TouchGFX的include路径比较多正常情况下CubeMX生成时会自动添加但偶尔因为工程导入顺序问题会丢几项手动补一下就能解决。4.2 TouchGFX Designer中打开工程和创建首屏双击工程目录里的.ioc文件TouchGFX Designer会以CubeMX项目的形式打开它。这么做的好处是设计器能直接读取到CubeMX里配置好的LTDC参数并在模拟器中按真实分辨率预览UI。设计器打开后左侧是控件面板中间是画布右侧是属性区。我们把默认的Screen0重命名为MainScreen拖一个Button控件到画布中央改一下按钮文本再设置背景颜色一个最简单的交互界面就出来了。设计完成后按F6生成代码TouchGFX Designer会把界面代码、资源和相关初始化代码写回到TouchGFX目录。然后切回CubeIDE如果弹出文件变更提示就选择刷新重新编译工程。整个过程不需要手动拷贝任何库文件也不用手写一行界面代码。4.3 链接脚本手动用SDRAM时需要的处理这里要澄清一个常见误区只要我们用的是TouchGFX Generator并且Framebuffer Location选的是SDRAM那么帧缓冲地址是由生成的HAL代码直接指定的不依赖链接脚本。换句话说默认情况下你不需要为TouchGFX修改链接脚本。但如果你的项目需要在SDRAM里分配额外的大块内存比如自定义的纹理缓存、音频Buffer或者图像资源池那就必须手动改CubeIDE里的.ld链接脚本。一个示例是在MEMORY段中增加SDRAM区域MEMORY { FLASH (rx) : ORIGIN 0x08000000, LENGTH 1024K RAM (xrw) : ORIGIN 0x20000000, LENGTH 256K SDRAM (xrw) : ORIGIN 0xC0000000, LENGTH 16M }然后再加一个段把需要放到SDRAM的变量收集进来。这种方式相对繁琐我的建议是能用TouchGFX内部机制解决的就不动链接脚本只有确定要放外部内存的大块数据时才这么做。4.4 Cache与DMA2D一致性问题F7特有的坑如果你是第一次从F4迁移到F7必须习惯一个概念Cortex-M7有ICache和DCache这是F4没有的。Cache能提升CPU访问内存的速度但也带来了数据一致性问题。CPU写入帧缓冲的数据可能还待在Cache里DMA2D从SDRAM读到的却是旧数据结果就是画面出现随机花屏、颜色块错乱而且表现很不稳定。TouchGFX官方推荐的解决方案一般是两种。第一种是把帧缓冲所在SDRAM区域配置成Non-cacheable通过MPU实现第二种是在帧缓冲切换后主动做Cache Clean操作。我更推荐第一种因为操作简单、无需改动TouchGFX内部代码。CubeMX里MPU配置页可以新建一个RegionBaseAddress设为0xC0000000Size设为16MBCacheable属性关掉然后使能MPU。代码大致是这样MPU_Region_InitTypeDef MPU_InitStruct {0}; HAL_MPU_Disable(); MPU_InitStruct.Enable MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress 0xC0000000; MPU_InitStruct.Size MPU_REGION_SIZE_16MB; MPU_InitStruct.AccessPermission MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsCacheable MPU_REGION_NOT_CACHEABLE; MPU_InitStruct.IsShareable MPU_REGION_NOT_SHAREABLE; MPU_InitStruct.TypeExtField MPU_TEX_LEVEL0; HAL_MPU_ConfigRegion(MPU_InitStruct); HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);如果你暂时不想深挖MPU还有一个保底做法在main函数里把DCache直接关掉。代价是图形渲染性能下降因为CPU缓存完全失效。在项目早期排查问题时可以用这个方式快速确认是否Cache一致性导致的花屏等验证过UI功能正确后再回过头来配置MPU把性能拉回来。这个排查思路在调试阶段非常实用。5. 编译、烧录与跑起来常见报错与踩坑实录5.1 编译链接常见的三类错误移植过程中编译报错是难免的但很多错误其实是同一个根源。我整理几个高频错误和对应的处理方向报错信息常见原因处理方式fatal error: TouchGFX/touchgfx.hpp: No such file or directoryTouchGFX头文件路径没加进工程在工程属性里添加touchgfx目录下的include路径undefined reference to touchgfx::HAL::initialize()TouchGFX生成代码没参与编译或是生成器配置不全重新检查TouchGFX Generator是否成功运行确认target目录参与了编译cannot open source input file stm32f746xx.hSTM32CubeF7固件包未安装在CubeMX的软件包管理器里安装F7固件包后重新生成代码如果你用的是Keil还需要特别检查C/C编译器选项里是否定义了STM32F746xx这个宏。CubeIDE一般会自动配置但Keil工程偶尔会漏这个宏没定义的话整个HAL层头文件都会报错。5.2 运行时问题HardFault、花屏、触摸无效编译通过只是第一步运行时崩溃往往更让人头疼。HardFault这个错误百分之八九十和SDRAM有关。程序一启动就进HardFault先别急着看代码逻辑用调试器看一下PC指针和LR寄存器如果停在外设初始化阶段优先怀疑SDRAM初始化失败了。确认方法是单步调试MX_SDRAM_Init看函数返回值是否正常。花屏问题要分两种静态图片显示正常但动态刷新时花屏大概率是Cache一致性问题按前面MPU的处理方式来解。如果静态显示就有大量杂色线条先检查LTDC像素时钟频率再检查LTDC和TouchGFX之间的帧缓冲格式是否一致。RGB888的设置两处不匹配颜色通道就会错乱看起来很像花屏。触摸无响应时先回到最底层确认I2C通信正常。CubeIDE调试模式下手动读取I2C1地址0x38如果能正确读到FT6206的寄存器数据说明硬件链路没问题问题出在TouchGFX的触摸驱动配置上。更常见的场景是触摸方向不对屏幕显示方向默认可能是横屏而触摸芯片坐标轴没有对应旋转表现就是点一个按钮却触发另一个按钮。解决办法是在TouchGFX Designer的工程设置里调整显示旋转方向或在target中的HAL初始化代码里配置触摸坐标变换。5.3 分阶段验证一条更快的调试路径最后分享一个我实际项目中屡试不爽的方法不要等整个UI工程都设计好了再烧录调试而是先分阶段验证硬件和底层配置。第一步在CubeIDE里写一个简单的main函数初始化LTDC后直接在SDRAM的帧缓冲地址填充固定颜色看屏幕是否能显示纯色画面。这个验证通过说明LTDC和SDRAM链路没问题。第二步使能DMA2D并做一个简单的颜色填充测试确认图形加速器工作正常。第三步再把TouchGFX Generator加上跑一个最简单的Button示例。每一步都有独立验证点出了问题能迅速定位到具体模块。我个人的体会是TouchGFX移植这件事最大的障碍往往不是工具本身而是对F7平台的硬件特性不够熟悉。只要把时钟树、SDRAM、LTDC、Cache这几个看似基础却又相互关联的环节理顺TouchGFX在F746 Discovery上跑起来是非常快的。这个流程打通之后你再去碰H7系列或者更大的分辨率屏幕思路都是一样的先确认显示链路再确认内存最后才上GUI框架。
返回列表