1. 背景
由于项需求,在STM32F072中需实现5个CDC设备,折腾了很久分享出来,希望能帮助别人少踩一些坑.USB2.0全速,该款单片机支持8个输出和8个输入端点
2.USB CDC设备
2.1 它是什么?需要使用到什么?
它是USB设备类型的一种,如U盘插入电脑时,电脑会知道其是U盘,是一个存储设备,那么它就属于USB MCU存储设备。USB协议中对设备进行了分类.它在stm32上叫虚拟串口设备,当将其链接电脑后,可以把它当成串口使用,如使用windows的串口工具打开它,设置波特率等等,这是我的理解。
它需要两个接口,三个端点
InterFace 0:第一个接口,其包括一个端点,和Functional_Destriptcrs,该端点为控制接口(输入型端点(IN)),Functional_Destriptcrs则是一些描述符。先不管这个
InterFace 1:第二接口,其包括两个端点,endpoint In 和endpoint out端点,IN为stm32数据输出端点,OUT为stm32数据输入端点,随便提下,在STM32 HAL库中,USB的IN,OUT是相对于主机而言的,如:上诉的IN是指主机的输入,主机的输入(IN),对于设备来说就是OUT,数据的输出端点,IN OUT都是相对于主机而言
由此可见,正常情况下,一个CDC需要三个端点,其中两个IN端点,一个OUT端点
3.配置过程
3.1 配置流程
在STM32CubeIDE的帮助下,生成一个CDC的代码,这里没什么坑,点几下就成功了,注意的是可能需要将Heap设置大一点
修改设备描述符
分配端点和修改配置描述符
分配PMA端点缓存地址
修改HAL库关于CDC部分函数接口的参数,以适配多CDC设备的情况
3.2 使用STM32CubeIDE生成一个CDC程序的代码
根据下面的文件操作即可,文件会介绍USBCDC的知识,在PDF的最后会说怎么使用cubeIDE配置,很简单没什么坑(注意的是可能需要将Heap设置大一点) USB CDC类入门培训.pdf
3.3 分配端点和修改配置描述符
此时问题来了,CDC要求3个端点,其中2个输入1个输出,而stm32F072只支持8个输入端点,8个输出端点,2x5>8,正常情况下是不够的,这里就需要将IN端口中的控制端口省略,也就是第一幅图中的Interface 0中的endpoint IN端点,不分配有效端点给它,在本款单片机中IN端点的有效范围(0x80-0x87),OUT(0x00-0x08)
#define CDC_IN_EP 0x81U /* CDC*/
#define CDC_OUT_EP 0x01U
#define CDC_CMD_EP 0x88U //无效端点
#define CDC_IN_EP1 0x82U /* CDC1*/
#define CDC_OUT_EP1 0x02U
#define CDC_CMD_EP1 0x89U //无效端点
#define CDC_IN_EP2 0x83U /* CDC2*/
#define CDC_OUT_EP2 0x03U
#define CDC_CMD_EP2 0x8AU //无效端点
#define CDC_IN_EP3 0x84U /* CDC3*/
#define CDC_OUT_EP3 0x04U
#define CDC_CMD_EP3 0x8CU //无效端点
#define CDC_IN_EP4 0x85U /* CDC4*/
#define CDC_OUT_EP4 0x05U
#define CDC_CMD_EP4 0x8BU //无效端点
修改配置描述符号,这里面的内容就很多了,里面涉及到USB方方面面的属性和参数,其中USB_CDC_CONFIG_DESC_SIZ是该结构体的大小,记得修改,或者直接改为最大255。
配置描述符的结构如下:
配置描述符
{
配置描述符总概括(相当于预览:9字节)
IAD描述符(标识接下来的接口属于一个设备,一个设备就一个IAD描述符)CDC
{
接口描述符1
{
其他描述符(ACM等)
端点描述符(控制端点)
}
接口描述符2
{
端点描述符(IN)
端点描述符(OUT)
}
}
IAD描述符(标识接下来的接口属于一个设备,一个设备就一个IAD描述符)CDC1
{
接口描述符1
{
其他描述符(ACM等)
端点描述符(控制端点)
}
接口描述符2
{
端点描述符(IN)
端点描述符(OUT)
}
}
IAD描述符(标识接下来的接口属于一个设备,一个设备就一个IAD描述符)CDC2
{
接口描述符1
{
其他描述符(ACM等)
端点描述符(控制端点)
}
接口描述符2
{
端点描述符(IN)
端点描述符(OUT)
}
}
IAD描述符(标识接下来的接口属于一个设备,一个设备就一个IAD描述符)CDC3
{
接口描述符1
{
其他描述符(ACM等)
端点描述符(控制端点)
}
接口描述符2
{
端点描述符(IN)
端点描述符(OUT)
}
}
IAD描述符(标识接下来的接口属于一个设备,一个设备就一个IAD描述符)CDC4
{
接口描述符1
{
其他描述符(ACM等)
端点描述符(控制端点)
}
接口描述符2
{
端点描述符(IN)
端点描述符(OUT)
}
}
}
配置描述符如下,下面有些字段需要修改的,都用casojie标记了,CTRL+F搜索casojie就可以方便显示;
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
{
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
0x00,
0x0A, /* bNumInterfaces: 10 interface *///总接口大小,5个CDC*2=10=0x0A casojie
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */
/*------------------------CDC0--------------------------------------------------8+9+5+5+7+9+7+7-*/
// // // IAD Interface Association Descriptor //IAD描述符需要添加 casojie
// 0x08, // bLength: Interface Descriptor size //标识IAD描述符的长度,基本都是8,casojie
// 0x0B, // bDescriptorType: IAD //不用管
// 0x00, // bFirstInterface //第一个接口的序号
// 0x02, // bInterfaceCount //本IDA的接口数量
// 0x02, // bFunctionClass: CDC //表明该IAD是一个CDC设备
// 0x02, // bFunctionSubClass //不用管
// 0x01, // bFunctionProtocol //控制协议等其他我也不懂,默认就行
// 0x02, // iFunction
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */ //接口编号,从0开始 casojie
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */ //接口内有多少个端点被使用 1个 casojie
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
// /*Header Functional Descriptor*/
// 0x05, /* bLength: Endpoint Descriptor size */
// 0x24, /* bDescriptorType: CS_INTERFACE */
// 0x00, /* bDescriptorSubtype: Header Func Desc */
// 0x10, /* bcdCDC: spec release number */
// 0x01,
// /*Call Management Functional Descriptor*/
// 0x05, /* bFunctionLength */
// 0x24, /* bDescriptorType: CS_INTERFACE */
// 0x01, /* bDescriptorSubtype: Call Management Func Desc */
// 0x00, /* bmCapabilities: D0+D1 */
// 0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x0F, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */ //联合描述符,与IAD功能类似,标识哪两个接口是属于一个设备的casojie
0x01, /* bSlaveInterface0: Data Class Interface */ //与上面一样,上面是0,这里是1,标识0号,1号接口是属于一个CDC设备的 casojie
/*Endpoint 2 Descriptor*/
上一篇:STM32的单脉冲模式实现精确个数脉冲
下一篇:stm32中断学习篇(1)——以定时器为例
推荐阅读最新更新时间:2024-11-13 17:58
设计资源 培训 开发板 精华推荐
- EVAL-ADG904EBZ,用于有源天线的单个 4:1 模拟多路复用器的评估板
- BTS 118D智能低边电源开关典型应用电路
- EVAL-AD7771FMCZ,用于评估 AD7771 8 通道、24 位、同步采样、带功率调节的 Sigma-Delta ADC 的评估板
- LT1171CQ、用于离线应用的 2.5A 驱动高压 FET 的典型应用
- 具有高调光比和 LED 开路报告的 LT3756EUD 降压模式 1A LED 驱动器的典型应用电路
- SI5316-EVB,使用 SI5316 19 至 710 MHz 时钟发生器的评估板
- LTM4601HV 的典型应用 - 具有 PLL、输出跟踪和裕度的 12A 28VIN DC/DC 模块稳压器
- 压力检测|压力传感器显示模块
- AM2G-2405DZ ±5V 2 瓦 DC/DC 转换器的典型应用
- 【征集令】ESP8266小游戏机
- 厦门警务机器人开始运行 为新时代智慧警务插上5G的翅膀
- TINECO添可突然闪现进视线,11.11大卖13万台
- 从末端配送到全场景赋能 坎德拉科技举办2020新品发布
- 李小龙:华为 Mate 40/Pro要 慎用金属保护壳
- 诺基亚2.4将于2020年11月在印度推出
- iPhone锁定屏幕键盘输入密码时或漏输,苹果在iOS 14.2修复了
- Redmi Note 9国行标准版详细参数:搭天玑800U处理器
- 诺基亚6300 4G/8000 4G详细信息解密:搭载KaiOS
- Razer推出适用于新款Xbox的两款游戏耳机:Kaira与Kaira Pro
- 苹果不忘iPhone 6等老机型:推出iOS 12.4.9正式版