STM32F4系列,如何实现usb host和usb device动态切换

2019-07-20 16:58发布

第一次发帖,请大家解答多谢;
STM32F4系列,如何实现usb host和usb device动态切换;
硬件设计是共用一个usb;
软件实现host和device的动态切换;
单独的host 和 device都是ok的;
而host切换到device也是好的;
device切到host不行??
请问切换需要注意什么么?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
jiafangshi
1楼-- · 2019-07-21 15:14
[mw_shl_code=c,true]
void        usb_application(void)
{
    /*host*/
    if(!usb.host_device)
    {
        USBH_Init(&USB_OTG_Core,
#ifdef USE_USB_OTG_FS
                  USB_OTG_FS_CORE_ID,
#else
                  USB_OTG_HS_CORE_ID,
#endif
                  &USB_Host,
                  &USBH_MSC_cb,
                  &USBH_USR_cb);
                                /*使能管脚,控制为Vbus管脚供电*/
                                GPIO_ResetBits(GPIOC, GPIO_Pin_9);
                                GPIOA->MODER=(GPIOA->MODER&0xfff3ffff);
                                GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,0) ;
                                /*等待电平稳定*/
                                os_dly_wait(10);
    }
    /*device*/
    else        if(usb.host_device == 1)
    {
        USBD_Init(&USB_OTG_Core,
#ifdef USE_USB_OTG_FS
                  USB_OTG_FS_CORE_ID,
#elif defined USE_USB_OTG_HS
                  USB_OTG_HS_CORE_ID,
#endif
                  &USR_desc,
                  &USBD_CDC_cb,
                  &USBD_USR_cb);               
                       
                        /*使能管脚,控制不为Vbus管脚供电*/
                        GPIO_SetBits(GPIOC, GPIO_Pin_9);
                        GPIOA->MODER=(GPIOA->MODER&0xfff3ffff)|0x00080000;
                        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ;
                        /*等待电平稳定*/
                        os_dly_wait(10);
    }
}


/*****************************************************************
** 函 数 名:    TaskUSBCommu
** 输    入:    无
** 输    出:    无
** 功能描述:    USB的通讯任务
** 作    者:
** 修改日期:    2008-09-30 15:19
****************************************************************/
__task        void TaskUSBCommu(void)
{
    OS_RESULT result;
    __IO uint32_t i = 0;
    u16 event,TaskTime=0xffff;
    u8 init_num=0;
//        u8 vcp_connect = 0;        /*表示虚拟串口线第一次插入*/
       
        /*初始化*/
        usb.connect = 0;
        usb.host_device=1;
        usb.sec_time=0;
    if((ProgUpdateStr.RTXSTCHECK&0x80000020)==0x80000020)        ProgUpdateStr.RTXSTCHECK&=0xffffffdf;
    while(1)
    {
        ClrHardDog();
                RTXTASKCheck.TaskUSBCommu_RT=0;
        result = os_evt_wait_or (0xffff, TaskTime);
        RTXTASKCheck.TaskUSBCommu_RT=0x8258;        //10分钟
                if(result==OS_R_EVT)        //有事件发生
        {
            event=os_evt_get ();        //获取事件标志
            os_evt_clr (event, tID_TaskEventManage);                //清除已取出的事件
            /*当有事件发生的时候,下面的也只执行一次即可*/
            if(event&0x0001)        //秒轮询事件
            {
                /*每次插拔U盘或者转换状态的时候,都需要重新进行一次初始化工作*/
                if((init_num == 0))
                {
                    init_num = 1;
                    usb_application();
                }
                                usb.sec_time++;                               
                                /*-------------------USB host状态------------------------------------------*/
                if(!usb.host_device)
                {
                    /*插入U盘检测U盘已经插入*/
                    if((HCD_IsDeviceConnected(&USB_OTG_Core) == 1))
                    {
                        USBStatus=1;
                        usb.connect = 1;
                            /*USB已经连接上了*/
                                                while(usb.connect == 1)
                                                {
                                                        /* Host Task handler */
                                                        USBH_Process(&USB_OTG_Core, &USB_Host);                /*USB的周期轮询任务*/
                                                        if(HCD_IsDeviceConnected(&USB_OTG_Core) == 0)        break;
                                                }
                    }
                    /*U盘已经拔出*/
                    else if((HCD_IsDeviceConnected(&USB_OTG_Core) == 0)&&(usb.connect))
                    {
                        usb.connect = 0;
                        init_num = 0;
                        USBStatus=0;
                        usb.sec_time=0;
                        usb.host_device=1;
                    }
                }
                                /*---------------------------USB vcp状态---------------------------------------*/
                else if(usb.host_device == 1)
                {
                                        /*检测到了串口线插上了*/
                                        if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9) == Bit_SET))
                                        {
                                                usb.connect = 1;                                               
                                        }
                                        /*未检出到串口线插上*/
                                        else if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9) != Bit_SET))
                                        {
                                                if(usb.connect)
                                                {
                                                        usb.connect = 0;
                                                        init_num = 0;
                                                        usb.sec_time=0;
                                                }
                                                if(usb.sec_time>30)        //未检测到串口线,且非信息输出状态
                                                {
                                                        usb.host_device=0;        //切换为host
                                                        init_num = 0;        //重新初始化
                                                        InfoOutputMode=0;
                                                }
                                        }
                }
            }
        }
        else        //超时
        {

        }
    }
}[/mw_shl_code]
jiafangshi
2楼-- · 2019-07-21 20:19
这个是我当时操作device和host切换的时候做的主函数,你可以参考一下,使用的是供电电源来区分的device和host设备,实现其进行软切换,进入到不同的设备状态,自动切换没有办法,只能自己手动的进行切换的操作,因为开发板上面缺一根USB ID线
tt朝花夕拾
3楼-- · 2019-07-21 22:48
嗯,我现在也是准备用软件手动切换;
目前的思路是在host 到device的时候,关闭host,打开device;
device到host的时候,关闭device,打开host;
现在单独关闭,打开 host或者device,功能都是正常的,可就是整合一起的时候,device到host的不行;
我最新的发现,感觉还是一些状态不对;
正常时;在host中断识别的时候,会先生成一个 Host port interrupt 再生成一个 Host channels interrupt;
而异常的时候,只有  Host port interrupt ;
请问了解么?
tt朝花夕拾
4楼-- · 2019-07-22 00:43
jiafangshi 发表于 2017-2-10 15:58
这个是我当时操作device和host切换的时候做的主函数,你可以参考一下,使用的是供电电源来区分的device和ho ...

这个有需要配置usb id信号么?
我的理解usb id信号应该是对于MCU是输入的状况吧?
jiafangshi
5楼-- · 2019-07-22 00:46
 精彩回答 2  元偷偷看……
jiafangshi
6楼-- · 2019-07-22 05:34
融合方面的问题,你可以参考我提供的主函数代码,我自己做的比较成熟的产品,比较稳定来着,只是前年做的,时间有点长了,有些地方不好详细的回答你

一周热门 更多>