在项目中有时候会遇到单片机莫名奇妙复位的情况,为了判断是那种原因引起复位,就需要对单片机的复位源进行判断。现用STM32F103C8T6单片机进行测试。
先看看单片机复位源都有哪些?
在STM32中文参考手册中可以看到,复位源可以通过状态寄存器来读出。
于是写一段程序来读取复位状态寄存器:
void Check_Rst(void)
{
printf(" CSR = %xrn", RCC->CSR);
if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET ) // NRST 引脚复位
{
printf("PIN reset rn");
}
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET ) // 上电掉电复位
{
printf("POR/PDR reset rn");
}
if(RCC_GetFlagStatus(RCC_FLAG_SFTRST) != RESET ) // 软件复位
{
printf("Software reset rn");
}
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET ) // 独立看门狗复位
{
printf("Independent watchdog reset rn");
}
if(RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET ) // 窗口看门狗复位
{
printf("Window watchdog reset rn");
}
if(RCC_GetFlagStatus(RCC_FLAG_LPWRRST) != RESET ) // 低功耗复位
{
printf("(Low-power reset rn");
}
RCC_ClearFlag(); //清除复位标志
printf("rn");
}
通过串口将信息打印出来。
现在写个程序测试,引脚复位、掉电复位、看门狗复位都比较好测试。就是软件复位要用代码实现。通过查找资料发现软件复位可以分为系统复位和内核复位。系统复位会复位所有硬件电路,包括IO口状态。内核复位只复位内核,不影响硬件电路。
系统复位实现代码如下:
//系统复位 所有电路都会复位
void mcuSysRestart(void)
{
__set_FAULTMASK(1); //关闭所有中断
NVIC_SystemReset(); //系统复位 源码见 core_cm3.h 文件 static __INLINE void NVIC_SystemReset(void) 函数
}
内核复位代码如下:
//内核复位 不会影响外设和其他电路
void mcuCoreRestart(void)
{
__DSB();
//置位VECTREST
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_VECTRESET_Msk);
__DSB();
while(1);
}
在程序中通过不同的按键控制不同复位情况,打印信息如下:
上电复位:
按复位键复位:
独立看门狗复位:
窗口看门狗复位:
系统复位:
内核复位:
通过上面复位测试可以发现,每种复位都会检测到NRST 引脚复位,难道每种复位都会将复位引脚电平拉低吗?通过示波器看看复位引脚电平:
通过复位引脚波形可以看出,在其它复位情况发生时,复位引脚会有一个很短的负脉冲。说明其他复位源产生时,复位引脚电平也会变化。看来上面程序检测是正确的。
上一篇:STM32低功耗模式测试
下一篇:STM32F1xx系列单片机通过程序获取MCU信息
推荐阅读最新更新时间:2024-11-12 15:45