- 概述
- 硬件准备
- 新建工程
- 工程模板
- 保存工程路径
- 芯片配置
- 工程模板选择
- WDT配置
- WDT属性配置
- RTC配置
- RTC属性配置
- 设置e2studio堆栈
- e2studio的重定向printf设置
- uart配置
- uart属性配置
- printf输出重定向到串口
- R_WDT_Open()函数原型
- R_WDT_Refresh()函数原型
- R_WDT_CounterGet()函数原型
- WDT周期设定
- WDT计数周期
- 演示效果
- 完整代码
- 最后
本篇文章主要介绍如何使用e2studio对瑞萨进行看门狗WDT配置,并且配置RTC时钟产生1s的周期中断,通过串口打印查看看门狗WDT的计数值。
硬件准备首先需要准备一个开发板,这里我准备的是芯片型号R7FA2L1AB2DFL的开发板:
新建工程 工程模板 保存工程路径 芯片配置本文中使用R7FA2L1AB2DFL来进行演示。
点击Stacks->New Stack->Driver->Monitoring -> Watchdog Driver on r_wdt。
WDT属性配置 RTC配置点击Stacks->New Stack->Driver->Timers -> RTC Driver on r_rtc。
C++ 构建->设置->GNU ARM Cross C linker->Miscellaneous去掉Other linker flags中的 “–specs=rdimon.specs”
点击Stacks->New Stack->Driver->Connectivity -> UART Driver on r_sci_uart。
配置串口,用于打印数据。
打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。
注意一定要加上头文件#include
#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_uart0_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
R_WDT_Open()函数原型
故可以用R_WDT_Open()函数进行初始化和开启WDT。
err = R_WDT_Open(&g_wdt0_ctrl, &g_wdt0_cfg);
assert(FSP_SUCCESS == err);
R_WDT_Refresh()函数原型
故可以用R_WDT_Refresh()函数进行喂狗操作。
err = R_WDT_Refresh(&g_wdt0_ctrl);
assert(FSP_SUCCESS == err);
R_WDT_CounterGet()函数原型
故可以用R_WDT_CounterGet()函数获取当前的计数值。
err = R_WDT_CounterGet(&g_wdt0_ctrl, &wdt_counter);
assert(FSP_SUCCESS == err);
WDT周期设定
通过查阅数据手册,可以得知WDT使用的时钟为PCLKB。
在本案例中,使用的PCLKB时钟为24MHz。
WDT从PCLKB运行,依据上文的设定,PCLKB周期如下所示。
Parameter Equal to IPLCKB/2 24MHz Clock division ratio PLCK/8192 Timeout period 16384 cycles WDT clock frequency 24MHz / 8192 = 2929.6875 Hz Cycle time 1 / 2929.6875 Hz = 341.33 us Timeout 341.33 us * 16384 cycles = 5.59 seconds
上述可以看到在该设置下的溢出时间为5.59s,那么1s的计数为1s/341.33 us=2930。
WDT计数周期
WDT计数是从最高一直减到0,当到0时候触发复位。
演示效果
设置每过1s打印一次当前时间,分别设置喂狗和不喂狗,结果如下。
延迟1s的计数为1s/341.33us=2930,打印为13460,由于是向下计数,16384-2930=13554,符合计算值。
当不执行喂狗时候,计数值到0时会进行复位,2个复位之间为5.595s,符合计算的5.59s。
完整代码
#include "hal_data.h"
#include
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
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_uart0_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;ievent == RTC_EVENT_PERIODIC_IRQ)
rtc_flag=1;
}
void hal_entry(void)
{
err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
assert(FSP_SUCCESS == err);
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
assert(FSP_SUCCESS == err);
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
R_DEBUG->DBGSTOPCR_b.DBGSTOP_WDT = 0;
if (R_SYSTEM->RSTSR1_b.WDTRF)
{
R_SYSTEM->RSTSR1 = 0U;
}
err = R_WDT_Open(&g_wdt0_ctrl, &g_wdt0_cfg);
assert(FSP_SUCCESS == err);
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)
{
err = R_WDT_CounterGet(&g_wdt0_ctrl, &wdt_counter);
assert(FSP_SUCCESS == err);
printf("wdt_counter=%dn",wdt_counter);
rtc_flag=0;
err = R_WDT_Refresh(&g_wdt0_ctrl);
assert(FSP_SUCCESS == err);
}
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
最后
以上的代码会在Q群里分享。QQ群:615061293。
或者关注微信公众号『记帖』,持续更新文章和学习资料,可加作者的微信交流学习!



