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

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

查看全部评分

shrekshell 回答时间:2018-1-4 17:42:08
还有一个问题:
shrekshell 回答时间:2018-1-4 17:53:23
还有一个问题:
        板子用超声波洗过,洗的方式是板子串在粗铜丝上,吊在超声波清洗机里,板子下边缘接触到了清洗机的底部,洗板水大概有5mm-10mm深,只有板子下边缘的两个接插件没入洗板水中,单片机没有没入洗板水,晶振也没有没入洗板水,洗了大概3分钟,不知道跟这个有没有关系。
五哥1 回答时间:2018-2-3 09:27:31
楼主,粗看了你的大部分测试,我认为这个是晶振质量不过关造成,不知你的晶振来源,但是这个现象,就是和晶振有很大的关系,我们以前的产品有许多奇怪的问题,后来都是更换晶振最终解决问题。

评分

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

查看全部评分

st_application 回答时间:2019-1-25 11:34:48
此问题有解决吗?确实让人百思不得其解,reset脚都不能复位.还是怀疑mpu有硬件死锁的原因,属于设计缺陷

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版