瑞萨单片机论坛
直播中

华仔stm32

3年用户 2899经验值
擅长:嵌入式技术
私信 关注

【RA4M2设计挑战赛】LPM_MODE_SLEEP -RTC ALARM定时唤醒

温度定时采集,采集完后进入低功耗睡眠模式。然后由RTC产生闹钟中断,每一分钟唤醒一次。

配置RTC

image.png

rtc详细属性如下:

image.png

配置 r_lpm

General->Low Power Mode选择 Deep Softwoare Standby mode

Deep Standby Options -> Cance Sources - RTC Alarm

1674104243990.png

然后配置串口等(在原来hs3003的基础上配置)【RA4M2设计挑战赛】HS3003读取数据 - 瑞萨单片机论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛! (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的供电)。没有达到微安级别的待机电流。各位大佬如果有好方法,请告之。

更多回帖

发帖
×
20
完善资料,
赚取积分