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上电引起

posted @   喵喵喵mmm  阅读(131)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示