Spider 0 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба Усыпляю проц в 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). Как так то? Что я делаю не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 64 11 июня, 2019 Опубликовано 11 июня, 2019 · Жалоба 13 часов назад, Spider сказал: Как так то? Что я делаю не так? Вначале разделить - это программная или аппаратная ошибка? Т.е. поставить toggle какого-нибудь Pin вокруг каждой операции(начало чтения времени, окончание чтения времени, прямо перед засыпанием, сразу при пробуждении и т.д. ) и посмотреть осциллографом на длинной развертке где возникает ошибка времени. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 12 июня, 2019 Опубликовано 12 июня, 2019 · Жалоба 20 hours ago, HardEgor said: . . . Т.е. поставить toggle какого-нибудь Pin вокруг каждой операции(начало чтения времени, окончание чтения времени, прямо перед засыпанием, сразу при пробуждении и т.д. ) и посмотреть осциллографом на длинной развертке где возникает ошибка времени. + выдавать импульс на пин в начале main(). Проверить (тест) - время выхода из sleep (не по будильнику, а напр. по внешнему апп. прерыванию). И нет ли при пробуждении рестарта кода (режим пробуждения). Возможно эти 16 с - начальная инициализация. Проверьте момент пробуждения процессора по его току потребления. (те что 16 с - реальная задержка выхода из слип) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться