本帖最后由 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部分电路图:
4、PCB中USB部分电路图:
5、不正常进行数据收发时,串口助手截图:
使用STlink调试时发现STM32已经执行了usb_printf()函数,但是串口助手上没有任何反应;同时,使用串口助手向STM32发送数据,在调试界面可以看到STM32已经正确地接收到了这个数据:
7、上述情况发生后,只有拔下USB线并且通过按复位按键复位单片机,下一次连接USB线时才能够正常使用。而且通过SWD下载完成导致的软复位并不能解决这个故障,问题依旧。
8、不得不提的是,我使用自己之前购买的同款单片机的最小核心板,下载同样的程序,确完全没有该问题。这款最小核心板USB电路部分原理图如下:
9、可以确定自己制作的PCB板USB通信电路是没有问题的(可以正常收发数据),也可以确定现在所使用的程序也是可以正常工作的(在另外一块系统板上不会出现该问题)。现在我整个人处于懵圈的状态,有哪位大神可以帮助我解决一下当前的问题?
虽然跟你遇到的问题好像没有关系,但谁告诉你STM32F1不支持OTG功能的?明明支持呀。
1、第一感觉是你应该用示波器抓一下数据从哪里开始断的,如果发数据时是单片机的D+D-有信号就继续往下抓断在了哪个芯片上。如果没信号就一定是代码问题。
2、通过描述7,感觉是代码问题,而且你已经找到的解决的一种不好用的方式,但它说明了你在热插拔的处理上有问题。之前做USB OTG时热插拔是有相应处理的,你看看有没有这可能性。
嗯嗯是我的表述不严谨,107系列可以做主机,我用的STM32F103系列的USB是只能作为从机,不能作为USB主机= =
关于热插拔的处理,我回去好好看看
一周热门 更多>