Jump to content

    

STM32F401 опаздывает будильник на 16 секунд

Усыпляю проц в StandBy с последующим пробуждением по будильнику RTC.
Настраиваю будильник, усыпляю, а про просыпается на 16 секунд позже запланированного. и всегда РОВНО на 16 секунд позже. т.е. чтобы мне получить корректное время пробуждения, я должен установить будильник на 16 секунд раньше и тогда получаю желаемый результат. Как так то?

Привожу кусочек кода, максимально отчищеный по месту.
 

uint32_t time;
uint32_t date;
uint32_t subsec;

//Выгребаем время из RTC
do {		
	time = LL_RTC_TIME_Get(RTC);
	date = LL_RTC_DATE_Get(RTC);
	subsec = LL_RTC_TIME_GetSubSecond(RTC);
} while (subsec != LL_RTC_TIME_GetSubSecond(RTC));
 
sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(time));
min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(time));
hour= __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(time));
 
//Будем ставить будильник на 10 секунд
sec+=10; //Тут конечно есть проверки на "переполнение", но для простоты примера этого достаточно.
 
LL_RTC_DisableWriteProtection(RTC);
CLEAR_BIT(PWR->CSR, PWR_CSR_EWUP);
//Вроде как в Даташите написано, что наждо отключить будильник и дождаться его готовности к записи.
LL_RTC_ALMA_Disable(RTC);
do {} while (!LL_RTC_IsActiveFlag_ALRAW(RTC));
 
LL_RTC_ClearFlag_ALRA(RTC);
 
//пишем новое время в будильник А
LL_RTC_ALMA_ConfigTime(RTC, LL_RTC_ALMA_TIME_FORMAT_AM, __LL_RTC_CONVERT_BIN2BCD(hour), __LL_RTC_CONVERT_BIN2BCD(min), __LL_RTC_CONVERT_BIN2BCD(sec));
//Реагируем только на совпадение секунд, это отдельная тема
LL_RTC_ALMA_SetMask(RTC, LL_RTC_ALMA_MASK_DATEWEEKDAY | LL_RTC_ALMA_MASK_HOURS | LL_RTC_ALMA_MASK_MINUTES);
//Не реагируем на субсекунды
LL_RTC_ALMA_SetSubSecondMask(RTC, 0);
LL_RTC_ALMA_Enable(RTC);
 
LL_RTC_EnableWriteProtection(RTC);
 
//Вывожу в консольку фактическое значение будильника
TRACE_INFO("RTC->ALRMAR: 0x%08X\r\n",RTC->ALRMAR);
 
/* Enable the wake up pin */
SET_BIT(PWR->CSR, PWR_CSR_EWUP);
 
//Всем спать.
SET_BIT(PWR->CR, PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
__WFI();

В результате проц проснётся НО! проснётся на 16 секунд позже запланированного.
т.е. если в первых строка после пробуждения считать RTC время, то там ровно на 16 секунд больше чем записано в будильнике.
Регистр RTC_ALRMAR при выводе в консольку имеет корректные значения на сколько я могу судить.
Ну к примеру, выставил я время пробуждения 12:34:56, в регистре RTC_ALRMAR в младших битах значение 0x.....56 (BCD чтоб его так) но проснётся проц в 12:35:12 и в регистре RTC_TR, по мимо всего прочего будет 0x....12 (опять BCD).

Как так то? Что я делаю не так?

Share this post


Link to post
Share on other sites
13 часов назад, Spider сказал:

Как так то? Что я делаю не так?

Вначале разделить -  это  программная или аппаратная ошибка? Т.е. поставить toggle какого-нибудь Pin вокруг каждой операции(начало чтения времени, окончание чтения времени, прямо перед засыпанием, сразу при пробуждении и т.д. ) и посмотреть осциллографом на длинной развертке где возникает ошибка времени.

Share this post


Link to post
Share on other sites
20 hours ago, HardEgor said:

 . . . Т.е. поставить toggle какого-нибудь Pin вокруг каждой операции(начало чтения времени, окончание чтения времени, прямо перед засыпанием, сразу при пробуждении и т.д. ) и посмотреть осциллографом на длинной развертке где возникает ошибка времени.

+ выдавать импульс на пин в начале main(). 

Проверить (тест) - время выхода из sleep (не по будильнику, а напр. по внешнему апп. прерыванию). И нет ли при пробуждении рестарта кода (режим пробуждения). Возможно эти 16 с - начальная инициализация.

Проверьте момент пробуждения процессора по его току потребления. (те что 16 с - реальная задержка выхода из слип)

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now