欢迎光临
我们一直在努力

【学习记录】USB连接与枚举全解析:从D+/D-上拉到pyOCD烧录

【学习记录】USB连接与枚举全解析:从D+/D-上拉到pyOCD烧录

在嵌入式开发中,USB是最常用的通信接口之一。但很多工程师只知道“插上USB线就能用”,却不清楚主机是如何识别设备、判断速度、完成枚举的。本文从D+/D-上拉电阻讲起,完整拆解USB速度检测、chirp握手、枚举流程,并结合CMSIS-DAP调试器和pyOCD烧录场景,给出实战排查指南。


📌 目录

  • [一句话结论](#一 一句话结论)
  • USB速度等级与D+/D-的决定作用
  • 高速设备握手过程
  • 电脑枚举流程
  • Windows下查看速度和枚举状态
  • CMSIS-DAP / pyOCD场景补充
  • 常见故障与排查
  • 总结

  • 一、一句话结论

    USB连接后,主机先靠设备端的D+/D-上拉电阻判断“低速还是全速”;如果是高速设备,再通过chirp握手切到高速。枚举则是主机通过控制端点0读取描述符、分配地址、加载驱动,最终让设备可用。


    二、USB速度等级与D+/D-的决定作用

    USB 2.0有三种速度:

    速度速率设备端上拉典型设备
    低速 Low Speed 1.5 Mbps D- 上拉 1.5kΩ 键盘、鼠标
    全速 Full Speed 12 Mbps D+ 上拉 1.5kΩ CMSIS-DAP、HID、音频
    高速 High Speed 480 Mbps 先 D+ 上拉,握手后切高速 U盘、高速采集卡

    主机端D+/D-各有15kΩ下拉。设备插入后:

    • 若主机检测到 D-被拉高 → 低速设备;
    • 若检测到 D+被拉高 → 全速设备;
    • 若D+上拉后,主机复位期间发chirp,设备回应 → 切到高速;
    • 主机不支持高速,或设备不支持,就保持全速。

    ⚠️ 注意:高速设备不是靠D+/D-直接决定,而是“先以全速身份出现,再握手升级”。USB 3.0有独立TX/RX引脚,不靠D+/D-判断超速。

    硬件原理图检查要点:

    • D+上拉1.5kΩ(全速)或D-上拉1.5kΩ(低速)
    • 主机端15kΩ下拉(通常在Hub或主控内部)
    • 上拉电阻必须连接到3.3V(不能接5V,否则可能损坏芯片)

    三、高速设备握手过程

    高速设备的握手流程如下:

  • 设备插入,D+上拉,主机识别为全速。
  • 主机发总线复位(SE0)。
  • 主机发chirp K。
  • 设备回chirp K/J序列。
  • 双方切换高速终端,D+上拉断开。
  • 之后进入高速通信。
  • 主机

    USB设备

    主机

    USB设备

    #mermaid-svg-QYccyq6vtkbeACJa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QYccyq6vtkbeACJa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QYccyq6vtkbeACJa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QYccyq6vtkbeACJa .error-icon{fill:#552222;}#mermaid-svg-QYccyq6vtkbeACJa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QYccyq6vtkbeACJa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QYccyq6vtkbeACJa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QYccyq6vtkbeACJa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QYccyq6vtkbeACJa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QYccyq6vtkbeACJa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QYccyq6vtkbeACJa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QYccyq6vtkbeACJa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QYccyq6vtkbeACJa .marker.cross{stroke:#333333;}#mermaid-svg-QYccyq6vtkbeACJa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QYccyq6vtkbeACJa p{margin:0;}#mermaid-svg-QYccyq6vtkbeACJa .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QYccyq6vtkbeACJa text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-QYccyq6vtkbeACJa .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QYccyq6vtkbeACJa .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-QYccyq6vtkbeACJa .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-QYccyq6vtkbeACJa .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-QYccyq6vtkbeACJa #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-QYccyq6vtkbeACJa .sequenceNumber{fill:white;}#mermaid-svg-QYccyq6vtkbeACJa #sequencenumber{fill:#333;}#mermaid-svg-QYccyq6vtkbeACJa #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-QYccyq6vtkbeACJa .messageText{fill:#333;stroke:none;}#mermaid-svg-QYccyq6vtkbeACJa .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QYccyq6vtkbeACJa .labelText,#mermaid-svg-QYccyq6vtkbeACJa .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-QYccyq6vtkbeACJa .loopText,#mermaid-svg-QYccyq6vtkbeACJa .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-QYccyq6vtkbeACJa .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QYccyq6vtkbeACJa .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-QYccyq6vtkbeACJa .noteText,#mermaid-svg-QYccyq6vtkbeACJa .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-QYccyq6vtkbeACJa .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QYccyq6vtkbeACJa .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QYccyq6vtkbeACJa .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QYccyq6vtkbeACJa .actorPopupMenu{position:absolute;}#mermaid-svg-QYccyq6vtkbeACJa .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-QYccyq6vtkbeACJa .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QYccyq6vtkbeACJa .actor-man circle,#mermaid-svg-QYccyq6vtkbeACJa line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-QYccyq6vtkbeACJa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    双方切换高速终端

    进入高速通信

    D+上拉(识别为全速)

    总线复位(SE0)

    chirp K

    chirp K/J序列

    断开D+上拉

    如果这步失败,设备就停留在全速。

    💡 实战提示:CMSIS-DAP调试器绝大多数是全速12Mbps,足够烧录和调试。 不要盲目追求高速,全速对调试器来说完全够用。


    四、电脑枚举流程

    枚举就是主机“问清楚你是谁、怎么用你”的过程:

    步骤动作说明
    1 检测连接 主机看到D+/D-上拉,确认有设备
    2 端口供电 给VBUS 5V,等待稳定
    3 总线复位 设备进入默认状态,地址0,端点0
    4 读设备描述符前8字节 获取 bMaxPacketSize0
    5 分配地址 SET_ADDRESS,设备获得唯一地址
    6 读完整设备描述符 18字节,含VID、PID、类代码
    7 读配置描述符 接口、端点、供电方式
    8 读字符串描述符 厂商、产品、序列号
    9 选择配置 SET_CONFIGURATION,设备进入工作状态
    10 加载驱动 Windows根据VID/PID/类匹配HID、WinUSB、CDC等
    11 设备就绪 应用层可通信

    枚举失败常见提示:

    • “未知USB设备(设备描述符请求失败)”
    • “无法识别的USB设备”
    • 设备反复插拔声

    💡 枚举的本质:主机通过控制端点0(Endpoint 0)与设备通信,读取各种描述符,最终确定设备的身份和使用方式。


    五、Windows下查看速度和枚举状态

    方法作用
    USB Device Tree Viewer(UsbTreeView) 最直观,显示Low/Full/High Speed、VID/PID、描述符
    设备管理器 看是否识别、有无黄色感叹号
    USBView 微软官方工具,查看USB拓扑和描述符
    Wireshark + USBPcap 抓枚举包,分析控制传输
    示波器/逻辑分析仪 测D+/D-静态电平:全速D+≈3.3V,D-≈0V;低速相反

    Linux下:

    lsusb -t # 显示 480M/12M/1.5M
    dmesg | grep usb

    示波器测量方法:

    • 全速设备:D+约3.3V,D-约0V
    • 低速设备:D-约3.3V,D+约0V
    • 高速设备:静态时两者都接近0V(因为上拉已断开)

    六、CMSIS-DAP / pyOCD场景补充

    • CMSIS-DAP调试器通常是全速USB HID或WinUSB设备。
    • python -m pyocd list 能看到调试器,前提是USB枚举成功且驱动匹配。
    • 如果 pyocd list 为空,先看设备管理器:
    设备管理器状态可能原因排查方向
    有“未知USB设备” 枚举失败 查D+上拉、晶振、USB走线、供电
    有HID/WinUSB设备但pyOCD不识别 驱动或VID/PID问题 查VID/PID、CMSIS-DAP固件、驱动

    ⚠️ 芯片限制:STM32F103只有全速USB,不能跑高速;STM32F4的OTG_HS需外接ULPI PHY才能480Mbps。

    pyOCD调试流程:

    USB枚举成功 → 驱动匹配 → pyOCD识别设备 → 烧录/调试

    任何一环失败,pyOCD都会显示“找不到设备”。


    七、常见故障与排查

    现象可能原因排查方法
    电脑无反应 D+无上拉、VBUS未到、USB线只供电 测D+电压、换线
    低速被识别 D-上拉,或D+/D-接反 查原理图、测上拉位置
    未知设备 枚举失败、描述符错误、时钟不准 UsbTreeView看描述符、查晶振
    反复重连 供电不足、看门狗复位、中断阻塞 测5V/3.3V、查固件
    pyOCD找不到 驱动未装、VID/PID不对 设备管理器、换HID/WinUSB模式

    排查思路总结:

  • 先看硬件:D+/D-上拉是否正确,VBUS是否到位,晶振是否起振。
  • 再看枚举:用UsbTreeView确认是否识别为全速设备,描述符是否正常。
  • 最后看驱动:设备管理器确认驱动是否加载,pyOCD是否匹配。

  • 八、总结

    阶段核心动作关键点
    速度检测 D+/D-上拉决定低速/全速 全速D+上拉1.5kΩ,低速D-上拉1.5kΩ
    高速握手 chirp K/J序列 失败则停留在全速
    枚举 读描述符、分配地址、加载驱动 控制端点0是关键通道
    调试器 CMSIS-DAP通常是全速设备 枚举成功+驱动匹配=pyOCD可用

    一句话总结:D+/D-上拉决定低速/全速,高速靠chirp握手;电脑枚举就是读描述符、分配地址、装驱动。调试器枚举成功,pyOCD才能烧录。

    赞(0)
    未经允许不得转载:171主机测评 » 【学习记录】USB连接与枚举全解析:从D+/D-上拉到pyOCD烧录
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址