- 概述
- 硬件准备
- 新建工程
- 工程模板
- 保存工程路径
- 芯片配置
- 工程模板选择
- 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;iR_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/224MHz Clock division ratioPLCK/8192 Timeout period16384 cycles WDT clock frequency24MHz / 8192 = 2929.6875 Hz Cycle time1 / 2929.6875 Hz = 341.33 us Timeout341.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;i event == 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。
或者关注微信公众号『记帖』,持续更新文章和学习资料,可加作者的微信交流学习!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)