# usb_device **Repository Path**: daizia/usb_device ## Basic Information - **Project Name**: usb_device - **Description**: usb device学习 通过stm32f407ZGt6 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-26 - **Last Updated**: 2025-03-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 📌 简介基于STM32F407ZGT6野火霸天虎V2.0 ```bash OTG一共5根线 D+(DP) D-(DM) VBUS GND 还有一个ID线,配置成悬空为device模式 配置为低电平,为HOST模式 OTG控制器集成在CPU上,需要提供PLL时钟48M 低功耗模式唤醒方法 主机唤醒:当D+、D-有数据时会触发中断,唤醒设备 主动唤醒:Remote Wakeup设备通过拉高 DP 线,主动向主机请求唤醒 USE_USBD_COMPOSITE:是否支持复合设备 Class(类) 代表 USB 设备的设备类型,即它属于哪种设备 IN方向: 发送给主机 out方向:主机发出 ``` ### 📌 STM32 USB 驱动架构 ```bash HAL 层(硬件抽象层) 主要包含 usb_core.c,负责控制器初始化、端点配置等。 USBD 层(USB 设备协议层) 负责处理 USB 设备类协议(HID、CDC、MSC 等)。 Class 层(具体 USB 设备类) 例如 usbd_hid.c 负责 HID 设备的数据处理。 ``` ### 代码分析流程 ```bash USB 设备初始化(USBD_Init()) → 设备如何注册? 设备描述符(usbd_desc.c) → 设备如何被识别? 数据发送(USBD_HID_SendReport()) → 如何向 PC 发送数据? 数据接收(HID_OutEvent()) → 如何从 PC 接收数据? ``` ### 📌 核心配置 ```c /* Init Device Library 数据结构和硬件初始化*/ USBD_Init(&USBD_Device, &HID_Desc, 0); /* Add Supported Class 将 USB 设备类(Class)注册到 USB 设备堆栈 */ USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS); /* Start Device Process 通过配置USB控制器的寄存器,使能USB device功能*/ USBD_Start(&USBD_Device); //之后就会在OTG_FS_IRQHandler()中断响应函数中处理,等待枚举 ``` ### 📌 中断处理函数 | **中断函数** | **触发事件** | **作用** | | ------------------------------------------------------------ | ------------------------------ | ---------------------------------------------------- | | `OTG_FS_IRQHandler()` | USB 设备所有核心事件 | 处理连接、断开、枚举、数据传输、挂起恢复,错误处理等 | | `OTG_FS_WKUP_IRQHandler()` | USB 低功耗唤醒 | 从 Suspend 模式恢复 | | `OTG_FS_EP1_OUT_IRQHandler()` / `OTG_FS_EP1_IN_IRQHandler()` | USB 端点传输(仅部分型号支持) | 用于优化大数据传输 | **通常你只需要关心 `OTG_FS_IRQHandler()`**,它已经包含了大部分 USB 事件处理。 ## **📌 FIFO** | FIFO 类型 | 作用 | 设备模式 | 主机模式 | | --------- | ---------- | ------------------------------------------------------------ | --------------------------------------------------------- | | TX FIFO | 发送缓冲区 | **每个 IN 端点有自己的 TX FIFO**,用于存放要发往主机的数据, **当 MCU 将数据写入 TX FIFO 时,USB 控制器会按照协议发送数据到主机**。 | **所有 OUT 端点共享一个 TX FIFO**,用于存放主机发送的数据 | | RX FIFO | 接收缓冲区 | **所有 OUT 端点共用一个 RX FIFO**,存储从主机发来的根据协议解析完的数据 | **存储从 USB 设备发送来的数据** | ## **各类回调函数** 了解即可,PCD库提供,只需要在conf.c中添加对应的即可 | 回调 ID | 触发事件 | 默认回调 | | ----------------------------- | --------------- | -------------------------------- | | `HAL_PCD_SETUPSTAGE_CB_ID` | 收到 `SETUP` 包 | `HAL_PCD_SetupStageCallback()` | | `HAL_PCD_DATAOUT_STAGE_CB_ID` | OUT 传输完成 | `HAL_PCD_DataOutStageCallback()` | | `HAL_PCD_DATAIN_STAGE_CB_ID` | IN 传输完成 | `HAL_PCD_DataInStageCallback()` | | `HAL_PCD_SOF_CB_ID` | Start of Frame | `HAL_PCD_SOFCallback()` | | `HAL_PCD_RESET_CB_ID` | USB 复位 | `HAL_PCD_ResetCallback()` | | `HAL_PCD_SUSPEND_CB_ID` | USB 挂起 | `HAL_PCD_SuspendCallback()` | | `HAL_PCD_RESUME_CB_ID` | USB 恢复 | `HAL_PCD_ResumeCallback()` | | `HAL_PCD_CONNECT_CB_ID` | USB 连接 | `HAL_PCD_ConnectCallback()` | | `HAL_PCD_DISCONNECT_CB_ID` | USB 断开 | `HAL_PCD_DisconnectCallback()` | ### 枚举数据收发的入口函数 USBD_LL_SetupStage() 处理 USB 设备端的 Setup 阶段请求 | **请求类别** | **bmRequestType & 0x1F** | **典型用途** | | ------------ | ------------------------ | -------------------------------------------- | | 设备请求 | `0x00` | 获取设备描述符、设置地址、选择配置等 | | 接口请求 | `0x01` | 获取/设置某个接口的状态,如 HID `GET_REPORT` | | 端点请求 | `0x02` | 控制端点的 `STALL` 状态,如 `CLEAR_FEATURE` | 此外,`bmRequestType` 的 **高 2 位**(`bmRequestType & 0x60`)决定了 **请求的类型**: - **标准请求 (0x00)**:如 `GET_DESCRIPTOR`、`SET_ADDRESS` - **类请求 (0x20)**:如 HID 设备的 `GET_REPORT` - **厂商请求 (0x40)**:自定义请求,供应商特定 ## **如何选择合适的 USB 传输方式?** | 传输类型 | 主要特点 | 适用场景 | 可靠性 | 速率保证 | 适用 USB 速度 | | ------------ | -------------------------- | -------------------------------- | -------------- | ------------ | ------------------------ | | **控制传输** | 设备管理,所有设备必须支持 | 设备枚举、配置请求 | ✅ 高 | ❌ 无 | 低速、全速、高速、超高速 | | **批量传输** | 大数据量,但可能有延迟 | U 盘、打印机、CDC 串口 | ✅ 高 | ❌ 无 | 全速、高速 | | **中断传输** | 小数据量,定期轮询 | 键盘、鼠标、HID 设备 | ✅ 高 | ✅ 有(轮询) | 低速、全速、高速 | | **等时传输** | 低延迟,固定带宽,无重传 | 音视频传输(USB 麦克风、摄像头) | ❌ 低(无重传) | ✅ 有 | 全速、高速 | ## **控制传输发送接口 ** | 函数 | 作用 | 典型使用场景 | | ---------------------------- | ---------------------------------------------------------- | ----------------------------------------------------- | | `USBD_CtlSendData()` | **启动新的控制传输** 数据阶段,发送数据 | `Get Descriptor`、HID `Get Report`、Vendor 自定义请求 | | `USBD_CtlContinueSendData()` | **继续发送数据**,适用于大于 `EP0_MAX_PKT_SIZE` 的数据传输 | 处理长数据请求,如大于 64 字节的 HID 报告描述符 | 程序员只需要调用USBD_CtlSendData() 其他传输任何传输调用接口为USBD_LL_Transmit()