四、GD32 MCU 常见外设介绍(9)9.FWDG 模块介绍

9.1.FWDG 简介

本章我们主要分析独立看门狗(FWDG)的功能框图和它的应用。独立看门狗用通俗一点的话来解释就是一个12位的递减计数器,当计数器的值从某个值一直减到0的时候,系统就会产生一个复位信号,即FWDGTRSTF。如果在计数没减到0之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍能工作。独立看门狗定时器有独立的时钟源(IRC40K) 。 即使主时钟失效, FWDGT依然 能保持正常工作状态, 适用于需要独立环境且对计时精度要求不高的场合。

9.2.GD32 FWDG 外设原理简介

因篇幅有限,本文无法详细介绍GD32所有系列FWDG外设接口,下面以GD32F30x为列,着重介绍下GD32F30x的FWDG外设简介和结构框图,后介绍下各个系列的差异。

GD32 FWDG 主要特性

◼ 自由运行的12位向下计数器;

◼ 如果看门狗定时器被使能,那么当向下计数器的值达到0时产生系统复位;

◼ 独立时钟源,独立看门狗定时器在主时钟故障(例如待机和深度睡眠模式下)时仍能工作;

◼ 独立看门狗定时器硬件控制位,可以用来控制是否在上电时自动启动独立看门狗定时器;

◼ 可以配置独立看门狗定时器在调试模式下选择停止还是继续工作。

FWDG时钟:如FWDG框图的①所示, FWDG的时钟由独立的RC振荡器IRC40K提供,即使主时钟发生故障它仍然有效,非常独立。IRC的频率根据温度和工作场合会有一定的漂移,我们一般取40KHZ,所以FWDG的定时时间并不一定非常精确,只适用于对时间精度要求相对较低的场合。

计数器时钟:如FWDG框图的②所示, 递减计数器的时钟由IRC40K经过一个8位的预分频器得到,我们可以操作预分频器寄存器FWDG_PSC来设置分频因子,分频因子可以是:[4,8,16,32,64,128,256]。

计数器:如图 0-28 FWDG框图的③所示, FWDG的计数器是一个12位的递减计数器,最大值为0XFFF,当计数器减到0时,会产生一个复位信号: FWDGTRSTF,让程序重新启动运行,如果在计数器减到0之前刷新了计数器的值的话,就不会产生复位信号,重新刷新计数器值的这个动作我们俗称喂狗。

重装载寄存器:如FWDG框图的④所示, 重装载寄存器是一个12位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着FWDG的溢出时间。超时时间Tout = (42^prv) / 40 rlv (s) ,prv是预分频器寄存器的值,rlv是重装载寄存器的值。

控制寄存器:如FWDG框图的⑤所示, 控制寄存器FWDG_CTL可以说是独立看门狗的一个控制寄存器,主要有三种控制方式,往这个寄存器写入下面三个不同的值有不同的效果。具体如下表控制寄存器取值枚举

 状态寄存器:如FWDG框图的⑥所示, 状态寄存器STAT只有位0:PUD和位1:RUD有效,这两位只能由硬件操作,软件操作不了。RUD:看门狗计数器重装载值更新,硬件置1表示重装载值的更新正在进行中,更新完毕之后由硬件清0。PUD: 看门狗预分频值更新,硬件置‘1‘指示预分频值的更新正在进行中,当更新完成后,由硬件清0。所以只有当RUD/PUD等于0的时候才可以更新重装载寄存器/预分频寄存器。

注意

  1. 如果在选项字节中打开了“硬件看门狗定时器”功能,那么在上电的时候看门狗定时器就被自动打开。为了避免系统复位,软件应该在计数器达到0x000之前重装载计数器;

  2. 如果DBG控制寄存器0(DBG_CTL0) 中的FWDGT_HOLD位被清0,即使Cortex®-M4内核停止(调试模式下) 独立看门狗定时器依然工作。如果FWDGT_HOLD位置1,独立看门狗定时器将在调试模式下停止工作。

各系列 FWDG 功能差异

F4xx系例FWDG时钟为32K,因此要注意FWDG的定时时间。

9.3.硬件连接说明

FWDG属于单片机内部资源,不需要外部电路,需要一个外部的按键和LED,通过按键来喂狗,喂狗成功LED亮,喂狗失败,程序重启,LED灭一次。

9.4.软件配置说明

本小节讲解FWDG_Example例程中FWDG模块的实验讲解,主要包括FWDG配置函数、FWDG喂狗函数、主函数介绍以及运行结果。

FWDG 配置函数

外设时钟配置

外设时钟配置如代码清单FWDG例程时钟配置所示,在GD32全系列MCU中需打开GPIOA(LED)的时钟,另外,在GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X || GD32F1X0 || GD32F3X0 || GD32E230中需要打开IRC40K,GD32F4XX中需要打开IRC32K。

void rcu_config(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X || GD32F1X0 || GD32F4XX || GD32F3X0 || 
GD32E230rcu_periph_clock_enable(RCU_GPIOA);
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X || GD32F1X0 || GD32F3X0 || GD32E230
/* enable IRC40K */rcu_osci_on(RCU_IRC40K);/* wait till IRC40K is ready */while(SUCCESS != rcu_osci_stab_wait(RCU_IRC40K)){} 
#elif GD32F4XX 
/* enable IRC32K */rcu_osci_on(RCU_IRC32K);/* wait till IRC32K is ready */while(SUCCESS != rcu_osci_stab_wait(RCU_IRC32K)){} 
#endif
#endif
}

GPIO(LED)引脚配置

GPIO引脚配置如代码清单FWDG例程GPIO(LED)引脚配置所示,GD32F10X、GD32F30X、GD32F20X、GD32E10X系列GPIO配置相同, PA3、PA4作为LED引脚配置为推挽输出模式;GD32F1X0、GD32F4XX、GD32F3X0、GD32E23X系列GPIO配置基本相同。配置完成后将PA3 和PA4拉低。

void gpio_led_config(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10Xgpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E230gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_4);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
#endif 
GPIO_BC(GPIOA) = GPIO_PIN_3;
GPIO_BC(GPIOA) = GPIO_PIN_4;
}

按键初始化配置

按键初始化配置如代码清单按键初始化配置所示。本例程中默认使用PA0下降沿进入中断,GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X系列配置基本相同,GD32F1X0 || GD32F3X0系列配置类似。GD32E230中断分组只有抢占优先级没有子优先级。

void key_init(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
rcu_periph_clock_enable(RCU_AF);gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_IRQn, 2U, 0U);
/* connect key EXTI line to key GPIO pin */
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_0);
/* configure key EXTI line */
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_0);
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E230
#if defined GD32F1X0 || GD32F3X0 
rcu_periph_clock_enable(RCU_CFGCMP);
/* configure button pin as input */gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_0);
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_1_IRQn, 2U, 0U);
#elif defined GD32E230
rcu_periph_clock_enable(RCU_CFGCMP);
/* configure button pin as input */gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_0);
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_1_IRQn, 2U);
#elif defined GD32F4XX
rcu_periph_clock_enable(RCU_SYSCFG);
/* configure button pin as input */gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_0);
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_IRQn, 2U, 0U);
#endif 
/* connect key EXTI line to key GPIO pin */
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0);
/* configure key EXTI line */
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_0);
#endif 
}

FWDG 配置函数

FWDG配置函数如代码清单FWDG配置配置所示。当时钟为40K时,溢出时间Tout =prv/40 rlv (s),prv可以是[4,8,16,32,64,128,256];rlv的取值范围为0~0XFFF。如果我们需要设置1s的超时溢出, prv 可以取 FWDGT_PSC_DIV64 , rlv 取 625 ,即调用 : fwdgt_config(625,FWDGT_PSC_DIV64)。Tout=64/40625=1s。GD32F4XX系列IRC为32K则定时时间1.25s。

void FWDGT_init(void)
{
/* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
|| GD32F1X0 || GD32F3X0 || GD32E23X*/
/* confiure FWDGT counter clock: 32KHz(IRC32K) / 64 = 0.5 KHz GD32F4XX*/fwdgt_config(625, FWDGT_PSC_DIV64); /* after 1.x seconds to generate a reset */fwdgt_enable();
}

中断喂狗

中断喂狗函数如代码清单中断喂狗所示。当进进入PA0外部中断时执行喂狗函数。

#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X || GD32F4XX
void EXTI0_IRQHandler(void)
{
/* make sure whether the tamper key EXTI Line is interrupted */if(RESET != exti_interrupt_flag_get(EXTI_0)){/* reload FWDGT counter */fwdgt_counter_reload();}/* clear the interrupt flag bit */exti_interrupt_flag_clear(EXTI_0);
}
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E230
void EXTI0_1_IRQHandler(void)
{
/* make sure whether the tamper key EXTI Line is interrupted */if(RESET != exti_interrupt_flag_get(EXTI_0)){/* reload FWDGT counter */fwdgt_counter_reload();}/* clear the interrupt flag bit */exti_interrupt_flag_clear(EXTI_0);
}
#endif

主函数说明

主函数如代码清单FWDG例程主函数所示,主函数中我们初始化好LED和按键相关的配置,设置FWDG 1s 超时溢出之后,进入while死循环,通过按键来喂狗,如果喂狗成功,则LED2(PA4)点亮,如果喂狗失败的话,系统重启,程序重新执行,当执行到rcu_flag_get函数的时候,则会检测到是FWDG复位,然后让LED1(PA3)亮。如果喂狗一直失败的话,则会一直产生系统复位,加上前面延时的效果,则会看到LED1(PA3)一直闪烁。

int main(void)
{/* peripheral clock enable */rcu_config();
/* config systick */systick_config(); /* GPIO config */gpio_led_config();
key_init();
delay_1ms(500);
FWDGT_init();
/* check if the system has resumed from FWDGT reset */
if(RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)){/* turn on LED1 */
GPIO_BOP(GPIOA) = GPIO_PIN_3;
/* clear the FWDGT reset flag */
rcu_all_reset_flag_clear();
while(1);
}
else{
/* turn on LED2 */
GPIO_BOP(GPIOA) = GPIO_PIN_4;
}while(1)
{
}
}

运行结果

把编译好的程序下载到开发板,在1s的时间内通过按键来不断的喂狗,如果喂狗失败,LED1闪烁。如果一直喂狗成功,则LED2常亮。

9.5.FWDG 使用注意事项

(1) FWDG在Debug仿真时,请将DBG控制寄存器0(DBG_CTL0) 中的FWDGT_HOLD位置1,来关闭FWDG功能。

(2) 没有开启软件看门狗时,程序自动复位,可能在选项字节里开启了硬件看门狗。

(3) 同时使用FWDG、Standby或Deep-sleep模式时,无法喂狗:在reload命令后,硬件清除reload信号之前,进入Deepsleep或者standby模式,会导致后续reload命令无法正常响应。软件保证在reload命令和进入Deepsleep/standby mode的命令中间有3个LXTAL clock(100us)以上的时间间隔。

(4) 由于环境温度影响,独立看门狗定时器超时周期会有些许波动,可以通过校准IRC40K使独立看门狗定时器超时更加精确。

更多GD32 MCU相关咨询:https://www.gd32bbs.com/ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/875793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习算法,支持再学习功能,不断提升系统精准度的智慧地产开源了。

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。通过计算机视觉和…

Java基础巩固——JDK 8、9新增接口的特性(接口中定义非抽象方法、静态方法和私有方法)

#Java学了这么久,项目也做了?基础知识还不巩固?快来关注我的这篇系列博客——Java基础复习巩固吧# 目录 引言 一、JDK8新特性:允许在接口中定义非抽象方法和静态方法。 注意事项 二、JDK9新特性:允许在接口中定义p…

ScriptableObject使用

资料 Scripting/Create modular game architecture in Unity with ScriptableObjects 脚本文档 基础 SO是一个Unity对象,继承UnityEngine.Objec, SO最大的特点是实例文件可共享,有点类似静态数据,同一个实例文件可被多个对象引…

matlab实验:实验六MATLAB 数值计算与符号运算

题目1:(线性方程组数值求解) 1. 用不同的方法求解下面方程:(方程原式参考 P369 实验 10,第 1 题) 第 1 种,左除和求逆函数(inv) 第 2 种 , 用 符 号 运 算 的…

JAVA基础知识4(static、继承)

JAVA基础知识4 static静态成员变量静态成员方法解释注意点 继承父类(基类或超类)子类(派生类)使用继承的示例解释运行结果 成员变量的访问特点成员方法的访问特点构造方法的访问特点 Java项目,包和类之间的联系包的概念…

vue elementui 在table里使用el-switch

<el-table-columnprop"operationStatus"label"状态"header-align"center"align"center"><template slot-scope"scope"><el-switch active-value"ENABLE" inactive-value"DISABLE" v-mod…

使用框架构建React Native应用程序的最佳实践

在React Conf上&#xff0c;我们更新了关于开始构建React Native应用程序的最佳工具的指导&#xff1a;一个React Native框架——一个包含所有必要API的工具箱&#xff0c;让您能够构建生产就绪的应用程序。 现在推荐使用React Native框架&#xff08;如Expo&#xff09;来创建…

Spring 依赖注入02

文章目录 1. 核心概念2. 依赖注入的方式3. 构造函数注入3.1 构造函数注入的优点包括&#xff1a; 4. 设值注入4.1 设值注入的特点和优点4.2 使用设值注入的注意事项 5. 接口注入5.1 接口注入的基本概念&#xff1a;5.2 使用接口注入的注意事项&#xff1a; 依赖注入&#xff08…

代码随想录day23 ||39组合总和1 40组合总和2 131分割回文串

39组合总和1 力扣题目链接 题目描述&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 cand…

【C语言】两个数组比较详解

目录 C语言中两个数组比较详解1. 逐元素比较1.1 示例代码1.2 输出结果1.3 分析 2. 内置函数的使用2.1 示例代码2.2 输出结果2.3 分析 3. 在嵌入式系统中的应用3.1 示例代码3.2 输出结果3.3 分析 4. 拓展技巧4.1 使用指针优化比较4.2 输出结果4.3 分析 5. 表格总结6. 结论7. 结束…

高级及架构师高频应用型面试题

一、微服务多节点批量应该怎么设计&#xff1f; 1、异步任务分类&#xff1a; 周期性定时任务调度任务批量任务 2、需要考虑并解决的问题&#xff1a; 2.1、避免同一任务同时被多个节点捞取。 1&#xff09;数据库的行级锁 2&#xff09;redis分布式锁 3&#xff09;quartz…

后端面试题日常练-day06 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备&#xff0c;答案在文末 在Java中&#xff0c;以下哪个关键字用于表示类之间的关联性&#xff0c;表明一个类包含另一个类的对象&#xff1f; a) include b) contain c) reference d) composition Java中的方法重写&#xff…

Python写UI自动化--playwright(通过UI文本匹配实现定位)

本篇简单拓展一下元素定位技巧&#xff0c;通过UI界面的文本去实现定位 目录 匹配XPath 匹配文本元素 .count()统计匹配数量 处理匹配文本返回多个元素 1、使用.nth(index)选择特定元素: 2、获取所有匹配的元素并遍历: 3、错误处理: 匹配XPath 比如我们要定位到下图的…

C++笔试强训8

文章目录 一、选择题1-5题6-10题 二、编程题题目一题目二 一、选择题 1-5题 根据下面的定义故选A。 函数重载:在相同作用域中&#xff0c;函数名字相同&#xff0c;参数列表不同的一系列函数称为函数重载参数列表不同具体的体现:参数个数不同参数类型不同类型的次序不同注意:…

单元测试--Junit

Junit是Java的单元测试框架提供了一些注解方便我们进行单元测试 1. 常用注解 常用注解&#xff1a; TestBeforeAll&#xff0c;AfterAllBeforeEach&#xff0c;AfterEach 使用这些注解需要先引入依赖&#xff1a; <dependency><groupId>org.junit.jupiter<…

6 C 语言指针的奥秘:理论与实践详解

目录 1 变量访问机制 1.1 内存地址 1.2 变量的直接访问 1.3 变量的间接访问 2 指针变量及其内存大小 2.1 指针与指针变量 2.2 指针变量的定义格式 2.3 指针变量的内存大小 3 取地址操作符与取值操作符 3.1 取地址操作符 & 3.2 取值操作符 * 3.3 解引用与数据类…

Xcode是什么?它在iOS开发中的作用和功能有哪些?

Xcode是苹果公司为macOS平台开发的一款集成开发环境&#xff08;Integrated Development Environment&#xff0c;简称IDE&#xff09;&#xff0c;它主要用于开发iOS、iPadOS、macOS、watchOS和tvOS的应用程序。Xcode集成了从编写代码、界面设计、调试程序、版本控制到应用发布…

【数据结构】顺序表(杨辉三角、简单的洗牌算法)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 欢迎志同道合的朋友一起加油喔 &#x1f4aa;&#x1f4aa;&#x1f4aa; 谢谢你这么帅…

pandas.core.series.Series 转json

在Python中&#xff0c;可以使用Pandas库中的Series.to_json()方法将Series对象转换为JSON格式的字符串。以下是一个简单的例子&#xff1a; import pandas as pd# 创建一个Pandas Seriess pd.Series({a: 1, b: 2, c: 3})# 转换为JSON字符串json_str s.to_json(orientrecords…

Android SurfaceFlinger——通知消费流程(三十五)

上一篇文章介绍了 onFrameAvailable() 函数的流程&#xff0c;最终回调到了 BLASTBufferQueue 中&#xff0c;这里测处理跟 Android 老版本还是有区别的&#xff0c;在 BLASTBufferQueue 中通过提交事务的方式通知 SurfaceFlinger 进行更新&#xff0c;而不是老版本中的直接调用…