控制/MCU
最近在项目的时候需要判别STM32的复位类型,网上这部分资料也有许多大神进行总结。但是感觉不是特别深入,因此,小编参考参考了STM32的参考手册进行详细总结了一下。
分别为系统复位、电源复位和备份域复位。每一种型号的STM32都包含有这三种复位类型!
除了时钟控制寄存器 CSR 中的复位标志和备份域中的寄存器外,
系统复位会将其它全部寄存器都复位为复位值,只要发生以下事件之一,就会产生系统复位:
要对器件进行软件复位,必须将 Cortex™-M4F 应用中断和复位控制寄存器中的SYSRESETREQ 位置 1,标准库和HAL库默认都是置1的,软件复位的代码如下:
void NVIC_SystemReset(void)
{
__DSB();
SCB- >AIRCR = ((0x5FA < < SCB_AIRCR_VECTKEY_Pos) |
(SCB- >AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB();
while(1);
}
引发低功耗管理复位的方式有两种:
除备份域内的寄存器以外,电源复位会将其它全部寄存器设置为复位值。只要发生以下事件之一,就会产生电源复位:
这些源均作用于 NRST 引脚,该引脚在复位过程中始终保持低电平。RESET 复位入口向量
在存储器映射中固定在地址 0x0000_0004。
芯片内部的复位信号会在 NRST 引脚上输出。脉冲发生器用于保证最短复位脉冲持续时间,
可确保每个内部复位源的复位脉冲都至少持续 20 μs。对于外部复位,在 NRST 引脚处于低
电平时产生复位脉冲。
备份域复位会将所有 RTC 寄存器和 RCC_BDCR 寄存器复位为各自的复位值。只要发生以下事件之一,就会产生备份域复位:
BKPSRAM 不受此复位影响。BKPSRAM 的唯一复位方式是通过 Flash 接口将 Flash 保护等级从 1 切换到 0。
在实际项目中需要判断复位的类型,从而进行下一步动作。
判断复位类型的寄存器是RCC_CSR寄存器(RCC 时钟控制和状态寄存器 ),STM32的参考手册如下介绍:
RCC_CSR
由上面的寄存器介绍可以知道,我们直接读取这个寄存器的值就能知道是什么引起的复位。
读取完成后记得要将第24位,即RMVF置1。清除复位的标志。## 2.1、STM32区分复位类型的代码实现
直接操作寄存器的代码:
if(0 != (RCC- >CSR & 0x80000000))//低功耗复位标志
{
printf("低功耗复位rn");
}
else if(0 != (RCC- >CSR & 0x40000000))//窗口看门狗复位标志
{
printf("窗口看门狗复位rn");
}
else if(0 != (RCC- >CSR & 0x20000000))//独立看门狗复位标志
{
printf("独立看门狗复位rn");
}
else if(0 != (RCC- >CSR & 0x10000000))//软件复位标志
{
printf("软件复位rn");
}
else if(0 != (RCC- >CSR & 0x08000000))//上电/掉电复位标志
{
printf("上电/掉电复位rn");
}
else if(0 != (RCC- >CSR & 0x04000000))//引脚复位标志
{
printf("引脚复位rn");
}
else if(0 != (RCC- >CSR & 0x02000000))//BOR 复位标志
{
printf("BOR复位rn");
}
RCC- >CSR |= 0x01000000;//清除复位标志
使用标准库的代码:
if(1 == RCC_GetFlagStatus(RCC_FLAG_LPWRRST))//低功耗复位标志
{
printf("低功耗复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_WWDGRST))//窗口看门狗复位标志
{
printf("窗口看门狗复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_IWDGRST))//独立看门狗复位标志
{
printf("独立看门狗复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_SFTRST))//软件复位标志
{
printf("软件复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_PORRST))//上电/掉电复位标志
{
printf("上电/掉电复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_PINRST))//引脚复位标志
{
printf("引脚复位rn");
}
else if(1 == RCC_GetFlagStatus(RCC_FLAG_BORRST))//BOR 复位标志
{
printf("BOR复位rn");
}
RCC_ClearFlag();//清除复位标志
如果在代码中使用iap_load_app来代替复位是可行的,即将复位函数NVIC_SystemReset();替换成iap_load_app(FLASH_BASE);即可。
此时RCC->CSR寄存器为0。
if(0 == RCC- >CSR)
{
printf("跳转rn");
}
RCC_ClearFlag();//清除复位标志
delay_ms(3000);
全部0条评论
快来发表一下你的评论吧 !