Порядок инициализации календаря

 

Шаг Что делать Как делать Комментарии
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