nbutjyy 发表于 2024-3-26 02:45

手把手教你嵌入式国产化-杂项-GD32复位源寄存器(判断复位/重启生成)

本帖最后由 nbutjyy 于 2024-3-26 02:52 编辑

​       文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发
       本章主要以GD32复位源寄存器为主展开讲解

       后续项目主要在下面该专栏中发布:
https://blog.csdn.net/qq_62316532/category_12608431.html?spm=1001.2014.3001.5482
       感兴趣的点个关注收藏一下吧!

       电机驱动开发可以跳转:
手把手教你嵌入式国产化-实战项目-无刷电机驱动(1)

       BMS电源系统开发可以跳转:暂未放链接

目录
介绍       本小结主要讲解,在GD32F10x中复位源涉及到的寄存器和操作介绍;至于为什么要讲解这个呢?相信大家平常在学习使用GD32或者是项目开发的过程中,偶尔或者经常遇见设备的无故重启,这就很烦人,这对我们设置的稳定性造成极大影响。
       首先我们列举一下发生复位的一些标志位:


[*]低功耗管理复位
[*]窗口看门狗复位
[*]独立看门狗定时器复位
[*]软件复位
[*]电源复位
[*]外部引脚复位
[*]IRC40K稳定标志位
       平常我们为了防止系统在运行过程中,发生死机或者程序跑飞,都会人为开启开门狗去进行监控,通过特定的喂狗操作,使程序的自启动受到控制。


       但是单片机的复位操作可不止开门狗这一种,根据我上面列出的,大家可以发现也有很多情况会发生复位。那么,出现了我人为控制复位以外的复位情况,在我们看来,就是属于一种非正常复位,那么我们接下来肯定要对其进行处理修复!

       因此,我们本节涉及到的区别设备复位的复位源操作就显得十分重要了!


寄存器我们查看复位情况,主要是通过RCU下面的复位源/时钟寄存器(RCU_RSTSCK)

https://img-blog.csdnimg.cn/direct/2a41eba1dd9c4fda87aae8e64d2511e1.png​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑

       通过对该寄存器值的查看,我们可以通过产生复位的复位源标志位去识别!


https://img-blog.csdnimg.cn/direct/e481e12ec050471fa6fdec03064b60db.pngdata:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​编辑


https://img-blog.csdnimg.cn/direct/398f0ecf78374dbb8563a72c5760875d.png​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑


       那么在能获取标志位情况下,我们就完全可以每次复位后去读取上次的复位源标志位,并且通过用户代码编写,返回0,1,2,3等用户自定义的错误码,再去对对应的问题进行具体分析,相信可以极大情况下,方便解决设备复位问题!


       大家可能会问,为什么复位以后我们能够读取?
       那是因为该寄存器仅在电源复位时被清零!

https://img-blog.csdnimg.cn/direct/0cf286c4c05341eb8d14dc39cd64b947.png​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑


代码
uint32_t* RCU_RSTSCK = (uint32_t*)(RCU_BASE_ADDR + RCU_RSTSCK_OFFSET);

    if (*RCU_RSTSCK & 0x01)
    {
      // 外部复位源
    }
    else if (*RCU_RSTSCK & 0x02)
    {
      // 低功耗模式复位
    }
    else if (*RCU_RSTSCK & 0x04)
    {
      // 外部复位源唤醒复位
    }
    else
    {
      // 其他复位源
    }

头文件
#define RCU_RSTSCK_OFFSET 0x24
#define RCU_BASE_ADDR 0x40021000






       如果说,想要去了解其他错误的判断,不单单只是复位源,这里推荐一个非常好用的开源工具:CmBacktrace
       详细见:
https://gitee.com/Armink/CmBacktrace

https://img-blog.csdnimg.cn/direct/1f145262b372458b8122e4097dbae244.png​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑

       这个东西,用过都说好!

       欢迎私信留言讨论!

       自此结束,目前
       GD32F103RCT6 基础型 目前已经完成了教程文档开发、源码编写、UCOSIII移植、函数重写,正在进行电机驱动开发
       GD32F107RCT6 互联型 目前正在制作多路CAN、485、以太网通讯,输入输出隔离的开发以及源码编写和UCOSIII移植
       GD32F407ZET6 目前尚未开始

       我会在后续时机合适的时候发表,关注我!第一时间了解!

tpgf 发表于 2024-4-2 12:10

源寄存器是什么意思应该 对应的目标寄存器是吗

八层楼 发表于 2024-4-2 12:46

是不是所有的源寄存器都支持读写呢

观海 发表于 2024-4-2 13:18

非正常复位之后所有寄存器的值是不是就是随机的了啊

guanjiaer 发表于 2024-4-2 13:50

不同的复位方式所涉及到的寄存器是不一样的吧

keaibukelian 发表于 2024-4-2 14:23

复位源寄存器只用于判断单片机复位的原因的吗

caigang13 发表于 2024-4-2 21:00

收藏了,支持楼主。

heimaojingzhang 发表于 2024-4-2 23:50

当程序进行复位之后 通过读取特定的寄存器 可以判断之前的复位原因?

chenjun89 发表于 2024-4-3 07:56

可以写成系列文章了

cornrn 发表于 2025-9-16 16:19

#include "gd32f1x0_rcu.h"// 必须包含RCU寄存器定义头文件

void check_reset_source(void) {
    // 1. 读取复位状态寄存器(使用GD32标准库宏定义,避免手动计算地址)
    uint32_t reset_flags = RCU->RSTSCK;// RCU->RSTSCK 等价于访问复位状态寄存器
   
    // 2. 解析复位源(根据GD32F1x0数据手册,各bit定义如下)
    if (reset_flags & RCU_RSTSCK_PORRST) {
      // 上电复位(POR)/掉电复位(PDR)
    } else if (reset_flags & RCU_RSTSCK_EXTRST) {
      // 外部复位(NRST引脚)
    } else if (reset_flags & RCU_RSTSCK_WDTRST) {
      // 窗口看门狗(WWDG)复位 或 独立看门狗(IWDG)复位
    } else if (reset_flags & RCU_RSTSCK_SWRST) {
      // 软件复位(通过NVIC_SystemReset()触发)
    } else if (reset_flags & RCU_RSTSCK_LPRST) {
      // 低功耗复位(从深度睡眠模式唤醒时的复位)
    }
   
    // 3. 清除复位标志(必须手动清除,否则下次读取仍为旧值)
    RCU->RSTSCK |= RCU_RSTSCK_RSTFCLR;// 写1清除所有复位标志
}
页: [1]
查看完整版本: 手把手教你嵌入式国产化-杂项-GD32复位源寄存器(判断复位/重启生成)