30.3
看门狗启动模式详细介绍

30.3.1
自启动模式
使用自启动模式时,堆栈选项卡上的配置将被忽略。使用BSP选项卡上的OFS设置配置监视器。
在自启动模式下,根据Flash中Option Function Selectregister0(OFS0)的设置,在复位状态释放后自动开始计数。
当选项功能中WDT启动方式选择位(OFS0.wdtstrt)为0时,选择自动启动方式,关闭WDT控制寄存器(WDTCR)、WDT复位控制寄存器(WDTRCR)、WDT计数停止控制寄存器(WDTCSTPR),打开OFS0寄存器的设置。
在复位状态下,WDT寄存器中的选项功能选择寄存器0(OFS0)的设置值如下:
时钟分频比
窗口起始和结束位置
超时时间
复位输出或中断请求
在睡眠模式时计数器停止控制
30.3.2
寄存器启动模式
当WDT的启动模式被选择时OFS0.WDTSTRT位被置1,选择寄存器启动模式和WDT控制寄存器(WDTCR),WDT重置控制寄存器(WDTRCR),WDT计数停止控制寄存器(WDT)释放重置状态后,在WDTCSTPR寄存器中将以下内容设置为休眠模式:
时钟分频比
窗口的开始和结束位置
在WDTCR寄存器中的超时时间
在WDTRCR寄存器中重置输出或中断请求输出
在WDTCSTPR寄存器转换到睡眠模式期间的计数器停止控制
此后,只要计数器在允许刷新的时间段内刷新,计数器的值就会在每次刷新时重置,并继续向下计数。只要计数继续,WDT就不输出复位信号。但是,如果由于程序失控而导致下计数器无法刷新,或者由于计数器在刷新允许的时间之外刷新而发生刷新错误,WDT将输出复位信号或不可屏蔽的中断请求(WDT_NMIUNDF)。可以在WDT复位中断请求选择位(WDTRCR.RSTIRQS)中选择复位输出或中断请求输出。
30.4
WDT实验
在本实验中,我们使用NMI中断输出来进行实验。
30.4.1
硬件设计
WDT一个
LED两个
按键一个
程序设计思路:WDT属于单片机内部资源,不需要外部电路,我们需要两个LED和一个按键来测试看门狗功能。
30.4.2
软件设计
编写两个WDT驱动文件,分别是bsp_wdt.c和bsp_wdt.h,用来存放WDT的初始化配置函数。并开启按键1的中断,在程序运行中,需要使用按键来不停的“喂狗”,以此来防止程序进入复位或者NMI。关于按键中断的相关知识可以查阅本教程第16章ICU—外部中断。
30.4.2.1
新建工程
由于本实验需要LED和按键中断模块,因此我们可以在前面ICU-外部中断章节的实验例程的基础上修改程序。
对于e2 studio开发环境:拷贝一份我们之前的e2s工程“16_ICU_External_Interrupt”,然后将工程文件夹重命名为“30_WDT”,最后再将它导入到我们的e2 studio工作空间中。
对于Keil开发环境:拷贝一份我们之前的Keil工程“16_ICU_External_Interrupt”,然后将工程文件夹重命名为“30_WDT”,并进入该文件夹里面双击Keil工程文件,打开该工程。
工程新建好之后,在工程根目录的“src”文件夹下面新建wdt文件夹,再进入“wdt”文件夹里面新建源文件和头文件:“bsp_wdt.c”和“bsp_wdt.h”。工程文件结构如下。
列表1:文件结构
左右滑动查看完整内容
30_WDT ├─ ...... └─ src ├─ led │ ├─ bsp_led.c │ └─ bsp_led.h ├─ wdt │ ├─ bsp_wdt.c │ └─ bsp_wdt.h └─ hal_entry.c
30.4.2.2
FSP配置
首先打开“30_WDT”项目的FSP配置界面,接下来我们要在这个界面里配置芯片的引脚及其相应的功能。
双击configuration.xml打开配置界面:然后点开依次点击Stacks->New Stack->Search⋯里输入WDT选着Watchdog。

随后点击“Properties”对刚刚加入的WDT模块进行配置。

点击BSP的属性settings界面,找到OFS0 register settings->WDT去设置WDT的属性。

配置完成之后可以按下快捷键“Ctrl+S”保存,最后点右上角的“Generate Project Content”按钮,让软件自动生成配置代码即可。
30.4.2.3
NMI和复位
NMI就是会执行一个中断服务函数,这个中断函数是不能够被打断的,拥有最高的中断优先级。
一般是用在一些重要的数据上面,如果直接复位,这些数据将不被保存,这个时候我们可以写一个服务程序去保存重要数据,这也是看门狗最重要的功能。可以在NMI中断程序中通过软件复位或跳转到程序开头进行程序的重新运行。
复位就是在不断电的情况下,把当前MCU及运行数据清零后的启动。在本实验中使用NMI,也就是不可屏蔽中断来进行试验。
30.4.2.4
WDT初始化函数论
列表2:初始化函数
左右滑动查看完整内容
/* 初始化看门狗并启动计数器*/
voidWDT_Init(void)
{
//如果使用J-Link 调试器进行调试的话需要加上这一句话
R_DEBUG->DBGSTOPCR_b.DBGSTOP_WDT = 0;
//初始化看门狗(WDT)模块
R_WDT_Open(&g_wdt0_ctrl, &g_wdt0_cfg);
/* 刷新看门狗计数器,在这里的作用是初次启动寄存模式下的看门狗计数器
* 要注意,除非是在刷新允许的范围内,否则自启动模式下不应该使用该函数*/
R_WDT_Refresh(&g_wdt0_ctrl);
}
30.4.2.5
喂狗函数
列表3:喂狗函数
左右滑动查看完整内容
/* 喂狗*/
voidWDT_Feed(void)
{
/* 喂狗,刷新递减计数器的值*/
R_WDT_Refresh(&g_wdt0_ctrl);
}
30.4.2.6
NMI中断服务函数
列表4:NMI不可屏蔽中断函数
左右滑动查看完整内容
/* 当看门狗NMI 发生时中断回调*/
voidwdt_callback(wdt_callback_args_t * p_args)
{
/* 防止编译器产生关于函数中没有使用形参的警告*/
(void) p_args;
/* 蓝色LED 亮,请注意,在这里LED 灯函数为代指,
* 实际应用中,这里应该放最重要的函数,比如保存重要数据等*/
LED2_ON;
R_BSP_SoftwareDelay(3, BSP_DELAY_UNITS_SECONDS);
/* 通过软件复位MCU*/
__NVIC_SystemReset();
}
30.4.2.7
主函数
列表5:主函数
左右滑动查看完整内容
/* 按键中断回调函数*/
voidkey1_callback(external_irq_callback_args_t *p_args)
{
(void) p_args;
/* 按键按下触发中断,进行喂狗操作*/
WDT_Feed();
}
voidhal_entry(void)
{
/* 红色LED 亮3 秒*/
LED1_ON;
R_BSP_SoftwareDelay(3,BSP_DELAY_UNITS_SECONDS);
/* 按键中断初始化*/
g_external_irq_on_icu.open(&key1_ctrl, &key1_cfg);
g_external_irq_on_icu.enable(&key1_ctrl);
/* 初始化看门狗并开启计数器*/
WDT_Init();
while(1)
{
/* 红色LED 灯灭,在这里只是代指,
* 实际上这部分应该写需要被WDT 监控的程序*/
LED1_OFF;
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
注
使用J-Link调试器时,WDT计数器不计数,因此不会重置设备或生成NMI。若要使监视器能够在调试时计数并生成重置或NMI,请在应用程序中添加R_DEBUG->DBGSTOPCR_b.DBGSTOP_WDT=0代码。
30.4.2.8
下载验证
将程序下载到开发板内,红色LED灯亮三秒钟,随后启动看门狗,关闭红色LED灯,用户需要在不超过2.6秒左右内的时间按下按键1(SW2)来刷新计数器的数值(喂狗)。一旦超过这个时间,看门狗计数器下溢,将产生NMI,也就是不可屏蔽中断,届时蓝色LED灯会亮三秒,随后软件复位,程序从头运行。
全部0条评论
快来发表一下你的评论吧 !