本来是想调试GD115模块的,结果阴差阳错调试了usb转串口工具了 (CH340)
使用CubeMX生产代码
1、时钟配置:
2、USB_OTG_FS
3、Middleware
4、生产代码:
生产的时候如遇到如下提示可以忽略(我还没找到原因。。。)
5、代码更改
硬件没有问题的话程序应该可以执行到HOST_CHECK_CLASS这里,此时设备连接检测 和枚举过程都已成功完成,设备的描述符已经都获取到了。
5.1、因为CH340的接口描述符是0XFF(厂家自定义的),与我们用的标准CDC 0x02 不一样(usb clsss 可以参考该博客 https://blog.youkuaiyun.com/u014647208/article/details/79994473);
在该处可以添加一个 宏定义
然后替换原来的代码
5.2、类初初始化函数里根据接口描述的类、子类、协议修改USBH_FindInterface函数的入口参数。
static USBH_StatusTypeDef USBH_CDC_InterfaceInit (USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_FAIL ;
uint8_t interface;
CDC_HandleTypeDef *CDC_Handle;
interface = USBH_FindInterface(phost,
USER_USB_CDC_CLASS,
DIRECT_LINE_CONTROL_MODEL,
02);
if(interface == 0xFFU) /* No Valid Interface */
{
USBH_DbgLog ("Cannot Find the interface for Communication Interface Class.", phost->pActiveClass->Name);
}
else
{
USBH_SelectInterface (phost, interface);
phost->pActiveClass->pData = (CDC_HandleTypeDef *)USBH_malloc (sizeof(CDC_HandleTypeDef));
CDC_Handle = (CDC_HandleTypeDef*) phost->pActiveClass->pData;
/*Collect the notification endpoint address and length*/
if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].bEndpointAddress & 0x80U)
{
CDC_Handle->CommItf.NotifEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->CommItf.NotifEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
/*Allocate the length for host channel number in*/
CDC_Handle->CommItf.NotifPipe = USBH_AllocPipe(phost, CDC_Handle->CommItf.NotifEp);
/* Open pipe for Notification endpoint */
USBH_OpenPipe (phost,
CDC_Handle->CommItf.NotifPipe,
CDC_Handle->CommItf.NotifEp,
phost->device.address,
phost->device.speed,
USB_EP_TYPE_INTR,
CDC_Handle->CommItf.NotifEpSize);
USBH_LL_SetToggle (phost, CDC_Handle->CommItf.NotifPipe, 0U);
// interface = USBH_FindInterface(phost,
// DATA_INTERFACE_CLASS_CODE,
// RESERVED,
// NO_CLASS_SPECIFIC_PROTOCOL_CODE);
interface = USBH_FindInterface(phost,
USER_USB_CDC_CLASS,
DIRECT_LINE_CONTROL_MODEL,
02);
if(interface == 0xFFU) /* No Valid Interface */
{
USBH_DbgLog (“Cannot Find the interface for Data Interface Class.”, phost->pActiveClass->Name);
}
else
{
/Collect the class specific endpoint address and length/
if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80U)
{
CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
else
{
CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
if(phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress & 0x80U)
{
CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress;
CDC_Handle->DataItf.InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
else
{
CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress;
CDC_Handle->DataItf.OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
/*Allocate the length for host channel number out*/
CDC_Handle->DataItf.OutPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.OutEp);
/*Allocate the length for host channel number in*/
CDC_Handle->DataItf.InPipe = USBH_AllocPipe(phost, CDC_Handle->DataItf.InEp);
/* Open channel for OUT endpoint */
USBH_OpenPipe (phost,
CDC_Handle->DataItf.OutPipe,
CDC_Handle->DataItf.OutEp,
phost->device.address,
phost->device.speed,
USB_EP_TYPE_BULK,
CDC_Handle->DataItf.OutEpSize);
/* Open channel for IN endpoint */
USBH_OpenPipe (phost,
CDC_Handle->DataItf.InPipe,
CDC_Handle->DataItf.InEp,
phost->device.address,
phost->device.speed,
USB_EP_TYPE_BULK,
CDC_Handle->DataItf.InEpSize);
CDC_Handle->state = CDC_IDLE_STATE;
USBH_LL_SetToggle (phost, CDC_Handle->DataItf.OutPipe, 0U);
USBH_LL_SetToggle (phost, CDC_Handle->DataItf.InPipe, 0U);
status = USBH_OK;
}
}
return status;
}
5.3、进入HOST_CLASS_REQUEST阶段后,需要修改以下代码,我在这里卡很久。。。。,原函数里是GetLineCoding,不过每次返回值都不成功(USBH_BUSY或 USBH_NOT_SUPPORTED),直接 status = USBH_OK 此时也可正常收发数据,只是不可以更改波特率(波特率是19200)。 后来和ch340厂家沟通了下 需要发送一组数据过去。这组数据我是在SetLineCoding函数里更改的,偶尔能返回USBH_OK,大部分情况还是返回不正确。。。。
static USBH_StatusTypeDef USBH_CDC_ClassRequest (USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status = USBH_FAIL ;
CDC_HandleTypeDef CDC_Handle = (CDC_HandleTypeDef) phost->pActiveClass->pData;
/*Issue the get line coding request*/
// status = GetLineCoding(phost, &CDC_Handle->LineCoding);
status = SetLineCoding(phost, &CDC_Handle->LineCoding);
status = USBH_OK;
if(status == USBH_OK)
{
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
return status;
}
5.4 设置波特率
5.5添加发送、接收函数:在这里插入图片描述
6、通信成功
我用了两个sub转串口工具,一个接STM32L475 一个接电脑 再把两个连接下
7、总结
可能是我的PCB问题 我usb接口是通过飞线连接到板子上的,导致SetLineCoding函数返回失败。如有大佬知道原因请告知下。
ps:
这是我堆栈大小设置。