1. USB OTG 概述
USB OTG(On-The-Go)是 USB 协议的扩展功能,允许设备在主机(Host)和设备(Device)两种角色之间动态切换。APM32F407 支持 USB OTG,能在嵌入式设备中实现更灵活的通信功能。
OTG 的核心功能包括:
- 主机和设备角色切换:
- 通过 HNP(Host Negotiation Protocol) 协商角色。
- 双电源管理:
- 高效通信模式:
2. APM32F407 支持的 USB 模式
[td]模式 | 描述 | 应用场景 | USB 主机模式 | 主机负责控制通信,为设备分配地址、发送请求和接收数据。 | 连接鼠标、键盘、U盘、摄像头等外设 | USB 设备模式 | 设备被动响应主机请求,提供功能服务,例如数据传输或设备交互。 | 设备充当外设,如U盘、虚拟串口、音频设备 | USB OTG 模式 | 支持主机与设备角色的动态切换,通过 HNP 实现角色互换。 | 移动设备、双功能设备(如既能存储数据,又能调试通信)
|
3. USB 主模式、从模式与 OTG 模式的区别
[td]特性 | 主机模式 | 设备模式 | OTG 模式 | 角色固定性 | 固定为主机 | 固定为设备 | 动态切换主机与设备 | 电源管理 | 主机提供电源 | 接收主机电源 | 角色决定电源提供或接收 | 功能灵活性 | 固定控制功能 | 提供单一服务 | 同一设备可支持多种功能 | 典型应用场景 | 连接外设(如键盘、鼠标) | 提供服务(如虚拟串口) | 手机 OTG 数据线,用于双向传输 | 硬件要求 | 需要支持主机功能(如 USB Host) | 需要支持设备功能(如 USB Device) | 支持 ID 引脚检测与 HNP 协议 | 支持协议 | USB Host 支持的协议,如 HID、MSC | USB Device 支持的协议,如 CDC、MSC、HID | 主机和设备的所有协议 |
4. 基于 APM32F407 实现 USB OTG 功能
4.1 初始化 USB OTG
- 配置硬件引脚:
- 使用 OTG 的 D+、D- 数据引脚。
- 配置 ID 引脚,用于检测当前角色。
- 配置 VBUS 引脚,检测供电状态。
- 初始化 USB OTG 模块:
- 启用 USB OTG 硬件模块。
- 配置中断优先级,处理 OTG 请求。
4.2 检测角色并初始化协议栈
- 根据 ID 引脚状态确定初始角色:
- ID 引脚低电平(接地):配置为主机。
- ID 引脚高电平(悬空):配置为设备。
- 初始化对应的协议栈:
- 主机模式下初始化 USB Host 协议栈。
- 设备模式下初始化 USB Device 协议栈。
4.3 实现 HNP 角色切换
- 检测并处理 HNP 请求:
- 主机模式切换到设备模式时,停止 USB Host 协议栈,启动 USB Device 协议栈。
- 设备模式切换到主机模式时,停止 USB Device 协议栈,启动 USB Host 协议栈。
5. 关键代码实现
5.1 USB OTG 模式初始化
#include "Driver_USBH.h"
#include "Driver_USBD.h"
extern ARM_DRIVER_USBH Driver_USBH0;
extern ARM_DRIVER_USBD Driver_USBD0;
void USB_OTG_Init(void) {
// 检测 OTG ID 引脚状态
if (HAL_GPIO_ReadPin(OTG_ID_GPIO_Port, OTG_ID_Pin) == GPIO_PIN_RESET) {
// ID 引脚接地,配置为主机
Driver_USBH0.Initialize(USBH_Callback);
Driver_USBH0.PowerControl(ARM_POWER_FULL);
} else {
// ID 引脚悬空,配置为设备
Driver_USBD0.Initialize(USBD_Callback);
Driver_USBD0.PowerControl(ARM_POWER_FULL);
Driver_USBD0.DeviceConnect();
}
}
5.2 HNP 角色切换
void Handle_HNP_Request(void) {
if (CurrentRole == USB_ROLE_HOST && Detect_HNP_Request()) {
// 切换到设备角色
Driver_USBH0.Uninitialize();
CurrentRole = USB_ROLE_DEVICE;
Driver_USBD0.Initialize(USBD_Callback);
Driver_USBD0.PowerControl(ARM_POWER_FULL);
Driver_USBD0.DeviceConnect();
} else if (CurrentRole == USB_ROLE_DEVICE && Detect_HNP_Request()) {
// 切换到主机角色
Driver_USBD0.Uninitialize();
CurrentRole = USB_ROLE_HOST;
Driver_USBH0.Initialize(USBH_Callback);
Driver_USBH0.PowerControl(ARM_POWER_FULL);
}
}
5.3 OTG 检测中断
void OTG_IRQHandler(void) {
if (Check_ID_Pin_Change()) {
USB_OTG_Init(); // 根据角色变化重新初始化协议栈
}
if (Check_HNP_Request()) {
Handle_HNP_Request(); // 处理角色切换
}
}
6. 总结
- 主模式(Host Mode):适合外接键盘、鼠标、U盘等外设。
- 从模式(Device Mode):适合作为虚拟串口、音频设备或存储设备。
- OTG 模式(On-The-Go Mode):支持角色动态切换,适用于复杂应用场景,例如移动设备的数据交换。
APM32F407 的 USB OTG 功能通过硬件支持和协议栈实现,极大提升了 USB 通信的灵活性和功能性,广泛应用于嵌入式设备和物联网系统中。
|