3、MCU与驱动方案:主流MCU平台与显示控制器的实战选择
做嵌入式显示系统,选MCU平台这一步,其实就决定了你后面能走多远。我这些年经手过不少项目,从简单的温湿度显示到复杂的HMI人机界面,MCU选型这块踩过的坑还真不少。今天咱们就聊聊STM32、ESP32、i.MX RT这三个主流平台,以及它们背后的显示控制器和显存方案。
3.1 主流MCU平台:三足鼎立,各有所长
先说STM32。这玩意儿在嵌入式圈子里太常见了,生态成熟得不能再成熟。我个人习惯用STM32F4或H7系列做中小尺寸的显示项目,比如3.5寸到5寸的TFT屏。为什么?因为它的LTDC(LCD-TFT显示控制器)和DMA2D(2D图形加速器)配合得相当默契。
我在项目中遇到过用STM32F429驱动7寸屏的情况。当时客户要求刷新率至少30fps,还要带简单的动画效果。说实话,一开始我有点担心性能不够。但实际调下来,LTDC负责时序生成,DMA2D负责图层混合和颜色格式转换,CPU几乎不用管显示的事。嗯,这里要注意,STM32的LTDC最高支持XGA分辨率(1024x768),但实际跑起来,800x480左右是最舒服的。
再说ESP32。这芯片带Wi-Fi和蓝牙,天生就是为物联网显示终端准备的。它的显示方案比较特别——没有硬件LTDC,全靠SPI或并行8080接口刷屏。说白了,就是用CPU硬刷。我刚开始做ESP32显示项目时也觉得这太原始了,但后来发现,对于320x240这种小屏,配合ESP32的双核架构和DMA,效果其实还行。
我曾经用ESP32做过一个远程温湿度监测器,屏幕是2.8寸的ILI9341。刷屏用的是ESP-IDF的SPI驱动加DMA传输,帧率大概能到25fps。如果你要做更复杂的UI,比如带触摸和动画的,我建议用ESP32-S3,它带一个可编程的LCD接口,性能比老款ESP32强不少。
最后说i.MX RT。这是NXP的跨界处理器,性能介于MCU和MPU之间。它内置了eLCDIF(增强型LCD接口)和PXP(像素处理管道),说白了就是专门为显示优化的。我做过一个10.1寸的工业HMI项目,用的就是i.MX RT1050。1024x600的分辨率,跑起来毫无压力。
i.MX RT的显示方案有个特点——它支持RGB接口和LVDS接口,可以直接驱动大屏。而且它的PXP硬件加速器可以做图像缩放、颜色空间转换、旋转等操作,这些在STM32上得靠DMA2D慢慢算。你想想看,如果要做视频播放或复杂的UI过渡效果,i.MX RT明显更合适。
| 平台 | 显示接口 | 最大分辨率 | 硬件加速 | 适用场景 |
|---|---|---|---|---|
| STM32F4/H7 | LTDC + DMA2D | 1024x768 | 图层混合、颜色转换 | 中小尺寸HMI、仪表盘 |
| ESP32/ESP32-S3 | SPI/8080 + DMA | 480x320(推荐) | 无硬件加速 | 物联网显示、小屏终端 |
| i.MX RT | eLCDIF + PXP | 1366x768 | 缩放、旋转、颜色空间转换 | 工业HMI、大屏显示 |
3.2 显示控制器:LTDC与DMA2D的配合艺术
LTDC是什么?说白了就是专门负责生成LCD时序的硬件模块。它不需要CPU干预,自己就能产生VSYNC、HSYNC、DE这些信号。你只需要配置好时序参数,然后把帧缓冲区的地址告诉它,它就会自动把数据送到LCD接口上。
我刚开始用STM32的LTDC时,最头疼的就是时序配置。每个LCD屏的时序参数都不一样,比如HBP(水平后肩)、HFP(水平前肩)、VBP(垂直后肩)这些。配置错了,屏幕要么不亮,要么显示错位。后来我总结了一个方法——直接看LCD数据手册里的时序图,把参数一个个填进去,然后用逻辑分析仪抓波形验证。嗯,这招屡试不爽。
// STM32 LTDC时序配置示例
LTDC_HandleTypeDef hltdc;
hltdc.Init.HorizontalSync = 40; // HSYNC脉冲宽度
hltdc.Init.VerticalSync = 9; // VSYNC脉冲宽度
hltdc.Init.AccumulatedHBP = 40 + 20; // HBP + HSYNC
hltdc.Init.AccumulatedVBP = 9 + 2; // VBP + VSYNC
hltdc.Init.AccumulatedActiveW = 800; // 有效宽度
hltdc.Init.AccumulatedActiveH = 480; // 有效高度
hltdc.Init.TotalWidth = 800 + 40 + 20 + 10; // 总宽度
hltdc.Init.TotalHeigh = 480 + 9 + 2 + 1; // 总高度
DMA2D就更有意思了。它是个2D图形加速器,可以独立于CPU进行像素操作。比如你要把一个ARGB8888的图层转换成RGB565格式,或者把两个图层做alpha混合,DMA2D都能搞定。我习惯把DMA2D叫做「显示界的DMA」,因为它确实解放了CPU。
我在项目中遇到过需要做滑动菜单效果的情况。如果用CPU逐像素处理,帧率直接掉到个位数。后来改用DMA2D做图层滚动,配合LTDC的双缓冲机制,效果流畅多了。具体做法是:在后台缓冲区绘制下一帧,然后用DMA2D把数据搬运到前台缓冲区,LTDC自动显示。CPU全程只负责逻辑处理,不碰像素。
3.3 外部显存:SRAM与PSRAM的选择
做显示系统,内存永远不够用。你想想看,一个800x480的RGB565帧缓冲区,就需要800 * 480 * 2 = 768KB。如果再加一个图层做alpha混合,内存需求直接翻倍。MCU内部SRAM通常只有几百KB,所以外挂显存是必然的。
SRAM(静态随机存取存储器)速度最快,但容量小、价格高。我一般只在需要高速随机访问的场景用SRAM,比如做帧缓冲区或DMA2D的临时工作区。STM32的FMC接口可以轻松挂载SRAM,时序配置也不复杂。
PSRAM(伪静态随机存取存储器)就实惠多了。它本质上是DRAM,但内部集成了刷新逻辑,对外接口和SRAM一样。容量可以做到8MB甚至16MB,价格只有SRAM的几分之一。我做过一个项目,用i.MX RT1050外挂8MB PSRAM,同时做帧缓冲区和UI资源存储,效果很好。
不过PSRAM有个坑——它的访问速度比SRAM慢,而且有延迟。我曾经在PSRAM上直接跑DMA2D,结果发现图层混合时出现撕裂。后来查了手册才知道,PSRAM的随机访问延迟比SRAM高一个数量级。解决办法是把DMA2D的突发传输长度设大一点,比如16或32字节,这样能充分利用PSRAM的带宽。
| 类型 | 速度 | 容量 | 价格 | 典型应用 |
|---|---|---|---|---|
| SRAM | 快(<10ns) | 小(<4MB) | 高 | 帧缓冲区、DMA2D工作区 |
| PSRAM | 中等(~70ns) | 大(<16MB) | 低 | 帧缓冲区、UI资源存储 |
| SDRAM | 快(~10ns) | 大(<64MB) | 中 | 大尺寸帧缓冲区、视频播放 |
最后说一句,选显存方案时别只看容量。你得考虑MCU的FMC/SDRAM接口支持什么类型的存储器,以及你的显示控制器需要多快的访问速度。我个人的经验是:小屏(<5寸)用内部SRAM就够了;中屏(5-7寸)用PSRAM性价比最高;大屏(>7寸)或者需要视频播放的,老老实实上SDRAM。
好了,MCU平台和驱动方案这块就聊到这儿。下一章咱们会深入讲讲显示接口的硬件设计,包括RGB、LVDS、MIPI DSI这些接口的实战布线技巧。到时候再聊。