NVIC_SystemReset()函数软件复位失败的解决方法

在工作中遇到较为复杂的项目时,往往需要使用软件复位来重启单片机,我刚刚接手的一个项目中就遇到了这样的情况:项目中用了较多的任务和中断处理,在出现某些特定情况时,必须重新启动设备,于是就用了软件复位的方式,调用NVIC_SystemReset()函数来进行软件复位。

但是在代码运行过程中却发现了这样的问题:当某一条件成立,程序跑到NVIC_SystemReset()函数后,并没有重新运行,而是卡死了。

经过分析发现原因:NVIC_SystemReset()函数是通过将SYSRESETREQ置位有效来复位的,但是从SYSRESETREQ 被置为有效,到复位发生器执行复位命令,有一个延时,在这个延时期间,CPU可以被其他中断打断。但我们的要求是程序执行到这个函数之后立即停止,不再处理任何事件;

所以,最好在发出复位请求前,先把FAULTMASK置位,也就是加上这个函数:__set_FAULTMASK(1);意思是关闭所有中断的意思,目的是在执行NVIC_SystemReset()复位函数过程中不被中断所打断。两个函数执行后系统复位重新执行代码,包括之前所配置好的外设寄存器也都回到复位状态。

完整的重启方法是:

__set_FAULTMASK(1); //关闭所有中断 
 NVIC_SystemReset(); //复位

如果上面这两行代码还是无法完成软件复位的话,可以找到NVIC_SystemReset()函数的源代码:

static __INLINE void NVIC_SystemReset(void)
{
  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      | 
                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | 
                 SCB_AIRCR_SYSRESETREQ_Msk);            /* Keep priority group unchanged */
  __DSB();                                           /* Ensure completion of memory access */              
  while(1);                                                    /* wait until reset */
}

把上述代码中第5行的SCB_AIRCR_SYSRESETREQ_Msk 修改为 SCB_AIRCR_VECTRESET_Msk 即可。

我在工程中用的是第二种方法,目前亲测没问题

  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫王超平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值