
玩STM32F407的人基本都遇到过这么一幕板子画完固件烧进去USB线一插电脑要么是“无法识别的USB设备”要么就只有“滴嘟”一声然后没下文。旁边老师傅幽幽来一句“USB嘛都是玄学多拔插几次就好了”。我过去也信这个直到后来自己做了一版STM32F407 USB3320的高速USB OTG硬件仔细梳理完原理图和PCB才发现所谓“玄学”其实九成都是硬件设计阶段埋下的雷跟运气没多大关系。这篇内容就围绕STM32F407外接USB3320搭建480Mbps高速USB OTG的完整硬件方案展开。我会把为什么必须外接PHY、原理图怎么连、PCB怎么布、上电之后按什么顺序排查全部讲清楚并且把关键连接整理成可以直接抄的清单。适合正在画F407板子、打算做高速USB传输或者OTG功能的硬件工程师也适合软件工程师想搞明白硬件到底坑在哪。看完这篇至少下一次USB插上不识别的时候你知道先量哪里而不是对着原理图发呆。1. 先搞清楚为什么STM32F407要外接USB3320才能跑高速1.1 F407自带USB的“全速陷阱”STM32F407这颗芯片在USB方面其实给了两个控制器一个OTG_FS一个OTG_HS。很多人一看型号里带“F407”官方手册写着“USB OTG HS/FS”就觉得USB高速480Mbps是板上钉钉的事。结果按内部PHY直接画板跑起来一测速度卡在12Mbps上不去百思不得其解。原因在于STM32F407的OTG_HS控制器本身支持高速480Mbps但它内部的PHY只能做到全速12Mbps。控制器是“高速”的物理层收发器却只有“全速”能力想跑高速就必须外接一个支持高速的USB PHY通过ULPI接口把控制器和PHY连起来。这个设计在ST的参考手册里写得很清楚但如果你只看了芯片选型手册很容易忽略。这是我第一个要强调的认知点F407要把USB跑上480Mbps外部PHY是必需品不是可选项。1.2 ULPI接口控制器和PHY之间的高速公路控制器和外部PHY之间怎么通信答案是ULPIUTMI Low Pin Interface。这里需要稍微讲点背景。USB的物理层处理的是DP/DM这对差分线上的模拟信号同时要负责高速握手、位填充、NRZI编解码、时钟恢复、挂起唤醒这些脏活累活。如果让控制器直接处理这些模拟信号引脚会非常多布线也痛苦。UTMI标准定义了控制器和PHY之间的完整接口但原本的UTMI接口信号太多不适合集成到MCU上于是就有了ULPI这个精简版。ULPI把UTMI接口压缩成8根双向数据线D[7:0]加上4根控制线CLK60MHz时钟、DIR数据方向指示、NXT节流信号、STP停止信号。PHY负责把所有USB物理层的收发工作转成8位并行的ULPI数据控制器通过读写PHY内部的寄存器来配置工作模式。STM32F407的OTG_HS控制器原生支持ULPI所以F407 外部PHY ULPI接口就是一套典型的高速USB方案。1.3 为什么选USB3320而不是USB3300市面上做ULPI PHY的芯片不少Microchip原SMSC的USB3300和USB3320是用的最多的两颗。USB3300除了ULPI接口之外还带一个并行接口PIF支持非ULPI的并行模式封装更大引脚更多。USB3320则砍掉了并行接口只保留ULPI封装是QFN-32体积更小引脚更精简价格也更友好。对于STM32F407这种本身就带ULPI控制器的MCU来说USB3320是更匹配的选择。很多开发板比如正点原子探索者F407用的也是USB3300或USB3320但因为USB3300的并行接口功能在F407场景下完全是多余的选USB3320能省不少布局面积降低布线难度。如果你的项目恰好有USB3300的库存也不是不能用但要留意引脚分布和供电要求USB3300的模拟电源引脚需要额外滤波布线时多花点功夫。2. 原理图设计前的选型与规划2.1 USB3320关键特性与引脚功能梳理USB3320是Microchip推出的高速USB 2.0 PHY支持全速12Mbps和高速480Mbps收发内置PLL锁相环外部只需要一个24MHz参考时钟内部就能倍频出480Mbps所需的时钟。它同时支持OTG功能内置VBUS比较器和ID检测配合外部VBUS电源开关就能做完整的OTG主机/设备切换。拿到USB3320的数据手册引脚数量不多但每个引脚的功能要理清楚。我按功能分组梳理一下功能分组引脚方向说明ULPI数据DATA0 ~ DATA7双向8位ULPI数据总线接STM32F407对应引脚ULPI控制CLK输出60MHz参考时钟输出给STM32F407DIR输出数据方向指示NXT输出节流控制STP输入停止信号USB差分DP / DM模拟接USB连接器的D / D-OTG检测VBUS输入检测VBUS电压判断是否连接主机ID输入检测USB连接器ID引脚区分host/device供电输出CPEN输出控制外部VBUS电源开关使能时钟XI / XO输入24MHz晶振接口复位RESET_B输入低有效复位电源VDD / VDDIO输入核心电源 / I/O电源数据手册里的引脚号分布我在这里不逐个默写画图时对照手册和封装即可。但有一个关键点要提醒USB3320的VDD和VDDIO虽然都可以接3.3V但两者在PCB上要分开走各自独立去耦不能共用一个电容了事。VDD是PHY内部模拟/数字电路的电源VDDIO是ULPI接口电平转换的电源F407的IO是3.3VVDDIO也接3.3V这样ULPI接口电平才能匹配。2.2 需要占用的STM32F407引脚清单STM32F407的OTG_HS ULPI接口在芯片上映射到一组固定的引脚复用功能是AF10。画原理图时这些引脚必须手动分配到USB3320。我整理了一份标准映射核对CubeMX时也是对应的STM32F407引脚ULPI信号接到USB3320PA3ULPI_D0DATA0PA5ULPI_CKCLKPB0ULPI_D1DATA1PB1ULPI_D2DATA2PB6ULPI_NXTNXTPB7ULPI_DIRDIRPB10ULPI_D3DATA3PB11ULPI_D4DATA4PB12ULPI_D5DATA5PB13ULPI_D6DATA6PB14ULPI_D7DATA7PB15ULPI_STPSTP注意这里有一处容易搞反的地方STM32F407的PB6和PB7在AF10复用表里对应NXT和DIR。我之前画板的时候就把NXT和DIR接反过一次ULPI总线完全跑不起来。正确的接法是STM32的PB6ULPI_NXT接USB3320的NXTPB7ULPI_DIR接USB3320的DIR。两个脚接反的时候控制器和PHY之间的握手信号错乱逻辑分析仪上看数据总线有波形但枚举就是过不去。这张表里的引脚同时还会跟其他外设冲突最典型的几个PB6/PB7是I2C1PB10/PB11是I2C2PB12/PB13/PB14/PB15还和SPI2复用PA3和PA5分别是USART2和SPI1的引脚。设计时这些外设就不能再往这些引脚上放了。2.3 时钟方案24MHz参考时钟怎么给USB3320需要一个24MHz参考时钟内部PLL锁相环会把24MHz倍频到480MHz供高速收发器使用。这个24MHz时钟的精度直接影响USB高速握手能否成功USB 2.0高速模式对时钟精度要求比全速严格得多劣质晶振或者随手焊上去的谐振电容都可能让高速握手失败。时钟来源有两种常见做法第一种给USB3320单独配一颗24MHz无源晶振接XI和XO两个引脚配上两个负载电容。这是我最推荐的做法简单、独立、不依赖系统其他时钟。晶振选型时注意精度普通贴片晶振频率误差做到20ppm以内没什么问题已经足够USB高速使用。负载电容的大小按晶振的数据手册来一般18pF到22pF之间我习惯先在原理图上预留20pF焊接调试时用示波器测波形再微调。第二种从STM32F407的MCO引脚输出24MHz时钟给USB3320的XI。这个方案省一颗晶振但问题是F407的HSE通常选8MHz或25MHzMCO要精确分频出24MHz对主时钟频率和PLL配置有约束而且MCO输出的驱动能力和时钟抖动也不如专门晶振干净。除非是引脚极度紧张否则我不建议为了省一颗晶振在USB时钟上冒险。还有个容易踩的坑USB3320的24MHz晶振和STM32F407的HSE晶振是两个独立时钟域上电后没有同步关系这正常不需要做任何处理。有些同学担心两个晶振会不会互相干扰只要在PCB布局上把两颗晶振拉开距离不要靠近放完全没问题。2.4 电源网络3.3V vs 1.8V去耦怎么布置USB3320的供电看起来简单但细节不少。VDD和VDDIO都接3.3V是最省事的接法但要注意几点。电源入口处我习惯放一个磁珠把USB3320的供电和板子上其他数字电路分隔开避免USB数据线上的噪声串到其他芯片也避免数字电路的高频噪声反灌进PHY。磁珠选600Ω100MHz的就够后面跟一个10uF钽电容加几个100nF陶瓷电容。每个电源引脚旁边都要放一个100nF的MLCC去耦电容这个电容要尽可能地靠近引脚过孔到电容再到引脚的距离越短越好。如果USB3320有多个VDD或VDDIO引脚每个引脚都要单独配电容不能图省事只放一个。去耦电容的作用是在高频瞬间电流需求时提供一个低阻抗回路摆放位置不对就等于白放。3. 原理图连接全解析从ULPI到USB连接器3.1 ULPI数据/控制信号连接原理图上ULPI部分的连接非常直观就是把STM32F407的ULPI引脚按前文对照表接到USB3320的对应引脚。这部分唯一需要注意的就是NXT/DIR别接反、数据线别接错、STP别漏接。实际画图时建议把D0到D7这8根线在网络标号上就体现出来比如“ULPI_D0”“ULPI_D1”这样PCB阶段布线时能快速核对顺序出网表也不容易错位。控制信号用“ULPI_CLK”“ULPI_NXT”“ULPI_DIR”“ULPI_STP”类似命名一眼就能看出电气连接关系。CLK这根线要特别重视。USB3320的CLK是60MHz时钟输出作为ULPI总线的同步时钟它的质量决定了ULPI通信的稳定性。原理图上它只是一根普通连线但在PCB布局时CLK到STM32F407的距离要尽可能短中间不要打过孔不要穿过其他时钟信号或电源转换区域。3.2 DP/DM差分对的连接与端接DP/DM这对走线从USB3320出来直接连到USB连接器的D/D-。USB3320内部已经集成了高速模式所需的45欧姆驱动端接和全速模式所需的上拉/下拉电阻所以外部不需要再加任何并联电阻也不需要在DP上额外加上拉。关于串联电阻这是一个被问过很多次的问题。USB3320的数据手册和Microchip的参考设计里DP/DM上并没有串联电阻直接连连接器即可。不过实际项目中很多人在DP/DM上各串一颗22欧姆或33欧姆电阻用来调试和抑制过冲。我的经验是加不加都能工作但如果你信号完整性功底一般干脆别加直接直连。串了电阻反而可能引起高速信号反射让眼图变差到时候排查起来更玄学。DP/DM和连接器之间我强烈建议加一颗ESD保护器件比如ST的USBLC6-2这类的低电容TVS阵列。USB连接器是暴露在外的接口热插拔和静电冲击都是常态。ESD器件要选结电容小于1pF的型号普通TVS的结电容动辄几十pF串在DP/DM上会把高速信号废掉。这颗保护器件在PCB上要放在靠近连接器的地方让静电先打到ESD器件上再由它泄放到地而不是先经过手机芯片。3.3 OTG功能VBUS控制、ID检测、电源开关OTG的核心在于“一个接口既能做主机又能做外设”。硬件上需要三个能力检测VBUS、识别ID、控制VBUS供电。USB3320已经把前两个检测能力内置了剩下VBUS供电需要外部电路来实现。USB3320的VBUS引脚直接接USB连接器的VBUS信号内部有比较器用来判断VBUS电压是否有效。当USB设备插入主机时主机的VBUS会给到5VUSB3320检测到这个电压就知道自己是外设角色。当外部设备插入到我们的USB口时VBUS由我们自己的电源管理电路供出USB3320同样能检测到。ID引脚的逻辑类似连接器ID接地表示A设备主机ID悬空表示B设备外设USB3320把ID状态通过ULPI寄存器报告给STM32。VBUS供电控制是OTG硬件里最需要动脑的部分。作为主机给外部设备供电时VBUS要能输出5V/不小于500mA的电流这个电流不能直接从STM32的IO口或USB3320上取必须用一颗电源开关芯片。常用的有TPS2051、MIC2026这种单通道限流开关也可以用分立MOS管方案但要注意驱动电压和导通电阻。电源开关的控制信号可以接USB3320的CPEN引脚也可以接STM32的一个GPIO。CPEN是PHY内部OTG状态机产生的输出当检测到需要作主机时自动拉高。但实际用下来我更喜欢用一个普通GPIO直接控制开关软件想什么时候开就什么时候开灵活性更高。原理图上把GPIO和开关使能引脚之间预留一颗0欧姆电阻的连接选项CPEN也连到这颗电阻的一侧调试时可以根据需要选择控制源。3.4 复位与上电时序设计USB3320的RESET_B是低有效复位输入在上电后需要一个有效的低电平脉冲宽度至少几微秒然后释放PHY才能正确初始化内部状态机。如果复位时序不满足PHY可能进入异常状态ULPI枚举就过不去。复位电路最简单的方式是RC复位一个10k欧姆电阻上拉到3.3V接一个100nF电容到地中间节点接RESET_B。在上电瞬间电容充电产生低电平脉冲时间常数约1ms足够覆盖USB3320的复位要求。用RC复位的好处是零成本、零代码缺点是软件无法再次触发复位。如果希望软件能复位PHY就把RESET_B同时接一个GPIO通过10k欧姆电阻隔离避免GPIO输出和RC电路打架软件拉低GPIO就能重新复位PHY。我自己的板子是RC复位加GPIO复位双保险。RC电路保证上电自动复位GPIO留着以后调试用总线卡死的时候不用重新断电就能把PHY拉回来。4. PCB布局布线硬件设计成败的关键一步4.1 DP/DM90欧姆差分阻抗与长度匹配原理图画完PCB才是真正见功夫的地方。USB 2.0高速信号的比特率是480Mbps虽然是差分信号但信号上升沿非常快对走线的阻抗和长度匹配有明确要求。DP/DM的差分阻抗要求90欧姆误差尽量控制在正负10%以内。布线时需要把DP和DM作为差分对在PCB软件里设置为差分走线宽度和间距由叠层和阻抗工具计算得出。两层板的话常见的走线宽度和间距组合大约是8mil线宽配8mil间距但具体数字必须根据板厂提供的叠层参数来算不能照抄别人的。四层板因为有完整参考平面阻抗控制更容易做高速USB的板子我基本都推荐四层板起步。长度匹配方面DP和DM的信号线长度差要尽量控制在5mil以内。虽然USB 2.0对差分对内skew容忍度不算太苛刻但既然做高速设计匹配尽量做好。差分对内部不要在中间过孔整个DP/DM路径不要有桩线。如果DP/DM上接了ESD器件要注意ESD器件的两个焊盘会在差分线上引入残桩所以ESD器件的位置要放得特别靠近连接器让残桩尽量短。4.2 ULPI总线布线比想象中更敏感ULPI看似是数字接口实际上60MHz时钟加上8根双向数据线信号完整性问题一点也不比模拟差分线少。ULPI的一个关键要求是CLK到各数据线的时序关系时钟上升沿采样数据如果时钟线和数据线的长度差太大采样就会出错万枚举失败就“玄学”了。布线时我给自己定的规矩是CLK线尽量短优先走不要绕线D0~D7和STP、NXT、DIR这些信号与CLK的长度差控制在2厘米以内至少保证同一批次布线的信号组长度差别不要太大。如果实在有信号线需要绕线匹配优先绕短的信号线不要去绕CLK。另外ULPI总线不要跨过PCB上的分割地平面所有ULPI信号要有连续的参考地平面。很多两层板上因为走线拥挤不得已把ULPI信号从电源区域绕过去结果数据总线在接收端出现毛刺调试起来非常痛苦。如果条件允许ULPI信号底下铺完整的地铜皮不要有缝隙。4.3 地平面与去耦电容布局高速USB的板子地平面连续性比走线美观重要得多。USB3320底下的地焊盘要打过孔阵列连接到主地平面每个去耦电容的地端也要就近打过孔缩短回流路径。USB连接器的外壳地要用小电阻或者直接用铜皮连接到系统地具体接法取决于产品设计但不要让USB的外壳地悬空。去耦电容的位置我在原理图部分提过这里再强调一遍100nF去耦电容距离对应电源引脚不要超过2mm中间不要有其他走线穿过。如果USB3320的多个电源引脚分布在不同角落每个都要独立去耦不能指望一个电容照顾两个引脚。VDD和VDDIO的去耦电容要分别放在各自引脚旁边同时两个电源网络之间用磁珠或0欧姆电阻隔离。4.4 ESD保护器件的摆放位置ESD器件的位置其实是PCB设计里最容易犯的错。很多人把ESD器件放在PHY芯片旁边觉得这样离芯片近、保护效果好这恰恰是反的。ESD保护的原则是瞬态能量应该在进入PCB的入口处就被泄放掉而不是等它跑到芯片边上再拦截。所以USBLC6-2这类ESD保护器件必须放在USB连接器的焊盘旁边最好连接器焊盘出来先经过ESD器件再走差分线到USB3320。这样ESD器件的接地过孔也能在连接器附近直接打到地平面形成最短泄放路径。同时差分线的ESD器件本身带来的残桩就非常短对高速信号的影响也最小。5. 上电调试真正告别“玄学”5.1 硬件上电检查清单板子焊好上电调试之前先按这个顺序过一遍能过滤掉大部分硬件问题。第一步目视检查焊接质量。检查USB3320周围的引脚有没有连锡、虚焊、元件贴反。QFN-32封装的引脚在芯片底部焊接后最好用X-ray或者放大镜观察有条件就做一下引脚对地短路测试确认没有电源对地短路再上电。第二步量电源。上电后用万用表量USB3320的VDD和VDDIO电压是不是3.3V电流是否在正常范围。如果电流异常大大概率是焊接有短路立刻断电检查。这一步花不了两分钟但能避免后面积压一堆问题。第三步量时钟。用示波器探头接到XTAL的两个引脚或者USB3320的CLK输出引脚确认24MHz晶振起振CLK输出为60MHz。没有示波器的话用频率计也行。CLK输出正常说明PHY的电源和晶振都OK高速USB的底层基础有了。第四步量复位。确认上电后RESET_B信号有过低电平脉冲然后用示波器看最终复位释放后的高电平是否稳定。如果复位被某个下拉电阻拉低PHY一直处于复位状态ULPI接口就不会有任何反应。5.2 枚举失败和高速握手的排查流程如果硬件基础检查都过了插上USB线电脑还是提示无法识别那就要看USB协议层面的握手了。USB 2.0的高速握手过程大概是这样的设备插入后主机会先发一个复位信号SE0状态设备在复位期间需要切换高速模式。设备通过把D上的上拉电阻从1.5k欧姆切换为高速电流源发送一个K状态chirp K主机检测到chirp K后会回复KJ的交替信号chirp KJ来确认。设备看到主机的KJ chirp后才正式切换到480Mbps高速模式。这个握手过程只有毫秒级别任何一环出问题都会导致降级到全速或者干脆枚举失败。排查时用USB分析仪效果最好能看到握手细节。没有分析仪的话先用示波器抓D或D-上的波形看设备插入后D上有没有持续的K chirp信号。如果看不到chirp问题通常在PHY没正确初始化或者时钟不稳定。软件上要注意一点STM32F407使用外部PHY时HAL库初始化OTG_HS的流程和内置PHY不一样CubeMX配置时要选“USB_OTG_HS ULPI”模式而不是“USB_OTG_HS Internal PHY”。内部PHY和外部PHY的初始化路径、寄存器操作都不同配置错了软件层面就跑不通硬件再对也没用。5.3 从实际调试中总结的几个经验最后分享几个反复踩过之后才总结出来的经验希望对正在做同类项目的朋友有帮助。经验一DP/DM的阻抗匹配别应付。有一次板子在实验室工作正常拿到客户现场就出现设备偶发掉线查了很久发现是USB走线阻抗偏了导致长线缆下信号劣化严重。USB信号质量这种东西平时不显山露水一旦线缆变长或者环境干扰变大问题就集中爆发。做高速USB的板子能按90欧姆差分阻抗认真做就别偷懒。经验二晶振不要图便宜。USB3320对24MHz参考时钟的精度和抖动要求并不宽松。便宜的晶振常温下可能能跑温度一变或者批量生产时个体差异就暴露了。遇见“这块板子能识别那块板子不能识别”这种最折磨人的现象优先怀疑晶振批次问题。经验三给软件留一个PHY复位引脚。很多硬件工程师觉得RC复位够用就完了实际上软件调了半天怀疑PHY状态异常却无法单独复位PHY只能整体断电重来非常耽误时间。预留一个GPIO到RESET_B就等于给软件一条生路。经验四ESD器件一定要选低电容。别为了省几毛钱选一颗普通TVS装在USB数据线上。普通TVS的电容对高速信号的衰减是毁灭性的插上电脑识别成全速设备还算运气好直接不识别也完全正常。经验五调试时把D/D-上的串阻预留位画出来。虽然我前面说不加串阻也能工作但预留0欧姆电阻的位置调试时遇到信号过冲或振铃可以快速尝试改善不用重新打板。前期多花一秒钟放两个封装后期可能省下几天的调试时间。USB高速调试这件事本质上就是一个信号完整性和时序问题只要原理图上的电气连接正确、PCB上的阻抗和长度匹配到位上电后按检查清单一步步验证绝大多数“玄学”都是可以被预测和规避的。希望这篇硬件指南能让你在画STM32F407的高速USB板子时少走几个弯路。