本帖最后由 Alden 于 2025-6-3 17:17 编辑
#申请原创# #技术资源#
在前面测试了APM32F402进入stop和standby模式后通过按键进行唤醒,但有时候希望芯片可以周期性唤醒,进行喂狗或者其他操作再休眠。
就在前面测试的基础上增加了RTC闹钟的唤醒。
要注意RTC闹钟要配置到外部17线中断上。
以下是RTC的初始化:
void RTC_Config(void)
{
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
EINT_Config_T EINT_ConfigStruct = {0U};
/* unLock RTC write protection */
PMU_EnableBackupAccess();
RCM_EnableLSI();
while(RCM_ReadStatusFlag(RCM_FLAG_LSIRDY) == RESET);
RCM_ConfigRTCCLK(RCM_RTCCLK_LSI);
RCM_EnableRTCCLK();
/* Wait for RTC clock source synchro */
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ConfigPrescaler(40000);
RTC_WaitForLastTask();
/* Configure counter 0 */
RTC_ConfigCounter(0);
RTC_WaitForLastTask();
/* Enable RTC alarm interrupt */
RTC_EnableInterrupt(RTC_INT_ALR);
RTC_WaitForLastTask();
NVIC_EnableIRQRequest(RTC_Alarm_IRQn, 0, 0);
EINT_ClearIntFlag(EINT_LINE_17);
EINT_ConfigStruct.line =EINT_LINE_17;
EINT_ConfigStruct.mode = EINT_MODE_INTERRUPT;
EINT_ConfigStruct.trigger = EINT_TRIGGER_FALLING;
EINT_ConfigStruct.lineCmd = ENABLE;
EINT_Config(&EINT_ConfigStruct);
}
RTC的中断中只用清除标志位和做一些判断.
void RTC_Isr(void)
{
if (EINT_ReadIntFlag(EINT_LINE_17) != RESET)
{
rtcwkup_flag=1;
EINT_ClearIntFlag(EINT_LINE_17);
RTC_ClearIntFlag(RTC_INT_ALR);
}
}
进休眠之前要配置RTC唤醒的时间要几秒:
//RTC定时闹钟时间设置以及开启
void RTC_Set_Alarm_Time(uint32_t AlarmValue)
{
if(AlarmValue == 0)
{
return;
}
EINT_ClearIntFlag(EINT_LINE_17);
RTC_ClearIntFlag(RTC_INT_ALR);
RTC_ConfigAlarm(RTC_ReadCounter() + AlarmValue);
RTC_WaitForLastTask();
}
可以通过定义的标志位判断是什么唤醒源唤醒的:
int stop_flag=0;
int rtcwkup_flag=0;
int keywkup_flag=0;
int main(void)
{
RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR));
BOARD_LED_Config(LED2);
BOARD_LED_Config(LED3);
RTC_Config();
Usart_Init();
printf("run start\r\n");
/* KEY1 \ KEY2 Set */
BOARD_BUTTON_Config(BUTTON_KEY1, BUTTON_MODE_EINT);
BOARD_BUTTON_Config(BUTTON_KEY2, BUTTON_MODE_EINT);
/* NVIC Priority Set */
NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_1);
NVIC_EnableIRQRequest(EINT0_IRQn, 0, 1);
NVIC_EnableIRQRequest(EINT1_IRQn, 1, 1);
BOARD_LED_On(LED2);
BOARD_LED_Off(LED3);
// Delay(0x7FFFFF);//上电进入休眠测试功耗
// stop_flag=1;//上电进入休眠测试功耗
printf("Press KEY1 to Enter STOP Mode\r\n");
while (1)
{
Delay(0x7FFFFF);
BOARD_LED_Toggle(LED2);
if(stop_flag==1)
{
printf("\r\nIN STOP mode\r\n");
stop_flag=0;
GPIO_ALL_init();
RTC_Set_Alarm_Time(5);
PMU_EnterSTOPMode(PMU_REGULATOR_LOWPOWER, PMU_STOP_ENTRY_WFI);//测试stop开启
// PMU_EnableWakeUpPin();//测试standby开启
// PMU_EnterSTANDBYMode();//测试standby开启
SystemInit();
Usart_Init();
BOARD_LED_Config(LED2);
printf("\r\nOUT STOP mode\r\n");
if(rtcwkup_flag==1)
{
rtcwkup_flag=0;
printf("\r\nrtc WKUP STOP mode\r\n");
}
if(keywkup_flag==1)
{
keywkup_flag=0;
printf("\r\nkey WKUP STOP mode\r\n");
}
}
}
}
需要stop模式就这样测试,需要测试standby就打开对应的代码。
用按键唤醒:
等待RTC唤醒:
APM32F402_403_SDK_stop_standby_key_RTC.zip
(4.51 MB)
|