STM32F1 USB虚拟串口 断开USB线后重连问题

2019-08-12 16:48发布

本帖最后由 DreamWaterPro 于 2017-10-25 21:27 编辑

问题现象:
实验室课题需要,使用STM32F1系列单片机的USB虚拟串口功能,能够被计算机正常识别为虚拟串口。然而经过近百次测试发现,在第一次上电之后,USB可以被正确枚举,通过串口助手sscom也可以正确使用;然而只要拔掉USB线缆,重新插入之后,USB还是可以正常被识别,串口助手可以正常发现并打开串口,但是无法接收STM32经过USB发送过来的数据。更加神奇的是,STM32竟然可以完好地接收到电脑上发过来的数据。

具体细节:
1、使用芯片为STM32F103C8T6,程序使用正点原子战舰开发板中的USB虚拟串口例程,仅在主函数做了相关改动(删除LCD的代码,增加自己的外设驱动代码),实现完全相同的功能,除了增加了RGB彩灯的相关代码(使用TIM2 TIM3)和串口一外没有使用到任何其他外设。
2、改动后的USB驱动代码:
[mw_shl_code=c,true]//相关代码开始
        delay_ms(1800);
        USB_Port_Set(0);         //USB先断开
        delay_ms(700);
        USB_Port_Set(1);        //USB再次连接
         Set_USBClock();   
         USB_Interrupts_Config();   
         USB_Init();                           
        while(1)
        {
                if(usbstatus!=bDeviceState)//USB连接状态发生了改变.
                {
                        usbstatus=bDeviceState;//记录新的状态
                        if(usbstatus==CONFIGURED)
                        {
                                //删除用不到的LED LCD代码
//                                POINT_COLOR=BLUE;
//                                LCD_ShowString(30,130,200,16,16,"USB Connected    ");//提示USB连接成功
//                                LED1=0;//DS1亮
                                //自己的外设驱动代码,其实是一个RGB彩灯,
                                //当USB连接时,显示绿 {MOD}
                                SetLEDSpecialColor(COLOR_GREEN);
                        }else
                        {
                                //删除用不到的LED LCD代码
//                                POINT_COLOR=RED;
//                                LCD_ShowString(30,130,200,16,16,"USB disConnected ");//提示USB断开
//                                LED1=1;//DS1灭
                                //自己的外设驱动代码
                                //当USB连接断开时,显示红 {MOD}
                                SetLEDSpecialColor(COLOR_RED);
                        }
                }

                //判断是否已经收到了一组数据
                if(USB_USART_RX_STA&0x8000)
                {                                          
                        len=USB_USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
                        usb_printf(" 您发送的消息为:%d ",len);
                        for(t=0;t<len;t++)
                        {
                                USB_USART_SendData(USB_USART_RX_BUF[t]);//以字节方式,发送给USB
                        }
                        usb_printf(" ");//插入换行
                        USB_USART_RX_STA=0;
                }else
                {
                        times++;
                        if(times%5000==0)
                        {
                                usb_printf(" 战舰STM32开发板USB虚拟串口实验 ");
                                usb_printf("正点原子@ALIENTEK ");
                        }
                        if(times%200==0)
                                usb_printf("请输入数据,以回车键结束 ");  
                        //屏蔽掉用不到的LED驱动
//                        if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
                        delay_ms(10);   
                }
        }[/mw_shl_code]
3、USB部分电路图:
1.png

4、PCB中USB部分电路图:

2.png

5、不正常进行数据收发时,串口助手截图:

4.png

使用STlink调试时发现STM32已经执行了usb_printf()函数,但是串口助手上没有任何反应;同时,使用串口助手向STM32发送数据,在调试界面可以看到STM32已经正确地接收到了这个数据:

5.png

7、上述情况发生后,只有拔下USB线并且通过按复位按键复位单片机,下一次连接USB线时才能够正常使用。而且通过SWD下载完成导致的软复位并不能解决这个故障,问题依旧。

8、不得不提的是,我使用自己之前购买的同款单片机的最小核心板,下载同样的程序,确完全没有该问题。这款最小核心板USB电路部分原理图如下:

6.png

9、可以确定自己制作的PCB板USB通信电路是没有问题的(可以正常收发数据),也可以确定现在所使用的程序也是可以正常工作的(在另外一块系统板上不会出现该问题)。现在我整个人处于懵圈的状态,有哪位大神可以帮助我解决一下当前的问题?




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。