Порядок инициализации календаря
Шаг | Что делать | Как делать | Комментарии |
1 | Снять защиту от записи в регистры RTC | Записать “0xCA” и затем “0×53″ в регистр RTC_WPR | Регистры RTC можно изменять |
2 | Войти в режим инициализации | Установить бит INIT регистра RTC_ISR в ‘1’ | Счетчик календаря останавливается, чтобы обеспечить возможность внесения изменений |
3 | Дождаться подтверждения входа в режим инициализации (синхронизация часов) | Poll INITF bit of in RTC_ISR until it is set | Для устройств “medium density” это продолжается примерно 2 RTCCLK цикла часов |
4 | В случае необходимости настроить the prescalers register | Регистр RTC_PRER: Сначала записать synchronous value, а затем write the asynchronous | По умолчанию prescalers register RTC_PRER is initialized to provide 1Hz to the Calendar unit when RTCCLK = 32768Hz |
5 | Загрузить значения времени и даты в the shadow registers | Установить значения регистров RTC_TR и RTC_DR | |
6 | Configure the time format (12h or 24h) | Set FMT bit in RTC_CR register | FMT = 0: 24 hour/day format FMT = 1: AM/PM hour format |
7 | Exit Initialization mode | Clear the INIT bit in RTC_ISR register | The current calendar counter is automatically loaded and the counting restarts after 4 RTCCLK clock cycles |
8 | Enable the RTC Registers Write Protection | Write “0xFF” into the RTC_WPR register | RTC Registers can no longer be modified |
RTC_WPR - Write protection register
RTC_ISR -
RTC_PREP -
RTC_TR -
RTC_DR -
RTC_CR -
Похоже, что мои предыдущие попытки установки часов ограничивались шагом 5, а без выполнения шага 1 (и следующего за ним 2) это приводило к бесконечному ожиданию разрешения на запись в функции RTC_WaitForLastTask().
——–
Короткий поиск в Интернете привел к примеру от Keil (stm32_rtc.zip), в недрах которого нашлась функция реализации часов, выполняющая вышеописанные шаги:
/*---------------------------------------------------------------------------- STM32 Real Time Clock setup. initializes the RTC Prescaler and RTC counter register *----------------------------------------------------------------------------*/ __inline static void stm32_RtcSetup (void) {RCC->APB1ENR |= RCC_APB1ENR_PWREN; // enable clock for Power interface PWR->CR |= PWR_CR_DBP; // enable access to RTC, BDC registers if ((__RTC_CLKSRC_VAL & RCC_BDCR_RTCSEL) == 0x00000100) { // LSE is RTC clock source RCC->BDCR |= RCC_BDCR_LSEON; // enable LSE while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0); // Wait for LSERDY = 1 (LSE is ready) } if ((__RTC_CLKSRC_VAL & RCC_BDCR_RTCSEL) == 0x00000200) { // LSI is RTC clock source RCC->CSR |= RCC_CSR_LSION; // enable LSI while ((RCC->CSR & RCC_CSR_LSIRDY) == 0); // Wait for LSERDY = 1 (LSE is ready) } RCC->BDCR |= (__RTC_CLKSRC_VAL | RCC_BDCR_RTCEN); // set RTC clock source, enable RTC clock // RTC->CRL &= ~(1<<3); // reset Registers Synchronized Flag // while ((RTC->CRL & (1<<3)) == 0); // wait until registers are synchronized RTC->CRL |= RTC_CRL_CNF; // set configuration mode RTC->PRLH = ((__RTC_PERIOD*__RTCCLK/1000-1)>>16) & 0x00FF; // set prescaler load register high RTC->PRLL = ((__RTC_PERIOD*__RTCCLK/1000-1) ) & 0xFFFF; // set prescaler load register low RTC->CNTH = ((__RTC_CNT)>>16) & 0xFFFF; // set counter high RTC->CNTL = ((__RTC_CNT) ) & 0xFFFF; // set counter low RTC->ALRH = ((__RTC_ALR)>>16) & 0xFFFF; // set alarm high RTC->ALRL = ((__RTC_ALR) ) & 0xFFFF; // set alarm low if (__RTC_INTERRUPTS) { // RTC interrupts used RTC->CRH = __RTC_CRH; // enable RTC interrupts NVIC->ISER[0] |= (1 << (RTC_IRQChannel & 0x1F)); // enable interrupt } RTC->CRL &= ~RTC_CRL_CNF; // reset configuration mode while ((RTC->CRL & RTC_CRL_RTOFF) == 0); // wait until write is finished
PWR->CR &= ~PWR_CR_DBP; // disable access to RTC registers } // end of stm32_RtcSetup
12.01.12: Обертывание имеющейся (до этого времени неработавшей) функции установки времени вызовами PWR_BackupAccessCmd(ENABLE);
…
PWR_BackupAccessCmd(DISABLE);
решило проблему зависания – программа бодренько проглотила введенные параметры и часы стали отсчитывать новое время. Теперь дело за датой.
Обратная связь
Интересуют вопросы реализации алгоритмов, программирования, выбора электроники и прочая информация, постараюсь осветить в отдельных статьях
пишите мне на netdm@mail.ru