3. 设备枚举失败分析:复位与速度检测
枚举失败,是USB调试里最常见的坑。我见过不少工程师,拿着示波器一脸茫然——明明D+、D-都有波形,为什么主机就是认不出设备?
说白了,枚举的第一步就是复位和速度检测。这一步要是没过,后面全是白搭。咱们今天就把这块掰开揉碎了讲清楚。
3.1 复位信号与速度检测波形
主机检测到设备插入后,会先做一件事:拉低D+和D-至少10ms。这就是复位信号(Reset)。
复位结束后,主机开始检测速度。怎么检测?看终端电阻的位置:
- 全速(FS)设备:D+线上有1.5kΩ上拉电阻
- 低速(LS)设备:D-线上有1.5kΩ上拉电阻
- 高速(HS)设备:先以FS模式启动,再通过Chirp握手切换到高速
我建议你用示波器抓一下复位后的D+、D-波形。正常情况应该是:复位结束后,D+或D-被拉高,主机检测到电平变化,就知道设备速度了。
关键波形特征:
- 复位:D+和D-同时为低,持续≥10ms
- FS设备:复位结束后D+被拉高(约3.3V)
- LS设备:复位结束后D-被拉高(约3.3V)
- HS设备:复位结束后D+先拉高(FS模式),然后主机发送Chirp K信号
我在项目中遇到过一个问题:设备插上后,主机偶尔能识别,偶尔不行。抓波形发现,复位时间只有8ms,刚好卡在临界值上。后来把复位时间改到12ms,问题就解决了。嗯,这里要注意——有些主机的时序要求比规范更严格。
3.2 速度检测失败常见原因
速度检测失败,通常逃不出这几个原因:
| 故障现象 | 可能原因 | 排查方法 |
|---|---|---|
| 复位后D+无上拉 | 终端电阻虚焊、电阻值错误 | 万用表测量D+对地电阻 |
| D+上拉电压偏低 | 上拉电阻供电不足、PCB走线过长 | 示波器测量上拉电压幅值 |
| HS设备无法握手 | Chirp信号时序异常、PHY未正确初始化 | 抓取Chirp K/J序列波形 |
| 主机反复复位 | 设备响应超时、VBUS电压跌落 | 检查VBUS电容、电源纹波 |
你想想看,如果D+上拉电阻没焊好,主机复位后根本看不到电平变化,那它就会认为总线上没有设备。我曾经排查过一个案子,折腾了两天,最后发现是1.5kΩ电阻被贴成了15kΩ——颜色环看走眼了。
注意:HS设备的Chirp握手必须在复位结束后100μs内开始。如果设备响应慢了,主机会认为它是FS设备,直接跳过高速模式。
3.3 获取描述符阶段常见错误
速度检测通过后,主机开始获取设备描述符。这一步最容易出问题的是Stall和CRC错误。
3.3.1 Stall错误
Stall,说白了就是设备对主机说“我不支持这个请求”。但很多时候,Stall是因为设备固件没处理好。
- 设备描述符请求(0x80 0x06 0x00 0x01):如果设备返回Stall,说明USB外设根本没初始化
- 配置描述符请求(0x80 0x06 0x00 0x02):Stall通常是因为描述符长度填错了
- 字符串描述符请求:Stall可能是因为语言ID不支持
我建议你在固件里加个调试打印,把主机发来的Setup包内容都打出来。这样一眼就能看出是哪个请求出了问题。
小技巧:用USB分析仪抓包时,注意看Stall包的PID。如果设备连续Stall三次,主机会认为设备不可用,直接断开连接。
3.3.2 CRC错误
CRC错误,说明数据在传输过程中被破坏了。原因通常是:
- 时钟抖动:晶振精度不够,导致位采样出错
- 信号完整性:PCB走线过长、阻抗不匹配
- 电源噪声:VBUS纹波太大,影响收发器工作
我记得有一次,客户反馈设备偶尔枚举失败。抓包发现CRC错误率高达5%。最后定位到是D+走线绕了个大圈,长度超过30cm。改板后把走线控制在15cm以内,CRC错误就消失了。
3.4 地址分配失败原因排查
主机获取描述符后,会发Set Address请求给设备分配地址。这一步失败,通常是因为:
| 错误类型 | 典型现象 | 根因分析 |
|---|---|---|
| 设备无响应 | 主机发Set Address后收不到ACK | 设备未正确解析Setup包、地址寄存器未更新 |
| 地址冲突 | 主机分配地址后,设备用新地址通信失败 | 设备固件未切换地址、PHY未重新配置 |
| 超时重试 | 主机反复发Set Address | 设备响应延迟、USB时钟不稳定 |
这里有个容易忽略的点:Set Address请求成功后,设备必须在2ms内切换到新地址。如果固件里处理得太慢,主机会认为设备没响应,重新复位总线。
我曾经踩过这个坑——固件里在Set Address处理函数中加了个延时,结果超时了。去掉延时后,地址分配就正常了。
3.5 枚举失败排查流程图
下面这张图,是我自己总结的枚举失败排查流程。每次遇到枚举问题,我都会按这个思路走一遍。
3.6 实战排查建议
最后,我分享几个实战中总结的排查建议:
我的排查工具箱:
- 示波器:抓D+、D-波形,看复位、速度检测、Chirp握手
- USB分析仪:抓协议包,看Stall、CRC错误、地址分配
- 万用表:测量终端电阻、VBUS电压、上拉电阻供电
- 调试串口:打印固件中USB中断、Setup包内容
我个人习惯,遇到枚举问题先抓波形。波形能告诉你80%的问题——是复位没到位,还是速度检测失败,还是Chirp握手没完成。剩下的20%,再用分析仪和调试串口去定位。
记住一句话:枚举失败,90%是硬件问题,10%是固件问题。先查硬件,再查固件,别搞反了。