你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f103 stop模式定时唤醒,运行一段时间死机,复位无效

[复制链接]
shrekshell 提问时间:2018-1-3 16:15 /
求助,做了一个低功耗的项目,使用stm32f103C8T6,初始化做了这些工作:         RCC_Configuration();//内部RC  没有用PLL,8M直接做系统时钟
        WATCHDOG_init(5000);//看门狗 5s
        TIMER_Configuration();//定时器1ms
        USART_Configuration();//串口1 2 波特率9600
        I2C_Configuration();//软件模拟I2C(硬件的出了问题,不敢用了)
        RTC_Configuration();//外部RTC(内部的有问题,不敢用了)
        NVIC_Configuration();//中断配置
        GPIO_Configuration();//GPIO初始化
        程序在主循环里喂狗,在没有外部条件触发的情况下延时进入stop模式。
        在进入stop模式前,把必要的输入口配置成外部中断,必要的输出口配置成相应输出,其他所有IO全部配置成模拟输入。
        外部RTC芯片每2s输出一个上升沿,触发中断,唤醒单片机,单片机唤醒后对单片机进行一次初始化,和上边的初始化一模一样,然后进行一次喂狗,并做一些任务(所有工作耗时大概15ms),然后再次进入休眠。这里我称它为心跳休眠。
        如果单片机被外部条件触发,会退出心跳休眠,进入正常模式,当外部条件消失,会延时再次进入心跳休眠。


那么问题来了:
        单片机在进入心跳休眠一段时间之后,会完全死掉,外部复位都无法复位单片机,只能重新上电才能正常工作。
        我的这个问题和一位前辈遇到的问题一模一样,帖子链接如下:
        https://www.stmcu.org.cn/faq/index/detail/id-70559
        https://www.stmcu.org.cn/faq/index/detail/id-70556
        另外一位前辈遇到的问题,有点类似,帖子链接如下:
        http://bbs.eeworld.com.cn/thread-502936-1-1.html

问题分析:


        这个问题复现的概率很小,1000片板子,有10片板子出现了这样的问题。出现问题的板子重新上电后大部分没有再出现过死机的情况。
        有一片我在反复上电的过程中,多次出现死机的情况,但过了一会,我再去测,直到现在,都没有出现过死机的情况。

        我有一个假设,假设如下:
        单片机上电正常工作,然后进入休眠,休眠时所有时钟停止(除了LSI,因为要给看门狗提供时钟),但是如果某一次唤醒后,HSI并没有起振,那么程序不会往下执行,喂狗失败导致看门狗复位,复位后,所有寄存器变为初始值,HSI仍然在一个停振的状态,程序停在入口处不会继续往下执行,即使外部复位,程序依然停在入口处。这就可以解释为什么外部复位不起作用了。

        功耗描述:
        单片机正常功耗9mA左右,休眠功耗120uA左右(整板功耗,单片机休眠功耗13uA左右),单片机死掉后,整板功耗稳定在400uA左右(单片机此时功耗在300uA左右),当我外部复位的时候,功耗会跳一会(时间在几秒-二三十秒不等),最终会又稳定400uA左右,一般很快就会稳定到400uA左右。



收藏 1 评论13 发布时间:2018-1-3 16:15

举报

13个回答
shrekshell 回答时间:2018-1-3 16:40:17
我现在做了一个实验,用的外部晶振,RCC初始化是这样写的:
if(RCC_WaitForHSEStartUp() == SUCCESS){开始初始化外部时钟}
else {while(1);}①
        接下来是看门狗初始化。
        WATCHDOG_init(5000);//看门狗 5s
实验开始:
        单片机上电正常运行。这时,短接晶振引脚,晶振停振,5s后,看门狗复位,这时所有寄存器复位,晶振切换到内部RC,并继续运行初始化程序,当初始化外部晶振的时候,外部晶振还被我短接这,初始化不通过,进入①处的else{while(1);},这时松开短接晶振的镊子,单片机死掉,因为看门狗还没初始化,所以看门狗无法复位。
        如果镊子一直短接着晶振,那么外部复位可以让程序复位,并继续走到①处,但表面上看,程序仍然是死掉的,进入while(1);后,板子功耗3mA。
shrekshell 回答时间:2018-1-3 17:29:53
刚又想起来一个点:
shrekshell 回答时间:2018-1-3 18:51:26
用ST LINK仿真程序的时候,程序下载完成,进入仿真,这时候不取消debug,而是直接拔掉板子仿真口的排线,单片机也是死在那里的,此时功耗1.5mA。不知道此时的状态,跟我上边描述的死掉的状态有什么区别。当然,debug这种状态复位就可以正常跑起来。
shrekshell 回答时间:2018-1-3 21:22:00
刚又发现一个现象:用镊子短接晶振,不同情况下的对比。
A情况:程序停在进入主函数之前,但晶振短接移除后,程序继续往下走。
B情况:程序进入了主函数,外部晶振READY失败,程序停止在else{while(1);}处。
C情况:程序进入了主函数,外部晶振READY成功,程序停在系统时钟切换处while(RCC_GetSYSCLKSource() != 0x04){}。
A情况发生的条件:
1.正常工作时,短接电容,看门狗复位,程序停在进入主函数之前,短接释放,程序继续往下走。
B情况发生的条件:
1.stop模式时,短接电容,看门狗复位,程序停在else{while(1);}处,短接释放,程序停在while(1)处。
2.仿真时,拔掉仿真线,短接晶振,镊子点外部复位,是B情况。
C情况发生的条件:
B情况发生后,镊子松开晶振,然后再次短接晶振,另外一个镊子短接复位,产生C情况,如果B情况发生后,镊子不松开晶振,持续短接,另外一个镊子短接复位后,还是B情况。


问题分析:
C情况和B情况的区别是这一段程序
  do
  {
    HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
    StartUpCounter++;  
  }
while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET));
C情况检测到了HSERDY,而B情况没有检测到HSERDY。
很显然,C情况发生时,镊子松开了一下晶振,晶振起振了,导致HSERDY置位。

有一种猜测,系统复位的时候,寄存器的值没有复位,因为松开镊子是在复位之前,但镊子再次短上晶振后,复位,此时外部晶振仍然是失效的,HSERDY竟然可以置位,HSERDY是不是上一次松开短接时置的位,复位并没有将其清除掉。HSERDY 寄存器复位值0x000 XX83,可以确定是0;

通过对比C情况和B情况,发现:
晶振停振期间,即:
1.系统在复位(仿真时复位拔掉仿真器);
2.休眠(stop模式时);
短接晶振,
1.短接NRST
2.看门狗自动复位
程序都会进入主循环(使用HSI),直到在初始化HSE时失败,会停下来。

为什么A进不了主函数?而B和C都能进入主函数?
我有一个猜测,那就是NRST并没有使所有寄存器值复位。推测入下:
A之所以没有进入主函数,是因为复位前,是正常工作状态,RCC寄存器配置的是外部晶振。但由于人为的短接了晶振,导致晶振停振,看门狗复位,复位后,寄存器的值并没有复位,RCC配置的仍然是HSE,且晶振仍然被短接着,CPU没有时钟,所以程序无法运行进入主函数。当松开镊子后,晶振起振,程序正常开始往下跑。

为了保险起见,我查了英文原版的数据手册,跟中文的一样,说:
A system reset sets all registers to their reset values except the reset flags in the clock controller CSR registers in the Backup domain。
除了时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器(见图4)以外,系统复位将复位所有寄存器至它们的复位状态。

但是从上边实验可以看出,复位寄存器很有可能没有被复位。
如果寄存为没有被复位,假设休眠时,HSI是Disable的,由于异常,导致复位后,HIS仍然是Disable,没有主时钟,单片机就死掉了。

我明天做几个实验:
在main函数入口处,判断是主时钟是HSE还是HSI。
正常模式下(HSE被正常初始化),我短接外部晶振,触发看门狗复位,按照数据手册,在main函数入口处,应该是HIS,但如果是HSE,那说明RCC没有复位。

再做一个实验,想办法得到休眠状态下,HIS是否是使能的。

再做一个实验,我这边1000片板子,是不是所有的单片机都是寄存器不复位的。
shrekshell 回答时间:2018-1-4 09:56:36
实验做了,ABC三种情况,进入main函数的时候,使用的都是HSI。因为在进入main函数之前,程序执行了SystemInit,RCC被初始化成了HSI,所以这个不能说明问题。
shrekshell 回答时间:2018-1-4 11:25:43
寄存器复位应该没问题,做了几组寄存器的实验,发现确实都是复位的值,除了GPIOA Pin13 14 15,GPIOB Pin5 跟数据书上不一样。

如果复位后,寄存器全部被设置成复位值,那A情况就没有办法解释了。
为什么外部晶振停振,看门狗复位后,进不了Main函数?
休眠后,死掉的状态是一个什么状态?
QQ截图20180104111519.jpg
shrekshell 回答时间:2018-1-4 12:08:15
刚做了独立看门狗的实验,发现独立看门狗初始化的时候,RCC_CSR的LSION位并没有置1,而LSIRDY置1了,此时看门狗可以复位,说明看门狗在没有LSION位置1的情况下仍然在工作,数据书上说IWDG的时钟源是LSI,且看门狗一旦被设置,除了系统复位,无法被停止。
那也就是说,LSI在看门狗设置的时候,已经在震荡,即使LSION为0。这个问题会不会造成死机?
shrekshell 回答时间:2018-1-4 14:54:57
还有一个问题:        板子在上电前,有一个排线要先插上,排线能给VCC供一个电压,但没有电流驱动能力,我量了下,3.3V LDO输出是1.89V。
        用示波器抓电源波形,发现是一个20ms周期震荡的波形,电压从1.86缓缓上升到1.94,然后被拉低到1.86,依次循环。
        这种情况是否是内核在将要工作的时候,电压被拉低,造成掉电复位,然后电压回升,上电复位,将要工作的时候,电压被拉低,依次循环。
        这种情况会不会导致单片机出现异常?
        还有上电时,电源波动,会不会造成异常,如这个帖子里描述的:
        http://www.51hei.com/bbs/dpj-40958-1.html
回答时间:2018-1-4 15:44:54
没有碰到类似的情况,楼主用的是内部看门狗还是外部的?
可以考虑晶振失败的情况,不要在那死等,当外部启动失败,可以试着切换到内部,保证本次能够正常工作。2s的唤醒频率是不是有电太频繁了?

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版