CH32F103C8T6的USB开发(一)
一、背景
项目用到单片机采集模拟量数据,原先使用USB转串口,速度嫌慢,还要转串口芯片,电脑还要安装驱动,现更改为采用USB的HID类来传输。
二、单片机选型
STM32F103的USB接口简单易用,且有STM32CubeMx代码生成器,非常方便,可惜芯片越来越贵。本次转用国产替代品沁恒CH32F103C8T6,价格比51还便宜,这家做USB多年,值得尝试。
三、开发过程
(一)阅读相关资料:
1. 关于CH32F103与STM32F103在USB接口上的差异与使用
https://blog.csdn.net/CAImoontion/article/details/112565011
2.USB HID报告描述符教程
https://zhuanlan.zhihu.com/p/27568561
(二)硬件准备
沁恒原厂开发板。USB接口方面有USBHD和USBD两种,均是从芯片引脚直接引出到TYPE-C的USB座,没有任何上拉、下拉电阻。
(三)编程
1. 学习沁恒官方开发包自带的USB例程。里面没有HID相关示例。将自带的一个示例下载到板子后,电脑并没有识别出硬件,看了一下代码说明,可能需要安装相关驱动,并使用特定上位机程序才可以通信。放弃此示例。
2. 参看《关于CH32F103与STM32F103在USB接口上的差异与使用》一文,此芯片的USBD与STM32的USBD寄存器等完全兼容,于是想到,用STM32的现有成熟代码编好程序,再移植过来。
(1)使用STM32CubeMx,设置时钟树,确保USB时钟为48M,选择usb中间库,配置相关参数,生成代码。
(2)安装官方提供的器件描述文件,打开上一步骤生成的KEIL工程,在配置中更改芯片型号,添加flash算法文件,更改调试为DAP方式。
(3)设置官方DAP调试下载器。将TX和RX引脚短路,插入USB接口,蓝灯常亮,表示进入ARM模式。
(4)下载程序成功。但没有成功,电脑没有反应,未检测到USB设备。
(5)反复排查,阅读官方快速应用手册,得知:虽然此芯片内置上下拉电阻,但是上电默认是没打开的,估计这是为了彻底兼容STM32。按手册上的说法,要设置新增的寄存器。经查询,参考官方其它例程,在main函数前方代码中加入:
typedef struct { __IO uint32_t EXTEN_CTR; } EXTEN_TypeDef; #define EXTEN_BASE ((uint32_t)0x40023800) #define EXTEN ((EXTEN_TypeDef *) EXTEN_BASE) #define EXTEN_USBD_PU_EN ((uint32_t)0x00000002)
在main函数中初始化USB设备后,加入
(EXTEN->EXTEN_CTR) |= EXTEN_USBD_PU_EN;
这样就使能了内部电阻。
(6)下载程序,电脑可以发现设备,但认为是鼠标。正常,因为CUBEMx里面配置的是鼠标,需要改各种描述符。
(7)利用HID描述符生成软件DT.exe,生成joystick类型的报告描述符,仅保留油门,删除里面不需要的usage_page,只保留1个就行。
USAGE_PAGE (Generic Desktop) 05 01 LOGICAL_MINIMUM (0) 15 00 USAGE (Joystick) 09 04 COLLECTION (Application) A1 01 USAGE_PAGE (Simulation Controls) 05 02 USAGE (Throttle) 09 BB LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (255) 26 FF 00 REPORT_SIZE (8) 75 08 REPORT_COUNT (8) 95 08 INPUT (Data,Var,Abs) 81 02 END_COLLECTION C0
(8)将上述数据填入HID_MOUSE_ReportDesc,删掉原来的数据,得到
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, 0x15, 0x00, 0x09, 0x04, 0xA1, 0x01, 0x05, 0x02, 0x09, 0xBB, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x81, 0x02, 0xC0 };
编译下载,电脑可以识别,但是属性框里显示“报告描述符中找到未知项目”,说明报告描述符有问题。但仔细观察第(7)步数据,没发现问题。
联系代码上下文,发现上述数组中 HID_MOUSE_REPORT_DESC_SIZE 应该修改,否则还是之前自动生成前的数组大小,找到后修改为当前数组大小,编译下载,电脑识别成功,在【控制面板】>【设备和打印机】中找到设备,右键菜单中点击游戏控制器设置,点击属性,可以看到测试页,有油门的数据条。
(9)在单片机中继续编程,输出数据。在上位机中利用前面获取罗技方向盘的代码模块,获取应用数据。
四、后记
整个过程耗时一天,应该说还是挺顺利的。不过本次USBHD的功能没有得到测试,这个就不能通过STM32CUBEMx的方式来编程了,只能使用官方提供的函数库,这个要留待后面测试。