手把手教你嵌入式国产化-杂项-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.pngdata: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.pngdata:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑
那么在能获取标志位情况下,我们就完全可以每次复位后去读取上次的复位源标志位,并且通过用户代码编写,返回0,1,2,3等用户自定义的错误码,再去对对应的问题进行具体分析,相信可以极大情况下,方便解决设备复位问题!
大家可能会问,为什么复位以后我们能够读取?
那是因为该寄存器仅在电源复位时被清零!
https://img-blog.csdnimg.cn/direct/0cf286c4c05341eb8d14dc39cd64b947.pngdata: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.pngdata:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑
这个东西,用过都说好!
欢迎私信留言讨论!
自此结束,目前
GD32F103RCT6 基础型 目前已经完成了教程文档开发、源码编写、UCOSIII移植、函数重写,正在进行电机驱动开发
GD32F107RCT6 互联型 目前正在制作多路CAN、485、以太网通讯,输入输出隔离的开发以及源码编写和UCOSIII移植
GD32F407ZET6 目前尚未开始
我会在后续时机合适的时候发表,关注我!第一时间了解!
源寄存器是什么意思应该 对应的目标寄存器是吗 是不是所有的源寄存器都支持读写呢
非正常复位之后所有寄存器的值是不是就是随机的了啊
不同的复位方式所涉及到的寄存器是不一样的吧
复位源寄存器只用于判断单片机复位的原因的吗 收藏了,支持楼主。 当程序进行复位之后 通过读取特定的寄存器 可以判断之前的复位原因?
可以写成系列文章了 #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]