用USB HOST CDC类 调试 CH340 USB转串口工具

本来是想调试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:
这是我堆栈大小设置。
在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值