RTC часы реального времени

В данном примере рассматривается простой вариант начальной инициализации модуля часов реального времени. Этот пример был отлажен на микроконтроллере серии STM32F4.

    MOV32 R0, RCC_BASE

    @ Затактировать POWER control
    @ Очевидно он был затактирован ранее
    @ Во время инициализации RCC
    LDR R1, [R0, RCC_APB1ENR]
    ORR R1, RCC_APB1ENR_PWREN
    STR R1, [R0, RCC_APB1ENR]

    @ Разрешить доступ к backup domain
    MOV32 R1, PWR_BASE+PWR_CR
    LDR R2, [R1]
    ORR R2, PWR_CR_DBP
    STR R2, [R1]

Жёсткий сброс системы не влияет на состояние часов и они будут продолжать тикать, не смотря на любые обстоятельства. До начала процедуры инициализации вы можете проверить состояние флага INITS в регистре RTC_ISR. Если этот флаг =1, вероятно часы уже были ранее настроены и счастливо тикают. А значит перенастраивать их не нужно.

    MOV32 R1, RTC_BASE+RTC_ISR
    LDR R2, [R1]
    TST R2, RTC_ISR_INITS
    BNE Выход_из_настройки_часов
    @ Если флаг =1 выйти из настройки

    @ Иначе продолжим
    @ Включаем усилитель часового кварца
    LDR R1, [R0, RCC_BDCR]
    ORR R1, RCC_BDCR_LSEON
    STR R1, [R0, RCC_BDCR]

    @ Ждём готовности часового кварца
    @ Внимание! Если с кварцем будут проблемы
    @ Этот цикл станет безконечным!
    wait_lserdy:
    LDR R1, [R0, RCC_BDCR]
    TST R1, RCC_BDCR_LSERDY
    BEQ wait_lserdy

Маленький комментарий. На моей тестовой платке из китая, часовой кварц раскачивается в этом месте аж три секунды! Система стоит и ждёт его в пустом цикле... Что там за кварц на плате, можно догадаться.. Такие продаются на ебэе
по три копейки за мешок.

Далее:

    @ Сбросим backup domain
    LDR R1, [R0, RCC_BDCR]
    ORR R1, RCC_BDCR_BDRST
    STR R1, [R0, RCC_BDCR]
    BIC R1, RCC_BDCR_BDRST
    STR R1, [R0, RCC_BDCR]

    @ Выбираем внешний часовой кварц
    @ В качестве источника тактовых импульсов для часов
    LDR R1, [R0, RCC_BDCR]
    BIC R1, RCC_BDCR_RTCSEL
    ORR R1, RCC_BDCR_RTCSEL_0
    STR R1, [R0, RCC_BDCR]

    @ Запускаем часики!
    LDR R1, [R0, RCC_BDCR]
    ORR R1, RCC_BDCR_RTCEN
    STR R1, [R0, RCC_BDCR]

    @ Начинаем работу непосредственно с регистрами часов
    MOV32 R0, RTC_BASE

    @ Вскроем защиту часовых регистров от записи
    MOV R1, 0xCA
    STR R1, [R0, RTC_WPR]
    MOV R1, 0x53
    STR R1, [R0, RTC_WPR]

    @ Запросим режим инициализации
    LDR R1, [R0, RTC_ISR]
    ORR R1, RTC_ISR_INIT
    STR R1, [R0, RTC_ISR]

    @ Дождёмся разрешения
    wait_initf:
    LDR R1, [R0, RTC_ISR]
    TST R1, RTC_ISR_INITF
    BEQ wait_initf

    @ Установим делитель в значение 32768-1
    @ Что бы регистр обновился, STR нужно повторить два раза
    MOV32 R1, 0x007F00FF
    STR R1, [R0, RTC_PRER]
    STR R1, [R0, RTC_PRER]

    @ Установим какое-нибудь время, например 11:35:15
    MOV32 R1, 0x00113515
    STR R1, [R0, RTC_TR]

    @ Установим дату, например понедельник 21 декабря 2015 года
    MOV32 R1, (0x15<<16) + (1<<13) + (0x12<<8) + 0x21
    STR R1, [R0, RTC_DR]

    @ Выйдем из режима инициализации
    LDR R1, [R0, RTC_ISR]
    BIC R1, RTC_ISR_INIT
    STR R1, [R0, RTC_ISR]

    Выход_из_настройки_часов:

    @ Закрыть доступ к backup domain
    MOV32 R1, PWR_BASE+PWR_CR
    LDR R2, [R1]
    BIC R2, PWR_CR_DBP
    STR R2, [R1]


Что ещё можно сделать..

В составе backup domain есть ещё одна полезняшка, называемая backup registers. Эти регистры являются альтернативой EEPROM и FRAM памяти. Они обладают всеми достоинствами встроенного ОЗУ, но требуют подпитки в дежурном режиме.
Если батарейка на часах установлена, регистры будут сохранять свои значения, потребляя нано-энергию.
Даже не предусмотрено их отключение от домена, настолько они экономичные, потому что их мало.
К backup регистрам можно обращаться по байту, полуслову и целому слову в 32 бита.

В состав STM32F4 входит 20 регистров с именами RTC_BKP0R ... RTC_BKP19R.
Что бы получить к ним доступ на запись, нужно только установить флаг DBP.

    @ Откроем доступ к backup domain
    MOV32 R1, PWR_BASE+PWR_CR
    LDR R2, [R1]
    ORR R2, PWR_CR_DBP
    STR R2, [R1]

    @ Запишем что-нибудь в регистр
    MOV32 R3, RTC
    MOV32 R4, 0x12345678
    STR R4, [R3, RTC_BKP0R]

    @ Закроем backup domain
    BIC R2, PWR_CR_DBP
    STR R2, [R1]

Что бы прочитать backup регистр, дополнительного разрешения не требуется.

    MOV32 R0, RTC
    LDR R1, [R0, RTC_BKP0R]


Вот и всё.

Краткое описание часов на русском:
часть 1, часть 2, локальная копия.

Читайте так же AN3371.