瑞萨e2studio.20--独立看门狗IWDT
- 概述
- 视频教学
- csdn课程
- 样品申请
- 完整代码下载
- 硬件准备
- 新建工程
- 工程模板
- 保存工程路径
- 芯片配置
- 工程模板选择
- 时钟配置
- uart配置
- uart属性配置
- 设置e2studio堆栈
- e2studio的重定向printf设置
- printf输出重定向到串口
- RTC配置
- RTC属性配置
- IWDT配置
- IWDT属性配置
- OFS0属性配置
- R_IWDT_Open()函数原型
- R_IWDT_Refresh()函数原型
- R_IWDT_CounterGet()函数原型
- IWDT周期设定
- IWDT计数周期
- 演示效果
- 完整代码
概述
本文主要阐述了如何借助e2studio工具对瑞萨独立看门狗IWDT进行配置设置,同时设置RTC时钟产生每秒的周期性中断,并通过串口输出观察独立看门狗IWDT的计数情况。
最近在弄ST和瑞萨RA的课程,需要RA样片的可以加群申请:6_15061293 。
视频教学
https://www.bilibili.com/video/BV1TM4y1h7Xx/
瑞萨e2studio(20)----RTC时钟日历&闹钟&周期性中断
csdn课程
csdn课程更加详细。
https://edu.csdn.net/course/detail/36131
样品申请
https://www.wjx.top/vm/wBbmSFp.aspx#
完整代码下载
https://download.csdn.net/download/qq_24312945/87750302
硬件准备
首先需要准备一个开发板,这里我准备的是芯片型号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属性配置
IWDT配置
点击Stacks->New Stack->Monitoring -> Independent Watchdog(r_iwdt)。
IWDT属性配置
OFS0属性配置
R_IWDT_Open()函数原型
故可以用R_IWDT_Open()函数进行初始化和开启IWDT。
/* Open the module. */err = R_IWDT_Open(&g_iwdt0_ctrl, &g_iwdt0_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);
R_IWDT_Refresh()函数原型
故可以用R_IWDT_Refresh()函数进行喂狗操作。
/* Refresh before the counter underflows to prevent reset or NMI. */(void) R_IWDT_Refresh(&g_iwdt0_ctrl);
R_IWDT_CounterGet()函数原型
故可以用R_IWDT_CounterGet()函数获取当前的计数值。
uint32_t iwdt_counter = 0U;err = R_IWDT_CounterGet(&g_iwdt0_ctrl, &iwdt_counter);
IWDT周期设定
IWDTLOCO 是一个具有低功耗特性的独立看门狗定时器片上振荡器,可以在不消耗过多电力的情况下,提供稳定的时钟信号来驱动看门狗定时器。这种振荡器对于低功耗应用和可靠性要求较高的系统非常有用。
IWDT的时钟频率为15kHz,依据上文的设定,IWDT周期如下所示。
参数 | 值 |
---|---|
IWDTLOCO | 15 kHz |
分频(设置为32) | 15 kHz/32 |
超时周期 | 2048 cycles |
IWDT时钟频率 | 15 kHz / 32 = 468.75 Hz |
单周期时间 | 1 / 468.75 Hz = 2.13 ms |
溢出时间 | 2.13 ms x 2048 cycles = 4.362 seconds |
上述可以看到在该设置下的溢出时间为4.362s,那么1s的计数为1s/2.13ms=469。 |
IWDT计数周期
IWDT计数是从最高一直减到0,当到0时候触发复位。
演示效果
设置每过1s打印一次当前时间,分别设置喂狗和不喂狗,结果如下。
延迟1s的计数为1s/2.13ms=469,打印为1563,由于是向下计数,2048-1563=485,符合计算值。
当不执行喂狗时候,计数值到0时会进行复位。
完整代码
/* 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);printf("starting up !\n");/* Open the module. */err = R_IWDT_Open(&g_iwdt0_ctrl, &g_iwdt0_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Initialize other application code. *//* Do not call R_IWDT_Refresh() in auto start mode unless the* counter is in the acceptable refresh window. */(void) R_IWDT_Refresh(&g_iwdt0_ctrl);while(1){if(rtc_flag){uint32_t iwdt_counter = 0U;err = R_IWDT_CounterGet(&g_iwdt0_ctrl, &iwdt_counter);assert(FSP_SUCCESS == err);printf("iwdt_counter=%d\n",iwdt_counter);/* Refresh before the counter underflows to prevent reset or NMI. */(void) R_IWDT_Refresh(&g_iwdt0_ctrl);rtc_flag=0;}}