• 正文
  • 相关推荐
申请入驻 产业图谱

STM32H5 Classic‑USBH 实现 4G‑Dongle 枚举与 AT 指令通信

09/29 17:41
365
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

部分项目需要 STM32H5 作为 USB 主机,直接外接 USB 接口 4G Dongle,不经过 UART 串口,实现 AT 指令交互。使用 Classic‑USBH(传统 USB 主机中间件)开发会遇到典型现象:设备可以完成底层 USB 枚举打印 VID/PID、设备名称,但打印日志提示No registered class for this device,上层无法进行 AT 指令收发。

SIMCom A76XX 这类 4G Dongle 属于 USB 复合设备,内部包含多路 USB 接口,AT 指令工作在厂商自定义类接口,标准 CDC 类驱动无法直接匹配。本文基于 LAT1687 官方实战文档,还原工程搭建流程、现象根因、关键代码修改点、硬件注意事项、现存局限以及排错清单。

资料获取:实战经验 | LAT1687 STM32H5 Classic USB驱动USBH实现对4G dongle的枚举和AT指令通信

1. 项目背景与测试环境

1.1 业务场景

客户 STM32H5 电源管理项目,硬件已经外发海外,需求仅完成 4G Dongle 枚举 + AT 指令通信,不需要完整 TCP/IP 拨号联网功能。

1.2 软硬件环境

  1. 硬件:NUCLEO‑H563ZI 开发板、SIMCom A76XX 系列 4G USB Dongle;
  2. 软件源码仓库:stm32h5‑classic‑coremw‑apps(切换 USB‑Host 分支下载);
  3. HAL 驱动版本:STM32Cube_FW_H5_V1.5.0;
  4. USB Host 中间件:stm32‑mw‑usb‑host‑master.zip,需要单独从 middleware 分支获取;
  5. 编译器:IAR。

注意:下载的示例压缩包 Drivers、Middlewares 文件夹为空,必须手动复制对应版本 HAL 驱动和 USB‑Host 中间件源码到工程目录,编译才能通过。

1.3 开发板硬件跳线要求

NUCLEO‑H563ZI 做 USB Host 输出 VBUS 给 Dongle 供电: PWR SEL跳线帽需要短接 STLK 与 USB‑USER;供电正常板载LD7绿灯点亮,使用 USB 转接线连接 4G Dongle。

2. 初始现象分析:枚举成功但类注册失败

烧录原版 CDC‑Standalone 示例工程,插入 4G Dongle,串口日志输出:

USB Host library started.
Starting CDC Application
Connect your CDC Device
USB Device Connected
USB Device Reset Completed
PID:9011h  VID:1e0eh Address (#1) assigned.
Manufacturer : SIMCom Wireless Solution
Product:A76XX Series LTE Module
Serial Number :200806006809080000
Enumeration done
This device has only 1 configuration.
Default configuration set.
No registered class for this device.

现象拆解:

  1. USB 底层枚举流程完全正常:复位、分配 USB 地址、读取设备描述符、配置描述符全部成功;
  2. 报错No registered class for this device:Classic‑USBH 主机栈遍历注册的 USB 类,没有匹配到 Dongle 用于 AT 通信的接口。

硬件层面:4G Dongle 为高速 HS 设备,但 STM32H5 Classic‑USBH 仅支持全速 FS,总线握手后自动降速到全速 FS,调试需要读取Other‑Speed Configuration Descriptor(其他速度配置描述符),不能读取高速模式描述符。

3. 4G Dongle 复合设备接口解析

测试使用的 SIMCom A76XX Dongle 属于 USB 复合设备,一共 5 个 USB 接口(bInterfaceNumber 0~4):

接口编号 类型说明 端点资源
#0 Remote NDIS 网络接口 Interrupt IN 0x87
#1 Bulk 数据接口 Bulk IN 0x83,Bulk OUT 0x0C
#2 Diagnostics 诊断接口 Bulk IN 0x82,Bulk OUT 0x0B
#4 AT 指令通信接口 Interrupt IN 0x89,Bulk IN 0x86,Bulk OUT 0x0F
#5 HS‑USB Modem 接口 Interrupt IN 0x88,Bulk IN 0x81,Bulk OUT 0x0A

本次目标:选用bInterfaceNumber = 4接口执行 AT 指令交互;该接口 bInterfaceClass 为 0xFF(厂商自定义类),不属于标准 CDC‑ACM (0x02),原版 Classic‑USBH 的 CDC 驱动默认只能识别 0x02 类,因此报没有注册类。

4. 关键代码修改点

文档方案为简化验证,强制指定使用 bInterfaceNumber=4 的接口,产品级项目可以增加 VID/PID 匹配逻辑,支持多设备。

4.1 修改类识别宏定义(usbh_cdc.h)

将 CDC 类代码由标准 0x02 修改为厂商自定义类 0xFF:

#define COMMUNICATION_INTERFACE_CLASS_CODE 0xFFU

4.2 修改 usbh_core.c,增大支持最大接口数量

SIMCom Dongle 具备 5 个接口,需要修改最大支持接口数目,保证可以索引到数组下标 3(对应 bInterfaceNumber=4)。

注意:数组 Itf_Desc [] 下标从 0 开始,数组下标 3 等价硬件接口编号 4。

4.3 修改USBH_CDC_InterfaceInit()接口初始化函数

手动指定目标接口索引,解析该接口的 3 个端点:

  1. 中断通知 IN 端点:0x89
  2. Bulk IN 接收端点:0x86
  3. Bulk OUT 发送端点:0x0F

调用USBH_AllocPipe()分配 USB 主机 Pipe 管道,调用OpenPipe()打开各个端点,完成 AT 通信接口初始化。

完成修改之后日志输出CDC class started,代表厂商自定义接口初始化成功。

5. AT 指令收发测试与现存局限

5.1 测试手段

开发板 USER 按键作为触发源,按下之后发送AT指令; PC 端预先使用串口工具和 4G Dongle 通信,确认AT返回OK作为参照基准。

5.2 已知工程短板(文档明确指出)

示例工程没有实现接收环形缓冲区 Ring‑Buffer。接收新数据包会直接覆盖上一帧接收缓存,日志看起来只打印OK,原始发送出去的AT字符被覆盖。仅适合简单验证通信链路,不能直接拿来做量产业务代码。

5.3 正确现象

Sending data..
AT
OK

可以确认 Bulk 收发通路工作正常,AT 指令交互链路调通。

6. 工程落地实施清单

6.1 完整搭建步骤

  1. 从 GitHub 下载stm32h5‑classic‑coremw‑apps‑main.zip,切换 USB‑Host 分支;
  2. 单独下载stm32‑mw‑usb‑host‑master.zip中间件源码;
  3. 将 STM32Cube_FW_H5_V1.5.0 下 Drivers 驱动复制进工程;
  4. 将 USB‑Host 中间件复制到 Middlewares 目录;
  5. IAR 编译项目,确认零错误零警告;
  6. NUCLEO‑H563ZI 硬件设置 PWR‑SEL 跳线,提供 USB‑Host VBUS 供电;
  7. 烧录,插入 4G Dongle,确认枚举流程;
  8. 修改头文件、usbh_core.c、CDC 初始化函数,指定目标接口和端点;
  9. 按键触发发送 AT,观察串口打印应答。

6.2 高频故障排查清单

  1. 现象:设备完全无法枚举
    • 核查 NUCLEO‑H563ZI PWR‑SEL 跳线,确认 VBUS 供电,LD7 绿灯点亮;确认 USB 时钟 48MHz 配置正确。
  2. 现象:枚举成功,持续打印No registered class for this device
    • 核查COMMUNICATION_INTERFACE_CLASS_CODE已经改为 0xFF;核对最大接口数组大小,确保可以索引到 Itf_Desc [3](bInterfaceNumber=4)。
  3. 现象:类启动成功,发送 AT 无应答
    • 使用 USBlyzer 读取 Dongle 的 Other‑Speed 描述符,核对实际端点地址;不同厂商 4G Dongle 接口、端点号不一样,不能直接照搬 A76XX 端点;确认 Pipe 分配、OpenPipe 调用成功。
  4. 现象:收到应答,只有 OK,看不到 AT 回显
    • 属于示例工程设计限制,缺少接收 Ring‑Buffer,新接收数据覆盖旧缓冲区;产品开发需要自行实现环形接收缓存。
  5. 多接口风险提示 Classic‑USBH 主机栈 Pipe 硬件资源有限,如果要同时支持多个 USB 接口,必须评估可用 Pipe 数量,防止资源耗尽。

7. 小结

  1. STM32H5 Classic‑USBH 底层 USB 主机栈可以完成绝大多数 USB 设备的基础枚举,不管标准设备、复合设备、厂商自定义类设备;枚举成功不等于上层业务通信可用,需要匹配对应 USB 接口、分配 Pipe 管道。
  2. SIMCom A76XX 4G‑Dongle AT 指令运行在厂商自定义 0xFF 类接口,不是标准 CDC‑ACM;原版示例无法匹配,需要修改类识别宏,手动定位目标接口索引,解析并打开对应的 Bulk、Interrupt 端点。
  3. 参考示例仅用于链路验证,没有实现接收环形缓冲区,不能直接用于量产项目;更换其他型号 4G Dongle,必须重新读取 Other‑Speed 配置描述符,核对接口编号、端点地址。
  4. Classic‑USBH 硬件资源有限,如果同时启用多个 USB 类 / 多个接口,需要评估 USB Pipe 资源上限。该思路具备可移植性,可以迁移到其他支持 Classic‑USBH 的 STM32 系列。

8. FAQ

Q:为什么要读取 Other‑Speed 配置描述符,不能直接看高速模式描述符?

A:STM32H5 Classic‑USBH 仅支持全速 FS;4G Dongle 是 HS 设备,接入后降速运行,实际使用全速对应的 Other‑Speed 描述符。

Q:这套方案可以直接做 4G 拨号上网吗?

A:文档示例只打通 AT 指令 Bulk 通信链路,没有 RNDIS/PPP 网络协议栈,不能直接实现拨号上网。

Q:我换另外品牌 4G Dongle,直接复用这套代码行不行?

A:不行。不同厂商 Dongle 接口编号、端点地址不一样;必须使用 USB 抓包工具读取 Other‑Speed 描述符,重新确认 AT 指令对应的 bInterfaceNumber、各个端点地址。

免责声明:本文全部基于 ST 官方 LAT1687 文档,示例代码仅作为开发验证参考,量产项目需要完成环形缓存、异常重连、USB 插拔事件健壮性处理,实际项目以 ST 官方 GitHub 源码为准。

相关推荐