瑞萨e2studio(21)----看门狗WDT

63 篇文章 104 订阅

概述

WDT(Watchdog Timer)和IWDT(Independent Watchdog Timer)都是微控制器中的看门狗定时器,它们的主要功能是在系统发生故障时触发重置,以确保系统能够自动恢复。但它们之间存在一些区别:
时钟源:WDT通常使用系统时钟作为时钟源,而IWDT使用独立的内部低速时钟源。因此,IWDT不依赖于系统时钟,即使系统时钟失效,IWDT仍能正常工作。
供电:WDT和系统共享电源,而IWDT通常拥有独立的电源。这意味着当系统电源出现问题时,IWDT仍可以继续工作。
控制和配置:WDT通常提供更多的控制和配置选项,如可编程超时时间、预分频器等,而IWDT的配置可能较为简单。
应用场景:WDT适用于需要更多控制和配置选项的场景,而IWDT适用于需要独立于系统时钟和电源的场景,例如对系统稳定性和安全性要求较高的应用。
可靠性:由于IWDT使用独立的时钟源和电源,其可靠性通常优于WDT。
总之,WDT和IWDT虽然都是看门狗定时器,但在时钟源、供电、控制和配置等方面存在区别。选择使用WDT还是IWDT取决于具体应用的需求和设计考虑。
最近在弄ST和瑞萨RA的课程,需要RA样片的可以加群申请:6_15061293 。

视频教学

https://www.bilibili.com/video/BV1fg4y1L75m/

瑞萨e2studio(22)--看门狗WDT

csdn课程

csdn课程更加详细。
https://edu.csdn.net/course/detail/36131

样品申请

https://www.wjx.top/vm/wBbmSFp.aspx#

完整代码下载

https://download.csdn.net/download/qq_24312945/87750334

硬件准备

首先需要准备一个开发板,这里我准备的是芯片型号R7FA4M2AD3CFP的开发板:
在这里插入图片描述

新建工程

在这里插入图片描述

工程模板

在这里插入图片描述

保存工程路径

在这里插入图片描述

芯片配置

本文中使用R7FA4M2AD3CFP来进行演示。
在这里插入图片描述

工程模板选择

在这里插入图片描述

时钟配置

开发板上的外部高速晶振为12M,需要修改XTAL为12M.
在这里插入图片描述

uart配置

点击Stacks->New Stack->Driver->Connectivity -> UART (r_sci_uart)。
在这里插入图片描述

uart属性配置

在这里插入图片描述

设置e2studio堆栈

在这里插入图片描述

e2studio的重定向printf设置

在这里插入图片描述
C++ 构建->设置->GNU ARM Cross C Linker->Miscellaneous去掉Other linker flags中的 “–specs=rdimon.specs”

在这里插入图片描述

printf输出重定向到串口

打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。
注意一定要加上头文件#include <stdio.h>

#include <stdio.h>

fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
        uart_send_complete_flag = true;
    }
}
#ifdef __GNUC__                                 //串口重定向
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
        err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
        if(FSP_SUCCESS != err) __BKPT();
        while(uart_send_complete_flag == false){}
        uart_send_complete_flag = false;
        return ch;
}
int _write(int fd,char *pBuffer,int size)
{
    for(int i=0;i<size;i++)
    {
        __io_putchar(*pBuffer++);
    }
    return size;
}

RTC配置

点击Stacks->New Stack->Driver->Timers -> Realtime Clock(r_rtc)。
在这里插入图片描述

RTC属性配置

在这里插入图片描述

WDT配置

点击Stacks->New Stack->Monitoring -> Watchdog(r_wdt)。
在这里插入图片描述

WDT属性配置

在这里插入图片描述

R_WDT_Open()函数原型

在这里插入图片描述

可以用R_WDT_Open()函数进行初始化和开启WDT。

 /* Open the module. */
    err = R_WDT_Open(&g_wdt0_ctrl, &g_wdt0_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);

R_WDT_Refresh()函数原型

在这里插入图片描述

可以用R_WDT_Refresh()函数进行喂狗操作。

	/* Refresh before the counter underflows to prevent reset or NMI. */
	err = R_WDT_Refresh(&g_wdt0_ctrl);
	assert(FSP_SUCCESS == err);

R_WDT_CounterGet()函数原型

在这里插入图片描述

可以用R_WDT_CounterGet()函数获取当前的计数值。

 /* Read the current WDT counter value. */
	err = R_WDT_CounterGet(&g_wdt0_ctrl, &wdt_counter);
	assert(FSP_SUCCESS == err);

WDT周期设定

通过查阅数据手册,可以得知WDT使用的时钟为PCLKB。
在这里插入图片描述

在本案例中,使用的PCLKB时钟为25MHz。
在这里插入图片描述

WDT从PCLKB运行,依据上文的设定,PCLKB周期如下所示。

参数
PLCKB25MHz
分频PLCK/8192
超时周期16384 cycles
WDT时钟频率25MHz / 8192 = 3051.7578 Hz
单周期时间1 / 2929.6875 Hz = 327.68us
溢出时间341.33 us * 16384 cycles = 5.3687 seconds

上述可以看到在该设置下的溢出时间为5.59s,那么1s的计数为1s/341.33 us=2930。

WDT计数周期

WDT计数是从最高一直减到0,当到0时候触发复位。

在这里插入图片描述

注意事项

如果使用J-Link调试器进行调试的话需要加上这一句话。

       R_DEBUG->DBGSTOPCR_b.DBGSTOP_WDT = 0;

演示效果

设置每过1s打印一次当前时间,分别设置喂狗和不喂狗,结果如下。
延迟1s的计数为1s/327.68 us=3052,打印为13337,由于是向下计数,16384-3052=13332,符合计算值。
在这里插入图片描述

当不执行喂狗时候,计数值到0时会进行复位,2个复位之间为5.4s,符合计算的5.3687s。

在这里插入图片描述

完整代码

    /* Initialize the RTC module*/
       err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
       /* Handle any errors. This function should be defined by the user. */
       assert(FSP_SUCCESS == err);
       /* Set the RTC clock source. Can be skipped if "Set Source Clock in Open" property is enabled. */
       R_RTC_ClockSourceSet(&g_rtc0_ctrl);

       /* R_RTC_CalendarTimeSet must be called at least once to start the RTC */
       R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
       /* Set the periodic interrupt rate to 1 second */
       R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);



       /* Open the module. */
        err = R_WDT_Open(&g_wdt0_ctrl, &g_wdt0_cfg);
        /* Handle any errors. This function should be defined by the user. */
        assert(FSP_SUCCESS == err);
        /* In register start mode, start the watchdog by calling R_WDT_Refresh. */
        err = R_WDT_Refresh(&g_wdt0_ctrl);
        assert(FSP_SUCCESS == err);
        printf("starting up !\n");
        uint32_t wdt_counter = 0U;

        while(1)
               {
                   if(rtc_flag)
                   {
                       /* Read the current WDT counter value. */
                       err = R_WDT_CounterGet(&g_wdt0_ctrl, &wdt_counter);
                       assert(FSP_SUCCESS == err);
                       printf("wdt_counter=%d\n",wdt_counter);
                       rtc_flag=0;
                       /* Refresh before the counter underflows to prevent reset or NMI. */
                       err = R_WDT_Refresh(&g_wdt0_ctrl);
                       assert(FSP_SUCCESS == err);
                   }
               }     

最后

以上的代码会在Qqun里分享。Qqun:615061293。
或者关注『记帖』,持续更新文章和学习资料!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记帖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值