单片机
返回首页

STM32 USB断开连接代码停止运行

2016-10-13 来源:eefocus

        这段时间做USB固件升级,使用ST官方固件,最开始按照ST的做法通过检测按键进入DFU模式。后来由于别人觉得这种方式做不好,要改成检测USB的而不是检测按键的。但是当我改好了测试的时候却发现当我把USB初始化之后断开了USB连接程序停止了运行,接上USB程序才会继续跑。连使用Jlink调试都没用了。然而根据打印调试,USB接上的时候MCU并没有复位,硬件出错其实也不太像,总之觉得一切很诡异。至少在当时我根本就没办法解释我所观察到的这个现象。百度也没有结果,大多数情况下百度其实很废但是没办法。
 
        想了很久我觉得是不是MCU休眠去了?带着这样的猜测到初始化过程中去找相关初始化,因为在我印象当中,睡眠模式也是需要初始化寄存器的,只可惜找了好久没有找到。不过我觉得打印调试在大多数时候还是好用的。于是我就通过printf一个个捕捉中断,试图搞清楚在拔出USB的那一刻到底去哪里执行代码了。几经调试,最后才发现在USB_Istr函数中有这样一段代码:

#if (IMR_MSK & ISTR_SUSP)
if (wIstr & ISTR_SUSP & wInterrupt_Mask)
{

/* check if SUSPEND is possible */
if (fSuspendEnabled)
{
Suspend();
}
else
{
/* if not possible then resume after xx ms */
Resume(RESUME_LATER);
}
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
_SetISTR((uint16_t)CLR_SUSP);
#ifdef SUSP_CALLBACK
SUSP_Callback();
#endif
}
#endif

问题就出在Suspend()函数:

/* enter system in STOP mode, only when wakeup flag in not set */
if((_GetISTR()&ISTR_WKUP)==0)
{
__WFI();
/* Reset SLEEPDEEP bit of Cortex System Control Register */
#if defined (STM32F30X) || defined (STM32F37X)
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
#else
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
#endif
}

这里的__WFI()指令就是导致代码停止运行的罪魁祸首。从数据手册中可以查到这是一条进入睡眠状态的指令,令我以外的是STM32进入睡眠低功耗模式连初始化都不需要(我确实没有找到相关初始化代码)直接一条指令就搞定。这也可以算的是我墨守成规的一个教训吧。所以最后只需把这条__WFI()指令屏蔽掉就OK了。

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

最新器件
精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 非常简单的150W功放电路图

  • 基于IC555的可变PWM振荡器电路

  • 优化电路板布局的简单方法

  • 分享一个电网倾角计电路

    相关电子头条文章