C语言 STM32通过FreeRTOS进入STOP模式

j2qf4p5b  于 2023-05-06  发布在  其他
关注(0)|答案(1)|浏览(334)

我正在尝试进入STOP模式并使用RTC报警唤醒。
在启动FreeRTOS内核之前测试代码时,它工作正常。
启动FreeRTOS内核后,唤醒不起作用,系统继续处于STOP模式。
我认为问题出在RTC报警中断故障。我试过启用它,但它仍然没有醒来。
关于这个问题有什么迹象吗?
以下是进入STOP1模式前后的代码部分

taskDISABLE_INTERRUPTS();    
    HAL_SuspendTick();
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
    HAL_NVIC_ClearPendingIRQ(RTC_Alarm_IRQn);
    SET_Alarm_A();

    HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);

    SystemClock_Config();
    HAL_ResumeTick();
    taskENABLE_INTERRUPTS();

SET_Alarm_A函数:

void SET_Alarm_A(uint8_t ui8_MinuteAlarm)
{
    uint8_t ui8_AlarmInterval;
    RTC_AlarmTypeDef sAlarm = {0};
    RTC_TimeTypeDef sTime = {0};
    RTC_DateTypeDef sDate = {0};

    // Get updated time from RTC
    HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);         // Get current Time
    HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);         // Get current Date. It is mandatory to read the Date after Time, even if not used
    gui8_RTChours = sTime.Hours;                            // Take the current RTC Hours
    gui8_RTCminutes = sTime.Minutes;                        // Take the current RTC Minutes
    gui8_RTCseconds = sTime.Seconds;                        // Take the current RTC Seconds

    ui8_AlarmInterval = gui8_RTCminutes + ui8_MinuteAlarm;  // update the timing interval for next cycle
    if(ui8_AlarmInterval > 59U) {                           // check for values over 59
        ui8_AlarmInterval = ui8_AlarmInterval - 60U;        // calculate and compensate the overflow
    }

    sAlarm.AlarmTime.Hours = 0x0;
    sAlarm.AlarmTime.Minutes = ui8_AlarmInterval;
    sAlarm.AlarmTime.Seconds = 0x0;
    sAlarm.AlarmTime.SubSeconds = 0x0;
    sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
    sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_SECONDS;     // Compares Minutes only
    sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
    sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
    sAlarm.AlarmDateWeekDay = 0x1;
    sAlarm.Alarm = RTC_ALARM_A;
    if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
    {
        Error_Handler();
    }
}
wh6knrhe

wh6knrhe1#

发现了一个与BASEPRI相关的主题,它允许按优先级组禁用中断。下面的代码是工作,但我没有得到正确的BASEPRI逻辑。RTC_Alarm的优先级为5,在这种情况下,__set_BASEPRI的优先级参数应小于5。但它只在我使用大于5的时候起作用。
请解释一下

HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 5, 0);
              HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
              SET_Alarm_A(gui8_EETIMEPUBINTERVAL);          // Set RTC Alarm with the TIMEPUBINTERVAL
              HAL_ADC_DeInit(&hadc1);
              vTaskSuspendAll();
              HAL_SuspendTick();
              __set_BASEPRI(6 << 4);            // RTC Alarm A has priority 5 (do not know how it is working. It should be a value smaller than 5 ??!)
              __disable_irq();                  // Disable all interrupts except the RTC Alarm (due to the priority block)

              HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);          // Enter Stop1 mode, wait for RTC Alarm to wake up

              __set_BASEPRI(0);
              __enable_irq();                   // Enable all interrupts
              SystemClock_Config();             // Resume the clock configuration, affected after the Stop Mode
              MX_ADC1_Init();                   // It was Clocked-off during STOP1 Mode
              HAL_ResumeTick();
              xTaskResumeAll();

相关问题