温度定时采集,采集完后进入低功耗睡眠模式。然后由RTC产生闹钟中断,每一分钟唤醒一次。
rtc详细属性如下:
General->Low Power Mode选择 Deep Softwoare Standby mode
Deep Standby Options -> Cance Sources - RTC Alarm
然后配置串口等(在原来hs3003的基础上配置)【RA4M2设计挑战赛】HS3003读取数据 - 瑞萨单片机william hill官网 - 电子技术william hill官网 - 广受欢迎的专业电子william hill官网 ! (elecfans.com)
生成代码后,在hal_entry.c中增加如下代码:
fsp_err_t err = FSP_SUCCESS;
extern volatile bool e31_send_complete_flag;
/* rtc_time_t is an alias for the C Standard time.h struct 'tm' */
rtc_time_t set_time =
{
.tm_sec = 0, /* 秒,范围从 0 到 59 */
.tm_min = 30, /* 分,范围从 0 到 59 */
.tm_hour = 12, /* 小时,范围从 0 到 23*/
.tm_mday = 20, /* 一月中的第几天,范围从 1 到 31*/
.tm_mon = 11, /* 月份,范围从 0 到 11*/
.tm_year = 121, /* 自 1900 起的年数,2021为121*/
.tm_wday = 5, /* 一周中的第几天,范围从 0 到 6*/
// .tm_yday=0, /* 一年中的第几天,范围从 0 到 365*/
// .tm_isdst=0; /* 夏令时*/
};
rtc_alarm_time_t set_alarm_time =
{
.time.tm_sec = 1,
.time.tm_sec = 59, /* 秒,范围从 0 到 59 */
.time.tm_min = 59, /* 分,范围从 0 到 59 */
.time.tm_hour = 23, /* 小时,范围从 0 到 23*/
.time.tm_mday = 31, /* 一月中的第几天,范围从 1 到 31*/
.time.tm_mon = 11, /* 月份,范围从 0 到 11*/
.time.tm_year = 199, /* 自 1900 起的年数,2021为121*/
.time.tm_wday = 6, /* 一周中的第几天,范围从 0 到 6*/
.sec_match = 1,
.min_match = 0,
.hour_match = 0,
.mday_match = 0,
.mon_match = 0,
.year_match = 0,
.dayofweek_match = 0,
};
volatile bool rtc_flag = 0;//RTC延时1s标志位
volatile bool rtc_alarm_flag = 0;//RTC闹钟
/* Callback function */
void rtc_callback(rtc_callback_args_t* p_args)
{
/* TODO: add your own code here */
if(p_args->event == RTC_EVENT_PERIODIC_IRQ)
rtc_flag = 1;
else if(p_args->event == RTC_EVENT_ALARM_IRQ)
rtc_alarm_flag = 1;
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
uint8_t hs_rxbuf[8];
uint8_t rtc_second = 0; //秒
uint8_t rtc_minute = 0; //分
uint8_t rtc_hour = 0; //时
uint8_t rtc_day = 0; //日
uint8_t rtc_month = 0; //月
uint16_t rtc_year = 0; //年
uint8_t rtc_week = 0; //周
rtc_time_t get_time;
//rtc_time_t get_time;
//uint8_t e31_reset[] = {0xC4, 0xC4, 0xC4};
R_BSP_PinAccessEnable(); //启用对PFS寄存器的访问,因为后面写IO口都用BSP内联函数
if (1U == R_SYSTEM->RSTSR0_b.DPSRSTF)
{
/*从深度软件待机模式唤醒后清除IOkeep位*/
R_LPM_IoKeepClear (NULL);
/*清除唤醒标志位*/
R_SYSTEM->RSTSR0_b.DPSRSTF = 0;
/*判断唤醒源是IRQ-9还是IRQ-10,并将判断结果打印出来*/
if (R_SYSTEM->DPSIFR1 >> 1 & 0x01U)
{
printf("MCU is woke up by IRQ-9\r\n");
}
else if (R_SYSTEM->DPSIFR1 >> 2 & 0x01U)
{
printf("MCU is woke up by IRQ-10\r\n");
}
}
R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
bsp_uart_init();
E31_uart_init();
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);
/* 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_2_SECOND);
R_RTC_CalendarAlarmSet(&g_rtc0_ctrl, &set_alarm_time);
printf("start..\r\n");
set_e31_M1();
while(1)
{
#if DEBUG
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
rtc_flag=0;
rtc_second=get_time.tm_sec;//秒
rtc_minute=get_time.tm_min;//分
rtc_hour=get_time.tm_hour;//时
rtc_day=get_time.tm_mday;//日
rtc_month=get_time.tm_mon;//月
rtc_year=get_time.tm_year; //年
rtc_week=get_time.tm_wday;//周
printf(" %d y %d m %d d %d h %d m %d s %d w\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);
printf("/************************Alarm Clock********************************/\n");
#endif
set_e31_M0();
getdata_hs3003(hs_rxbuf);
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
#if DEBUG
printf("temp: %X,%X,%X,%X,%X\n", hs_rxbuf[2], hs_rxbuf[3], hs_rxbuf[4], hs_rxbuf[5], hs_rxbuf[6]);
#endif
hs_rxbuf[0] = 0x5A;
hs_rxbuf[1] = 0xA5;
//打开e31的M0、M1置状态为0
R_SCI_UART_Write(&E31_uart_ctrl, hs_rxbuf, 7);
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
#if DEBUG
if(e31_send_complete_flag == true)
{
printf("发送成功\n");
e31_send_complete_flag = false;
}
else
printf("发送失败\n");
#endif
set_e31_M1();
/*进入低功耗模式前打印*/
printf("MCU enters Deep SW Standby mode\r\n");
/*打开LPM,进入深度软件待机模式*/
R_LPM_Open (Deep_SW_Standby.p_ctrl, Deep_SW_Standby.p_cfg);
R_LPM_LowPowerModeEnter (Deep_SW_Standby.p_ctrl);
/*唤醒后打印,但是在进入深度软件待机模式后不能保存上下文,
故这里正常来说无法被执行,如果执行了则说明进入的是睡眠模式,
一般刚烧写程序会导致这个问题,重新上电即可恢复正常*/
printf("MCU has been woken up without reset\r\n");
// R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
下载到开发板后,每隔1分钟唤醒一次,采集数据,采集、发送完成后,对E31进行配置使其进入睡眠模式,然后主芯片也进入睡眠模式。
效果:进入睡眠模式后测得的待电流为6mA(备注开发板去除了5V电源、CH340G的供电)。没有达到微安级别的待机电流。各位大佬如果有好方法,请告之。
更多回帖