RISC-V MCU 应用教程之RCC(1)
CH32V307提供了3钟复位形式:
-
电源复位
-
系统复位
-
后备区域复位
1. 电源复位
产生电源复位的条件为:
-
上电/掉电复位(POR/PDR复位)
-
从待机模式下唤醒
电源复位发生时,将复位除了备份区域的所有寄存器。PC指针固定到0x00000000。
:::tip
此时的后备寄存器需由VBAT供电,如果同VDD供电,后备区域寄存器将同步复位。
:::
2. 系统复位
产生系统复位的条件为:
-
NRST引脚上的低电平信号(外部复位)
-
窗口看门狗计数终止(WWDG复位)
-
独立看门狗计数终止(IWDG复位)
-
软件复位(SW复位)
-
低功耗管理复位
:::tip
-
通过配置
PFIC_CFGR
寄存器SYSRESET
位置 1 ,或者配置PFIC_SCTLR
寄存器SYSRESET
位置 1,产生软件复位。 -
将用户选择字节中的 STANDY_RST 位置0,将启用待机模式复位,这时进入待机模式会产生低功耗管理复位;将用户选择字节中的 STOP_RST 位置0,将启用停止模式复位,这时进入停止模式会产生低功耗管理复位
系统复位时, 除了控制/状态寄存器 RCC_RSTSCKR
中的复位标志和后备区域的寄存器(VBAT单独供电),其余所有寄存器将复位。
所以可以通过寄存器 RCC_RSTSCKR
中的复位标志查看上一次系统复位原因,参考代码如下:
参考代码 - 查看系统复位原因
#include "debug.h" typedef enum { NONERST_FLAG = 0, /* none reset */ PINRST_FLAG, /* NRST reset */ PORRST_FLAG, /* POR/PDR reset */ SFTRST_FLAG, /* software reset */ IWDGRST_FLAG, /* independent watchdog reset */ WWDGRST_FLAG, /* window watchdog reset*/ LPWRRST_FLAG /* low power reset */ }reset_flag_t; reset_flag_t check_reset_flag() { reset_flag_t reset_flag = NONERST_FLAG; if( ( RCC->RSTSCKR & (1<<(25+PINRST_FLAG))) != RESET) { reset_flag = PINRST_FLAG; } else if( ( RCC->RSTSCKR & (1<<(25+PORRST_FLAG))) != RESET ) { reset_flag = PORRST_FLAG; } else if( ( RCC->RSTSCKR & (1<<(25+SFTRST_FLAG))) != RESET ) { reset_flag = SFTRST_FLAG; } else if( ( RCC->RSTSCKR & (1<<(25+IWDGRST_FLAG))) != RESET ) { reset_flag = IWDGRST_FLAG; } else if( ( RCC->RSTSCKR & (1<<(25+WWDGRST_FLAG))) != RESET ) { reset_flag = WWDGRST_FLAG; } else if( ( RCC->RSTSCKR & (1<<(25+LPWRRST_FLAG))) != RESET ) { reset_flag = LPWRRST_FLAG; } RCC->RSTSCKR |= (1<<24); /* clear reset flag */ return reset_flag; } int main(void) { reset_flag_t reset_flag = NONERST_FLAG; Delay_Init(); USART_Printf_Init(256000); printf("ch32v307 check reset flag\r\n"); reset_flag = check_reset_flag(); switch(reset_flag) { case PINRST_FLAG: printf("NRST reset\r\n"); break; case PORRST_FLAG: printf("POR/PDR reset\r\n"); break; case SFTRST_FLAG: printf("software reset\r\n"); break; case IWDGRST_FLAG: printf("independent watchdog reset\r\n"); break; case WWDGRST_FLAG: printf("window watchdog reset\r\n"); break; case LPWRRST_FLAG: printf("low power reset\r\n"); break; default: break; } printf("RCC->RSTSCKR : %08lx\r\n",RCC->RSTSCKR); // Delay_Ms(3000); // NVIC_SystemReset(); while(1) { ; } }
3. 后备区域复位
后备区域复位发生时,只会复位后备区域寄存器,包括后备寄存器、RCC_BDCTLR
寄存器(RTC 使能和LSE 振荡器)。其产生条件包括:
-
软件复位,将
RCC_BDCTLR
寄存器 的BDRST
位置1, 或者将RCC_APB1PRSTR
寄存器的BKPRST
位置1 -
在VDD和VBAT都掉电的前提下,由VDD或VBAT上电引起
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?