版本 66f3eac7b141f5c6308ce2a5f9588effe44686f1
embedded/RTC
Introduction
Real-Time Clock(RTC)是負責記錄時間的元件,出現在需要長期使用時鐘的電子設備中。例如學校定時關閉冷氣的裝置,以及手機上的鬧鈴功能。
System Overview
基本上RTC(Real-time clock)本身就是一個真正的時鐘,利用原本STM本身所內建的振盪器再利用Prescaler降成1Hz讓RTC使用。利用硬體達成的binary-coded decimal (BCD) format,可以把下列與時間有關的資訊儲存,而且不需要任何軟體轉換,因為硬體就已經把資料轉成一般的日期格式。
- sub-seconds
- seconds
- minutes
- hours in 12-hour or 24-hour format
- day of the week (day)
- day of the month (date)
- month
- year
可用的功能
- Alarm A & Alarm B
- Auto wakeup
- Timestamp
- Tamper detection
Block Diagram
.. image:: /rtc_block.png
Functional Description
Clock Source
.. image:: /clocksource2.png
STM32的 Clock 有分成「SYSCLK」和「RTCCLK」:
SYSCLK為系統的clock有三種來源:
- HSI (High-Speed Internal) :16MHz,RC電路
- HSE (Low-Speed External):4-26MHz (一般選用8MHz),石英震盪
- Main PLL clock
RTCCLK為設備的clock有兩種來源:
- LSI (Low-Speed Internal) :40kHz,RC電路震盪
- LSE (High-Speed External):32.768kHz,石英震盪
—-> RTC 主要是使用 HSE , LSI , LSE 三種來源
參閱reference manual p.150
比較 「HSE」, 「LSI」 , 「LSE」三種輸入來源:
- HSE - 較為耗能, 可以處理像是USB或TV訊號的clock,需要和和另一個clock穩定同步。
- LSI - 是一個低功耗的clock,可以再停機或待機模式下保持運行,用在auto-wakeup(簡稱AWU)與 watchdog看門狗(簡稱IMDG)。
- LSE - 它是一個低功耗且“精準”的clock,適合用在時間的精確計算。
Prescaler
.. image:: /RTC_Prescalers.png
ck_spre
一般而言要降為1Hz的頻率,因為省電的因素STM設計了兩個Prescaler。7 bit非同步prescaler(PREDIV_A
)和15 bit同步的prescaler(PREDIV_S
)。這兩個prescaler要在RTC_PRER的暫存器設定。ST在Reference有說明當兩個Prescaler都使用時,建議讓非同步的Prescaler讓他有較大的值,以讓系統更省電
所以ck_spre
與兩個prescaler的關係為:
.. image:: /ck_spre2.png
例如:
LSE: 32.768kHz / (127+1) / (255+1) = 1Hz
LSI: 32kHz / (127+1) /(249+1) =1Hz
Alternate Function RTC Outputs
Alternate function 可以將RTC某些功能對應到輸出的接腳(GPIO Pin),這些輸出可以被選擇成tamp event 或 time stamp event,
甚至RTC Calibration 的訊號都可以藉由這個功能輸出。
可以選擇兩個輸出:
輸出接腳 RTC_AF1(PC13) :
RTC_ALARM output: 1. RTC Alarm A 2. RTC Alarm B 3. RTC Wakeup
RTC_CALIB output
RTC_TAMP1
RTC_TS
輸出接腳 RTC_AF2 (PI8) :
RTC_TAMP1
RTC_TAMP2
RTC_TS
Reference Manual p.277
PI8接腳參考: datasheet p.10
RTC Calendar
.. image:: /RTC_calendar.png
讀取Calendar:
當在讀取Calendar時其實並不是真正直接讀取calendar register,其實是在讀shadow register,如果想要直接讀取calendar必須
要設BYPSHAD控制位元為1(在RTC_C Rregister)才能繞過shadow register而直接讀取calender register。
Shadow Register:
通常初始化和讀取的動作採用Shadow Register。
每兩個RTCCLK時間週期,RTC的calendar register (RTC_SSR, RTC_TR, and RTC_DR)的值會被自動更新到Shadow Register。
Calibration
RTC裡面有兩個校正功能,一個是coarse calibration另一個是smooth calibration。
這兩個校正不能同時被使用,而前者只能固定修正,後者則可以動態的校正。後者也可以較大範圍及更精準的校正。
1、RTC coarse calibration :
被使用在補償石英震盪器的校正。
在非同步分頻器(ck_apre)的輸出,藉由增加或減少時間的週期達到校正,最大範圍的校正為63ppm~126ppm。
只能在初始化Calendar時候修改,是一個非回授控制系統(opened loop control)。
可以利用AFO_CALIB去計算clock deviation。不能以圖中512Hz的訊號去確認coarse calibration的輸出結果,只能使用ck_spre確認校正的結果。
reference clock calibration 和 coarse calibration 不能同時使用。
.. image:: /coarse cal.png
2、RTC smooth calibration:
可以補償石英震盪器的偏差,此偏差可能是晶體老化或者溫度所造成。
利用每個RTCCLK pulse為單位做出小幅調整,來修正RTC的clock頻率。
最大範圍的校正為-487.1ppm~+488.5ppm。
與coarse calibration不同,是一個閉迴路的控制系統(closed loop control)。
可以使用AFO_CALIB來計算時間偏差,而且可直接檢查512Hz和1Hz的校正輸出。
.. image:: /smooth cal.png
3、RTC reference clock detection:
- 利用外部時鐘校正,其時鐘源必須要比LSE的時鐘還精準。
Interrupt Application
Alarm
有兩個時鐘Alarm A及Alarm B,可以當作鬧鐘使用。而且相關的register也都會有兩組。
可利用Mask達成不同時間的鬧鈴效果。
.. image:: /embedded/RTC/alarm_pass.png
.. image:: /Alarm3.png
利用MSKx bits設定遮罩改變Alarm的行為:
As an example, to configure the alarm time to 23:15:07 on Monday (預設MSK是0000)
.. image:: /MSK2.png
Application note p.10
Periodic Wakeup Unit
利用周期性的喚醒(wakeup)可以讓系統更省電。這個unit是一個downcounting且會auto-reload 的timer,當它的counter數到0的時候,一個flag和中斷會產生(如果在打開中斷的情況下)。
會有兩個因素影響wakeup unit的中斷觸發週期,一個是timer的value,一個是clock source
設定wakeup period
有三種組態:
Configuration 1:short wakeup periods
Configuration 2:medium wakeup periods
Configuration 3: long wakeup periods
Configuration 1:
Prescalers connected to the timebase/wakeup unit
.. image:: /wuck1.png
在這個設定中,wakeup unit,會接受由RTCCLK再經過Prescaler的clock。RTC_WUTR(RTC Wakeup Timer Register)為一個
auto-reload的down counting timer,這表示當使用者在初始化時設了一個值x,會在x數到0的時候觸發wakeup flag。
EX:當RTCCLK= 32768 Hz,代表著最小的timebase resolution為61.035μs(數一次的時間),最大則是488.28 μs。
所以這代表著最小可觸發wakeup flag時間為(0x0001 + 1) x 61.035 μs = 122.07 μs
最大可觸發wakeup flag時間為 (0xFFFF+ 1) x 488.28 μs = 2 s
註:STM32禁止timer初始值設為0
Prescalers connected to the wakeup unit for configurations 2 and 3
.. image:: /wuck2.png
2和3的clock source相同,都是用來計算calendar的ck_spre。
Configuration 2:
The minimum timebase/wakeup period is (0x0000 + 1) x 61.035 µs = 122.07 µs.
The maximum timebase/wakeup period is (0xFFFF+ 1) x 32 s = 131072 s (more than 36 hours).
Configuration 3:
其Clock Source與 Configuration 2 一樣,差在2最大可以從0xFFFF倒數至0x0000,3則是0x1FFFF至0x00000
The minimum timebase/wakeup period is: (0x10000 + 1) x 61.035 µs = 250.06 ms
The maximum timebase/wakeup period is: (0x1FFFF+ 1) x 32 s = 4194304 s (more than 48 days).
Min. and max. timebase/wakeup period when RTCCLK= 32768Hz
.. image:: /MaxMin.png
Time-stamp Function
實體世界裡有「郵戳為憑」來證明信件的時間,在網路世界裡如何來證明電子文件或交易的時間?
利用Time-stamp function 可以為任何電子文件或電子交易提供準確的時間證明,並且驗證其內容自蓋上時戳後是否曾被人修改過。
Time-stamp function 提供自動幫你儲存日曆的功能
RTC_TSDR register : 會去讀取RTC_DR 裡面的年、月、日、周的資料並儲存
RTC_TSTR register : 會去讀取RTC_TR 裡面的秒、時、分的資料並儲存
RTC_TSSR register : 會去讀取RTC_SSR 裡面的Sub-second 的資料並儲存
.. image:: /timestamp.png
Tamper Detection Function
Example of code
Initialize RTC
.. code-block:: prettyprint
RTC_InitTypeDef RTC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Enable the PWR clock */
PWR_BackupAccessCmd(ENABLE); /* Allow access to RTC */
RCC_LSICmd(ENABLE); /* Enable the LSI OSC */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /* Wait till LSI is ready */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* Select the RTC Clock Source */
RCC_RTCCLKCmd(ENABLE); /* Enable the RTC Clock */
RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */
/* Configure the RTC data register and RTC prescaler */
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0xF9;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
setting time
.. code-block:: prettyprint
/* set 8:29:55 */
RTC_TimeTypeDef RTC_TimeStruct;
RTC_TimeStruct.RTC_Hours = 8;
RTC_TimeStruct.RTC_Minutes = 29;
RTC_TimeStruct.RTC_Seconds = 55;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);
initialize RTC alarm
.. code-block:: prettyprint
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* EXTI configuration */
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setting alarm time
.. code-block:: prettyprint
RTC_AlarmTypeDef RTC_AlarmStructure;
RTC_AlarmCmd(RTC_Alarm_A, DISABLE); /* disable before setting or cann't write */
/* set alarm time 8:30:0 everyday */
RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = 0x00;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 8;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = 30;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0;
RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31; // Nonspecific
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; // Everyday
RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
/* Enable Alarm */
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
RTC_ClearFlag(RTC_FLAG_ALRAF);
complete code
.. code-block:: c
git clone git@gitcafe.com:ctc8631/RTC-example.git
cd RTC-example/
make flash
Previous
Generate 1Hz
http://wiki.csie.ncku.edu.tw/embedded/RTC RTC基本計算單位為一秒鐘。
由於clock source速度太快,我們需要用prescaler去轉換成一秒鐘。
.. image:: /stm32 RTC prescaler.png
基於省電需求,將prescaler分為兩個區塊,首先經由較省電的Asynchronous prescaler,再透過較耗能量的Synchronous prescaler輸出1Hz。
根據clock source的頻率不同,我們調整不同的prescaler參數。
.. image:: /embedded/RTC/ck_spre_formula.png
LSE: 32.768kHz / (127+1) / (255+1) = 1Hz
LSI: 32kHz / (127+1) /(249+1) =1Hz
Previous Functionality
Prescaler
Prescaler generates the clock to update the calendar.
To minimize power comsuption the prescaler is split into two prescalers, asynchronous and synchronous. It is recommended to configure the asynchronous prescaler to a high value to minimize consumption.
asynchronous prescaler clocks subsecond of calendar and propagates to synchronous prescaler to update date and time by second.
One can configure them through PREDIV_A
and PREDIV_S
bits in RTC_PRER
Calendar and Alarm
A calendar keeps track of the date (day, week, month, year) and time (hours, minutes and seconds) and even subseconds. It manages of numbers of days of mouths automaticly. Daylight saving time adjustment is programmable by software.
Binary repersentation is in binary-coded decimal (BCD) format.
Data can be read indirectly from shadow registers or directly from counters. The former method delays some clocks but ensures consistency between date and time registers; the later is opposite but this is especially useful after exiting from low power modes, since the shadow registers are not updated during these modes.
Data, time, and subsecond are separately recorded in RTC_DR
, RTC_TR
, and RTC_SSR
. With BYPSHAD
bit set, data can be read directly from counter.
Two programmable alarms (Alarm A, Alarm B) with interrupt function. The alarms can be triggered by any combination of the calendar fields.
An alarm consists of a register with the same length as the RTC time counter. When the RTC time counter reaches the value programmed in the alarm register, a flag is set to indicate that an alarm event occurred.
In addition to the time to trigger, alarm can be configured to mask some fields and do not compare.
Auto periodic wakeup
A periodic timebase and wakeup unit that can wake up the system from low power modes. When this counter reaches zero, a flag and an interrupt are generated.
It’s source clock can be RTC clock or prescaler. Time range can be configured through WUCKSEL
Timestamp
The calendar is saved in timestamp registers when timestamp event is detected on the pin which timestamp alternate function is mapped.
Tamper detection
It can be used for edge detection or level detection with filtering according to TAMPFLT
. Set to 00 is edge detection, others arg level detection.
When TAMPTS
set to 1, tamper event trigger timestamp event automatically.
Backup registers
Program can read or write data from or to these registers, which are not reset by system reset or power-on reset. They are reset when tamper detection event occurs.
Alternate function outputs
Two outputs are avalible : RTC_CALIB
and RTC_ALARM
.
RTC_CALIB
output is used to generate a variable-frequency signal. It can use either asynchronous or synchronous prescaler as clock.
besides alarm, RTC_ALARM
can use wakeup timer as source.
Synchronization and Reference clock detection
RTC can be synchronized to remote clock by adding a ‘shift’ to counter continuously to delay, or vice versa. With reference clock detection, RTC shifts misaligned 1 Hz clock to align it with the nearst referenced edge (found in a given time window).
One can adjust time by configuring shift through RTC_SHIFTR
.
When reference clock detection is enabled (REFCKON
), must not write RTC_SHIFTR
and not enable calibration and set prescalers (PREDIV_A
and PREDIV_S
) to default.
Digital calibration
Calibration can be used to compensate inaccuracy of oscillator by adding or substracting clock cycles in each calibration cycle.
There are two calibration methods : coarse and smooth. They should not be used togather. The cycle of the later is smaller than the former. It makes the later is more flexible to adjust clock. A smooth calibration can be performed on the fly so that it can be changed to handle changed envirenment variables.
coarse calibration is provided for capability reasons. It can only be configured in initialization mode and start when INIT bit is cleared. Also it is recommaned using it for static correction only.
Previous Configuration Register write protection
After system reset, the RTC registers are protected registers are automatically locked to against possible parasitic write accesses.
RTC registers need to disable backup domain protection to update the current calendar time and date.
set ``DBP`` bit in ``PWR_CR``
After power-up reset, the RTC registers are also protected and need to write a key into protection register. RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR are except. Write a wrong key will enable protection.
write ``0xCA`` to ``RTC_WPR``
write ``0x53`` to ``RTC_WPR``
Initialization mode
Modifications of RTC_DR
, RTC_TR
, and RTC_PRER
must be done in Initialization mode.
set ``INIT`` bit of ``RTC_ISR`` to enter Initialization mode
wait until ``RTC_ISR`` / ``INITF`` is set then ready to write
reset ``INIT`` bit of ``RTC_ISR`` to exit Initialization mode
Counter does not run in Initialization mode.
Reference
RTC application note<http://www.st.com/st-web-ui/static/active/cn/resource/technical/document/application_note/DM00025071.pdf>
_
STM32F405xx/07xx, STM32F415xx/17xx, STM32F42xxx and STM32F43xxx Reference Manual <http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00031020.pdf>
_
共筆<https://hackpad.com/STM32F74-RTCReal-Time-Clock-eclVxLGTj50>
_