WDT模块介绍
参考<<Renesas RA2L1 Group User’s Manual: Hardware>>的章节<<23. Watchdog Timer (WDT)>>
特征
- 14位递减计数器,溢出时可以产生复位,NMI中断,溢出中断。
- 时钟源PCLKB,4, 64, 128, 512, 2048, 8192分频。
- 可配置复位,喂狗错误,溢出自动启动,或者写寄存器启动
- 可配置窗口
- 可配置Sleep-mode时停止
框图
寄存器
WDTRR:写0x00然后写0xFF到WDTRR喂狗。
WDTCR:设置时钟分频,周期,窗口。
WDTSR:当前计数值和溢出状态,喂狗错误状态。
WDTRCR:配置看门狗溢出是产生NMI中断,溢出中断还是直接复位。
WDTCSTPR:配置进入Sleep模式时是否停止看门狗。
OFS0:配置看门狗复位后是否自动使能。和上述寄存器的默认配置。
启动
OFS0中可配置复位自动启动,使用OFS0中的参数。
也可以写WDTRR喂狗后手动启动。
IWDT模块介绍
和WDT差不多,更简单些,相关的寄存器只有IWDTRR,IWDTSR和OSF0.
不再赘述,可以参考手册。《24. Independent Watchdog Timer (IWDT)》
直接基于寄存器进行操作
\ra_cfg\fsp_cfg\bsp\bsp_mcu_family_cfg.h中定义了
#define BSP_MCU_GROUP_RA2L1 (1)
\ra\fsp\src\bsp\cmsis\Device\RENESAS\Include\renesas.h中
#elif BSP_MCU_GROUP_RA2L1
#include "R7FA2L1AB.h"
包含了 #include "R7FA2L1AB.h"
该头文件定义了各外设寄存器基地址
WDT寄存器组结构体是R_WDT
#define R_WDT ((R_WDT_Type *) R_WDT_BASE)
所以直接寄存器操作包含renesas.h即可。
代码如下
void wdt_feed(void)
{
R_WDT->WDTRR = 0x00;
R_WDT->WDTRR = 0xFF;
}
void wdt_init(void)
{
/* PCLKB=24MHz */
rt_kprintf("PCLKB:%d\r\n",BSP_STARTUP_PCLKB_HZ);
rt_kprintf("OFS0:%#x\r\n",*(volatile unsigned int*)0x00000400);
rt_kprintf("OFS0:%#x\r\n",*(volatile unsigned int*)0x00002400);
/* (16384*8192)/24000000 = 5.6S) */
/*
0 0: 1024 cycles (0x03FF)
0 1: 4096 cycles (0x0FFF)
1 0: 8192 cycles (0x1FFF)
1 1: 16384 cycles (0x3FFF)
*/
R_WDT->WDTCR_b.TOPS = 3;
/*
0x1: PCLKB/4
0x4: PCLKB/64
0xF: PCLKB/128
0x6: PCLKB/512
0x7: PCLKB/2048
0x8: PCLKB/8192
*/
R_WDT->WDTCR_b.CKS = 0x08;
/*
Window End Position Select
0 0: 75%
0 1: 50%
1 0: 25%
1 1: 0% (do not specify window end position).
*/
R_WDT->WDTCR_b.RPES = 3;
/*
Window Start Position Select R/W
0 0: 25%
0 1: 50%
1 0: 75%
1 1: 100% (do not specify window start position).
*/
R_WDT->WDTCR_b.RPSS = 3;
/* clear flag*/
R_WDT->WDTSR_b.REFEF = 0;
R_WDT->WDTSR_b.UNDFF = 0;
/* 0: Enable non-maskable interrupt request or interrupt request output
1: Enable reset output */
R_WDT->WDTRCR_b.RSTIRQS = 1;
/*
WDT Count Stop Control Register R/W
0: Disable count stop
1: Stop count on transition to Sleep mode
*/
R_WDT->WDTCSTPR_b.SLCSTP = 1;
}
void hal_entry(void)
{
wdt_init();
wdt_feed();
while (1)
{ rt_thread_mdelay(87);
wdt_feed();
}
}
测试
打印可以看到
PCLKB:24000000
OFS0:ffffffff
OFS0:b8cdf000
时钟源是24MHz
OFS0的值为0xFFFFFFFF,OFS的编程这里不再赘述,后面有机会单独文档说明。
注意这里根据boot swap不同OFS0的地址不一样。
WDTSTRT=1 b17 所以复位是不使能WDT的。
高16位控制WDT,低16位控制IWDT。
另外注意,仿真时不会触发看门狗溢出。
不断修改如下延时时间,看最大到多少时复位。实测88mS复位,87mS不复位。
wdt_init();
wdt_feed();
while (1)
{ rt_thread_mdelay(87);
wdt_feed();
}
问题
WDTCR的CKS设置为8,读出来是0x0F,也就是始终是128分频。CKS好像不能修改。
所以超时时间最大只能设置为16384*128/24000000=0.087S 87mS。
与实际测试一致。