2. 嵌入式UI基础

做嵌入式GUI,第一步不是写代码,而是选硬件。这个道理我是在第一个项目里摔过跟头才明白的。当时急着调界面,随便抓了个开发板就开干,结果做到一半发现内存不够、屏幕刷不动,整个方案推倒重来。嗯,从那以后,我养成了一个习惯:先花一周做硬件选型分析,再动一行代码。

这一章,我就把选型时最关键的几个决策点掰开揉碎讲清楚。你跟着走一遍,至少能避开80%的硬件坑。

MCU vs MPU:核心计算单元怎么选?

很多人一上来就问:「MCU和MPU到底有什么区别?」其实没那么玄乎。我习惯这么看:MCU是单片机,MPU是应用处理器。前者把CPU、RAM、Flash都塞在一个芯片里,后者更像电脑的CPU,需要外挂DDR和存储。

那具体到GUI项目,怎么选?我列个对比表,你一看就明白。

对比维度 MCU(如STM32、ESP32、GD32) MPU(如i.MX6ULL、全志V3s、RK3566)
典型主频 几十MHz ~ 几百MHz 400MHz ~ 1.5GHz+
内置RAM 几十KB ~ 1MB 无(需外挂DDR)
内置Flash 几百KB ~ 2MB 无(需外挂eMMC/NAND)
GUI复杂度 简单控件、2D图形、低帧率 复杂动画、多窗口、高帧率
典型GUI框架 LVGL、uGFX、emWin LVGL(带DMA2D)、Qt for MCU、AWTK
功耗 低(mW级) 较高(几百mW ~ 几W)
BOM成本 低($1 ~ $5) 较高($5 ~ $20+)
开发难度 低,裸机或RTOS 高,需要Linux驱动+文件系统

我的经验法则:如果你的界面只需要显示几个按钮、一个进度条、一些数字,用MCU就够了。如果要做滑动菜单、视频播放、多级页面切换,老老实实上MPU。我曾经在一个项目里硬用STM32F4跑LVGL的复杂动画,结果帧率只有8fps,用户一划就卡死——后来换了i.MX6ULL,问题瞬间解决。

屏幕接口:SPI、RGB、MIPI DSI怎么选?

屏幕接口这块,我见过太多人踩坑了。说白了,接口决定了你的屏幕能跑多快、能支持多大分辨率、需要多少引脚。

SPI接口

SPI是最简单的屏幕接口,只需要4根线(SCK、MOSI、MISO、CS)。但它的瓶颈也很明显:刷新率低。SPI是串行传输,数据是一bit一bit送的。我实测过,用40MHz的SPI刷一块320x240的屏幕,全屏刷新大概要30ms,也就是33fps左右。如果分辨率再大一点,帧率直接掉到十几帧。

适用场景:小尺寸屏幕(2.8寸以下)、低刷新率界面、对引脚数量敏感的项目。比如智能手表表盘、温控器面板。

RGB接口

RGB接口是并行的,R、G、B各用一组数据线,再加上HSYNC、VSYNC、DCLK、DE等控制信号。它最大的好处是不需要显存,直接由MCU/MPU的LTDC控制器驱动屏幕。但代价是占用的引脚多——16位色深需要18根数据线,24位色深需要24根。

我记得有个项目,客户要求用7寸1024x600的屏幕,我选了RGB接口。当时MCU的LTDC控制器直接输出时序,屏幕刷新率能做到60fps,效果非常流畅。但布线的时候,24根数据线在PCB上走等长,差点没把我逼疯。

注意:RGB接口需要MCU/MPU内置LTDC控制器,或者外挂一颗RGB驱动芯片。如果MCU没有LTDC,就别想RGB了。

MIPI DSI接口

MIPI DSI是手机和平板上最常用的接口。它用差分信号传输,只需要2对或4对数据线,就能驱动1080p甚至4K的屏幕。但它的门槛也最高:需要MPU内置DSI控制器,而且驱动协议比RGB复杂得多。

我建议,除非你的项目屏幕分辨率超过720p,或者需要高刷新率(60fps以上),否则别碰MIPI DSI。调试起来太痛苦了,我曾经花了两周才把DSI的时钟和lane配置调对。

接口类型 引脚数 最大分辨率 刷新率 典型成本 调试难度
SPI 4~6 480x320 20~40fps 低 低
RGB 18~28 1280x800 60fps 中 中
MIPI DSI 4~10 4K 60~120fps 高 高

触摸屏:电阻 vs 电容

触摸屏的选择,其实没那么复杂。我直接说结论:能用电容就别用电阻。除非你的项目有特殊需求。

电阻触摸屏

电阻屏的原理是两层导电膜受压后接触,检测电压变化。它的优点是便宜、支持任何物体触摸(戴手套、用笔尖都行)。但缺点也很致命:不支持多点触控、透光率低、容易磨损。

我做过一个工业手持设备,客户要求戴手套操作,没办法只能选电阻屏。结果用了半年,屏幕表面就全是划痕,触摸精度也下降了。后来换了更厚的PET膜,才勉强撑过一年。

电容触摸屏

电容屏利用人体电容感应原理,支持多点触控,透光率高,手感好。现在消费电子几乎全是电容屏。它的唯一缺点是成本稍高,而且戴普通手套不能用(需要特殊手套或触控笔)。

我的建议:家用、商用产品,无脑选电容屏。工业、医疗等需要戴手套的场景,才考虑电阻屏。另外,电容屏的触摸IC选型也很重要,我常用的有FT5x06、GT911、CST816S,都是成熟方案。

存储与RAM需求分析

GUI项目里,存储和RAM的规划直接决定了你的界面能做成什么样。我见过有人用64KB RAM的MCU跑LVGL,结果连一个全屏背景图都刷不出来。

RAM需求怎么算?

RAM主要消耗在三个地方:

  • 帧缓冲区(Frame Buffer):分辨率 × 色深 / 8。比如480x272、16位色深,一个帧缓冲区需要 480×272×2 = 261KB。如果做双缓冲,就是522KB。
  • LVGL/UI框架运行时内存:LVGL默认需要大约10~20KB的堆空间,加上控件对象、样式、字体缓存,一般建议预留50~100KB。
  • 系统堆栈和RTOS:RTOS任务栈、消息队列、定时器等,大约需要20~50KB。

所以,一个480x272的GUI项目,最少需要:帧缓冲区261KB + LVGL 80KB + 系统50KB ≈ 400KB。如果MCU内置RAM只有256KB,那就必须外挂SRAM或SDRAM。

小技巧:如果RAM不够,可以用LVGL的「局部刷新」模式,只刷新变化区域,不需要全屏帧缓冲区。但代价是CPU占用率会升高。

Flash/存储需求怎么算?

Flash主要存三样东西:

  • 代码:LVGL库本身大约100~300KB,加上你的应用代码,总共约300~500KB。
  • 字体:一个全字库(GB2312)大约1~2MB。如果只做数字和英文,几十KB就够了。
  • 图片/图标:一张全屏背景图(480x272、16位色深)约260KB。如果存10张,就是2.6MB。

我建议,MCU方案至少选4MB Flash,MPU方案至少选128MB NAND或8GB eMMC。别省这点钱,后期加功能时Flash不够用,那才叫痛苦。

知识体系总览

下面这张图,把本章的核心决策逻辑串起来了。你选型时,按这个流程走一遍,基本不会漏。

硬件平台选型决策流程 GUI项目需求 MCU方案 MPU方案 SPI接口(小屏) RGB接口(中屏) MIPI DSI(大屏) 电阻触摸屏 电容触摸屏 电容触摸屏 RAM≥400KB Flash≥4MB DDR≥128MB eMMC≥8GB 硬件方案确认 → 开始开发 提示:每个分支都需要根据实际项目需求做权衡,没有绝对最优方案

选型检查清单

最后,我把自己常用的选型检查清单分享给你。每次做新项目,我都会对着这张表过一遍,确保没有遗漏。

  1. 界面复杂度评估:需要多少控件?有没有动画?帧率要求多少?
  2. 屏幕尺寸与分辨率:2.8寸以下用SPI,3.5~7寸用RGB,7寸以上考虑MIPI DSI。
  3. 触摸方式:消费电子用电容,工业/医疗用电阻。
  4. RAM计算:帧缓冲区 + UI框架 + 系统开销,留30%余量。
  5. Flash计算:代码 + 字体 + 图片,至少留50%余量。
  6. 接口引脚数:确认MCU/MPU的引脚数量是否够用,特别是RGB接口需要大量GPIO。
  7. 成本预算:MCU方案BOM通常$5~15,MPU方案$15~40,别超预算。

避坑提醒:我曾经在一个项目里,选了STM32F429 + RGB 7寸屏 + 电容触摸。看起来没问题,但实际做的时候发现,F429的LTDC控制器需要SDRAM做显存,而SDRAM的布线要求很高,PCB打样了三次才稳定。所以,选型时一定要考虑硬件设计难度,别只看芯片参数。