void main(){ ................ RTC_init(); Wake_Vcc1_Off_config(); .............. for(;;){ ........ } } /***********************************************************************************************************************************/ void RTC_init() { PMURTC->RTC_CFG0_bit.EXTOSC = 1; PLIC_SetIrqHandler(Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler); PLIC_SetPriority(IsrVect_IRQ_PMURTC, 0x1); PLIC_IntEnable(Plic_Mach_Target, IsrVect_IRQ_PMURTC); PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_REGEN_Msk; } /***********************************************************************************************************************************/ /* Функция настройки Wake5 на событие "VBAT > VCC1" при отключении VCC1 */ void Wake_Vcc1_Off_config() { PMURTC->RTC_WAKECFG &= ~(0x20); // сброс WAKEUP5 PMURTC->RTC_HISTORY = 0x0; PMURTC->RTC_WAKECFG &= ~(0x20 << PMURTC_RTC_WAKECFG_WAKEPOL_Pos); // Устанавливаем полярность для WAKEUP5 - высокий уровень (VBAT > VCC1) PMURTC->RTC_WAKECFG |= 0x20; // Разрешаем событие WAKEUP5 PMURTC->RTC_HISTORY = 0x0; // СБрасываем регистр событий } /***********************************************************************************************************************************/ /* Функция настройки Wake5 на событие "VBAT < VCC1" при включении VCC1 */ void Wake_Vсс1_On_config() { PMURTC->RTC_WAKECFG &= ~(0x20); // сброс WAKEUP5 PMURTC->RTC_HISTORY = 0x0; PMURTC->RTC_WAKECFG |= (0x20 << PMURTC_RTC_WAKECFG_WAKEPOL_Pos); // Устанавливаем полярность для WAKEUP5 - низкий уровень (VBAT < VCC1) PMURTC->RTC_WAKECFG_bit.WAKEEN = 0x20; // Разрешаем событие WAKEUP5 PMURTC->RTC_HISTORY = 0x0; // СБрасываем регистр событий } /***********************************************************************************************************************************/ void RTC_IRQHandler() { uint32_t tmp_history; tmp_history = PMURTC->RTC_HISTORY; PMURTC->RTC_HISTORY = 0; if (tmp_history & PMURTC_RTC_HISTORY_WKVFVBAK_Msk) { // Если сработало событие (VBAT > VCC1) или (VBAT < VCC1) if(PMURTC->RTC_WAKECFG_bit.WAKEPOL & 0x20) { // VBAT < VCC1 — включилось питание VCC1 Wake_Vcc1_Off_config(); //настройка Wake5 на событие "VBAT > VCC1" при отключении VCC1, //которое произойдет в случае выключения питания } else { // VBAT > VCC1 — отключилось питание VCC1, нужно работать от Vbat, чтобы работали часики Wake_Vсс1_On_config(); //настройка Wake5 на событие "VBAT < VCC1" при включении VCC1, //которое произойдет в случае включения питания // Отключаем лишние функции для минимального тока PMURTC->PMU_VBATPER_WFI = 0xFFFFFFFF; PMURTC->RTC_REG[1].RTC_REG++; PMURTC->RTC_CFG1_bit.ALARMEN = 0; PMURTC->RTC_CFG1_bit.REGEN = 0; PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk; PMURTC->WFI_PDEN_bit.EN = 1; PMURTC->WFI_ENTR_bit.LDO0EN = 0; PMURTC->WFI_ENTR_bit.LDO1EN = 0; GPIOA->DATAOUTSET = (0b1) << 13; for(;;); // Уходим в WFI и ждем появления VCC1 while (1) { __asm("WFI"); } } } PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk; PMURTC->PMU_IRQEVT = 1; }