完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
最近在项目的时候需要判别STM32的复位类型,网上这部分资料也有许多大神进行总结。但是感觉不是特别深入,因此,小编参考参考了STM32的参考手册进行详细总结了一下。
1、STM32的三种复位类型 分别为系统复位、电源复位和备份域复位。每一种型号的STM32都包含有这三种复位类型! 1.1、系统复位 除了时钟控制寄存器 CSR 中的复位标志和备份域中的寄存器外, 系统复位会将其它全部寄存器都复位为复位值,只要发生以下事件之一,就会产生系统复位: NRST 引脚低电平(外部复位) 窗口看门狗计数结束( WWDG 复位) 独立看门狗计数结束( IWDG 复位) 软件复位( SW 复位) 低功耗管理复位 1.1.1、软件复位 要对器件进行软件复位,必须将 Cortex™-M4F 应用中断和复位控制寄存器中的SYSRESETREQ 位置 1,标准库和HAL库默认都是置1的,软件复位的代码如下: 1void NVIC_SystemReset(void) { __DSB(); SCB-》AIRCR = ((0x5FA 《《 SCB_AIRCR_VECTKEY_Pos) | (SCB-》AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); while(1); } .1.2、低功耗管理复位 引发低功耗管理复位的方式有两种: 进入待机模式时产生复位: 此复位的使能方式是清零用户选项字节中的 nRST_STDBY 位。使能后,只要成功执行 进入待机模式序列,器件就将复位,而非进入待机模式。 进入停止模式时产生复位: 此复位的使能方式是清零用户选项字节中的 nRST_STOP 位。使能后,只要成功执行 进入停止模式序列,器件就将复位,而非进入停止模式。 1.2、电源复位 除备份域内的寄存器以外,电源复位会将其它全部寄存器设置为复位值。只要发生以下事件之一,就会产生电源复位: 上电/掉电复位( POR/PDR 复位)或欠压 (BOR) 复位 在退出待机模式时 这些源均作用于 NRST 引脚,该引脚在复位过程中始终保持低电平。 RESET 复位入口向量在存储器映射中固定在地址 0x0000_0004。 芯片内部的复位信号会在 NRST 引脚上输出。脉冲发生器用于保证最短复位脉冲持续时间,可确保每个内部复位源的复位脉冲都至少持续 20 μs。 对于外部复位,在 NRST 引脚处于低电平时产生复位脉冲。 1.3、备份域复位 备份域复位会将所有 RTC 寄存器和 RCC_BDCR 寄存器复位为各自的复位值。只要发生以下事件之一,就会产生备份域复位: 软件复位,通过将 RCC 备份域控制寄存器 (RCC_BDCR) 中的 BDRST 位置 1 触发。 在电源 VDD 和 VBAT 都已掉电后,其中任何一个又再上电。 BKPSRAM 不受此复位影响。 BKPSRAM 的唯一复位方式是通过 Flash 接口将 Flash 保护等级从 1 切换到 0。 2、STM32复位类型的区分 在实际项目中需要判断复位的类型,从而进行下一步动作。 判断复位类型的寄存器是RCC_CSR寄存器(RCC 时钟控制和状态寄存器 ),STM32的参考手册如下介绍: 由上面的寄存器介绍可以知道,我们直接读取这个寄存器的值就能知道是什么引起的复位。 读取完成后记得要将第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();//清除复位标志 3、复位和iap_load_app的区别 发生复位,系统会记录一些标志信息。 但是使用iap_load_app跳转到0x8000000的位置,系统会一直默认在执行。不会有复位的标志返回。 如果在代码中使用iap_load_app来代替复位是可行的,即将复位函数NVIC_SystemReset();替换成iap_load_app(FLASH_BASE);即可。 此时RCC-》CSR寄存器为0。 if(0 == RCC-》CSR) { printf(“跳转rn”); } RCC_ClearFlag();//清除复位标志 delay_ms(3000); iap_load_app(FLASH_BASE); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1621 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1546 浏览 1 评论
980 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
686 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1599 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
536浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 07:12 , Processed in 0.765007 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号