在
S
T
M
32
STM32
STM32的
R
e
a
l
t
i
m
e
c
l
o
c
k
,
R
T
C
Real\quad time\quad clock,RTC
Realtimeclock,RTC模块中有一些功能点不太好理解,下面我根据我自己对这些功能难点的理解来做一些推导并记录如下。
首先来看一下平滑数字校准。假设我们目前的
R
T
C
RTC
RTC模块使用外部的
32768
H
Z
32768HZ
32768HZ的
L
S
E
LSE
LSE石英晶振作为内核时钟且配置异步分频值为128,同步分频值为256。这样按照理想的情况驱动日历时间的频率
c
k
_
s
p
r
e
ck\_spre
ck_spre应该为
1
H
Z
1HZ
1HZ。但是这只是理想的情况,
L
S
E
LSE
LSE石英晶振可能会由于温度或使用时长的原因而导致
L
S
E
LSE
LSE石英晶振实际的频率和理想的频率有所偏差,比如实际的频率可能是
32769
H
Z
32769HZ
32769HZ或
32765
H
Z
32765HZ
32765HZ。在这种情况下,实际的
c
k
_
s
p
r
e
ck\_spre
ck_spre的值和
1
H
Z
1HZ
1HZ就会有一定的偏差,短时间还没有太大的影响,但是时间长了之后就会表现为日历值出现较大的偏差。
平滑数字校准功能模块可以对这种偏差进行校准,平滑数字校准功能模块在
R
T
C
RTC
RTC模块中的位置如图1中红圈的位置所示。因为默认情况和平滑数字校准功能模块相关的校准寄存器
C
A
L
R
CALR
CALR的
C
A
L
M
[
8
:
0
]
CALM[8:0]
CALM[8:0]位域和
C
A
L
P
CALP
CALP位都是0,因此默认情况下是没有校准操作的,假如
R
T
C
RTC
RTC模块配置异步预分频功能模块的(对应图1中蓝色圈圈圈起来的区域)值为128,同步预分频功能模块的(对应图1中绿色圈圈圈起来的区域)值为256,在使用
32768
H
Z
32768HZ
32768HZ的
L
S
E
LSE
LSE石英晶振作为内核时钟的情况下,那么实际的经过平滑数字校准功能模块的
128
×
256
=
32768
128\times 256=32768
128×256=32768个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期之后就对应
c
k
_
s
p
r
e
ck\_spre
ck_spre的一个周期的开始,如果是输出时钟的话,那就对应这输出时钟信号的一个边缘,相对应的经过了从平滑数字校准功能模块输送给异步预分频功能模块的128个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期之后,异步预分频功能模块会输送一个驱动信号给同步预分频功能模块,经过了从异步预分频功能模块输送给同步预分频功能模块的256个驱动信号之后,同步预分频功能模块会输送一个驱动信号秒寄存器,也就是对应
c
k
_
s
p
r
e
ck\_spre
ck_spre的一个周期的开始,如果是输出时钟的话,那就对应这输出时钟信号的一个边缘。异步预分频功能模块和同步预分频功能模块都有一个对应的向下计数器,其配置的值就是向下计数器的初始值,每当向下计数器的值到达0的时候会重新加载这个配置值。异步预分频功能模块向下计数器的值的减1的驱动信号是来自于平滑数字校准功能模块过来的一个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟,同步预分频功能模块向下计数器的值的减1的驱动信号是来自于异步预分频功能模块的驱动信号。平滑数字校准功能模块通过对进入它的
R
T
C
C
L
K
RTCCLK
RTCCLK时钟进行屏蔽或插入来对输入它的
R
T
C
RTC
RTC模块的内核时钟进行校准。
平滑数字校准功能模块默认以
2
20
2^{20}
220个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期为校准周期,也可以通过校准寄存器
C
A
L
R
CALR
CALR的
C
A
L
W
8
CALW8
CALW8位或
C
A
L
W
16
CALW16
CALW16位配置校准周期为
2
18
2^{18}
218个或
2
19
2^{19}
219个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期。平滑数字校准功能模块里面有一个20位的计数器(下面这段话摘录自
S
T
M
32
STM32
STM32的
R
T
C
RTC
RTC模块的参考手册:This cycle is maintained by a 20-bit counter, cal_cnt[19:0], clocked by RTCCLK.)用来计数当前的校准周期已持续了多少个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期了。在使用
32768
H
Z
32768HZ
32768HZ的
L
S
E
LSE
LSE石英晶振作为内核时钟的情况下,上面3种校准周期的持续时间分别是
32
S
32S
32S,
16
S
16S
16S和
8
S
8S
8S。但是如果
R
T
C
RTC
RTC模块的内核时钟不是
32768
H
Z
32768HZ
32768HZ的话,那么上面3种校准周期的持续时间就不是
32
S
32S
32S,
16
S
16S
16S和
8
S
8S
8S了,但是
S
T
ST
ST的文档对
C
A
L
W
8
CALW8
CALW8位的描述直接写的就是什么8秒的校准周期,但是我不知是它写错了还是这时真真得就是
8
S
8S
8S的固定时间的校准周期而不是以时钟周期来计算校准周期的。同样的
S
T
ST
ST的文档对
C
A
L
W
16
CALW16
CALW16位的描述直接写的就是什么16秒的校准周期,我不知是它写错了还是这时真真得就是
16
S
16S
16S的固定时间的校准周期而不是以时钟周期来计算校准周期的。我这里还是倾向于以时钟周期来计算校准周期这个结论)。 这里需要注意的是这里没有规定使用平滑数字校准的时候
R
T
C
RTC
RTC模块的
K
e
r
n
e
l
C
l
o
c
k
Kernel\quad Clock
KernelClock一定必须是
L
S
E
LSE
LSE,也可以是
L
S
I
LSI
LSI或
D
i
v
i
d
e
d
H
S
E
Divided\quad HSE
DividedHSE。下面我根据我的理解来讲一下实现校准功能的通过对进入滑数字校准功能模块的
R
T
C
C
L
K
RTCCLK
RTCCLK时钟的屏蔽或插入操作。
- 时钟的屏蔽操作:图1中的平滑数字校准功能模块明明有 R T C C L K RTCCLK RTCCLK时钟脉冲输入,但是平滑数字校准功能模块不把这个时钟脉冲放出去驱动异步预分频功能模块,同时平滑数字校准功能模块用来计数当前的校准周期的计数器的值不增加, 这样就会导致当校准周期的计数器的值到达 0 x F F F F F 0xFFFFF 0xFFFFF的时候(假设这里的校准周期为 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期)实际上已经过了超过 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期的时间,这就相当于在大于 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期的时间内平滑数字校准功能模块只 放出了 2 20 2^{20} 220个脉冲,这样就意味着时钟周期变大,平滑数字校准功能模块输出的频率降低。这也继而导致异步预分频功能模块和同步预分频功能模块 放出一个驱动信号实际上占用了更多的 R T C C L K RTCCLK RTCCLK,因而也就是导致了 c k _ s p r e ck\_spre ck_spre的时钟周期变大,频率降低。时钟的屏蔽操作对应 R T C _ C A L R RTC\_CALR RTC_CALR寄存器的 C A L M [ 8 : 0 ] : CALM[8:0]: CALM[8:0]:位域,它的值表示在对应的校准周期中会屏蔽多少个 R T C C L K RTCCLK RTCCLK时钟脉冲,有效范围是 [ 0 , 511 ] [0,511] [0,511]。屏蔽的时钟脉冲的位置是均匀分布的。图2列出了 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域取值为 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 1,2,4,8,16,32,64,128,256 1,2,4,8,16,32,64,128,256等情况下在一个校准周期内屏蔽的脉冲的个数,第一个屏蔽的时钟脉冲以及下一个需要屏蔽的时钟脉冲的位置。假设现在 C A L M [ 8 : 0 ] : CALM[8:0]: CALM[8:0]:位域的值配置为256,那么实际上一个校准周期占用的输入到平滑数字校准功能模块的 R T C C L K RTCCLK RTCCLK时钟脉冲的个数是 2 20 + 256 2^{20}+256 220+256个,其中第 2 11 + 0 2^{11}+0 211+0个,第 2 11 + 2 12 ∗ 1 2^{11}+2^{12}*1 211+212∗1个,第 2 11 + 2 12 ∗ 2 2^{11}+2^{12}*2 211+212∗2个,…,第 2 11 + 2 12 ∗ 255 2^{11}+2^{12}*255 211+212∗255个 R T C C L K RTCCLK RTCCLK会被平滑数字校准功能模块屏蔽而不会输出这个时钟脉冲给异步预分频模块。如果 C A L M [ 8 : 0 ] : CALM[8:0]: CALM[8:0]:位域的值配置为0的话(假设这里校准寄存器 C A L R CALR CALR寄存器的 C A L P CALP CALP位为0),那此时平滑数字校准功能模块就没有工作,也就没有时钟脉冲的屏蔽操作。图2中相当于只列出了 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域的9个比特位中只有一个比特位置1的时候的情况,但是这里并不是说 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域只能取值图2中的9个值,前面也说过 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域的取值范围是 [ 0 , 511 ] [0,511] [0,511]。当 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域取图2中的9个值以外的值的时候相当于这个值对应于图2中的所有行的组合,也就是会被屏蔽的 R T C C L K RTCCLK RTCCLK是每一行会被屏蔽的 R T C C L K RTCCLK RTCCLK个数的总和,具体屏蔽的位置和对应的行一致。比如当 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域取值为3的时候,对于 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK的校准周期,会有3个 R T C C L K RTCCLK RTCCLK会被屏蔽,屏蔽的位置分别是第 2 18 2^{18} 218个,第 2 19 2^{19} 219个和第 2 18 + 2 19 2^{18}+2^{19} 218+219个。假设现在 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域的值为73,实际的情况是过了 2 20 + 73 2^{20}+73 220+73个内核时钟周期之后,对校准周期时间计数的计数器的值才达到 0 x F F F F F 0xFFFFF 0xFFFFF,所以此时相当于校准后的 2 20 2^{20} 220个内核时钟周期等于校准前的 2 20 + 73 2^{20}+73 220+73个内核时钟周期,也就是相当于校准后的时钟周期变大了,频率变低了。
- 时钟的插入操作:图1中的平滑数字校准功能模块明明没有 R T C C L K RTCCLK RTCCLK时钟脉冲输入,但是平滑数字校准功能模块却在这个时候放出去了一个时钟脉冲驱动异步预分频功能模块,同时平滑数字校准功能模块用来计数当前的校准周期的计数器的值也加1了, 这样就会导致当校准周期的计数器的值到达 0 x F F F F F 0xFFFFF 0xFFFFF的时候(假设这里的校准周期为 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期)实际上还没有 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期的时间,这就相当于在小于 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期的时间内平滑数字校准功能模块却 放出了 2 20 2^{20} 220个脉冲,这样就意味着时钟周期变小,平滑数字校准功能模块输出的频率增大。这也继而导致异步预分频功能模块和同步预分频功能模块 放出一个驱动信号实际上占用了更少的 R T C C L K RTCCLK RTCCLK,因而也就是导致了 c k _ s p r e ck\_spre ck_spre的时钟周期变小,频率增大。时钟的插入操作对应了 R T C RTC RTC模块的校准寄存器 C A L R CALR CALR的 C A L P CALP CALP位,它的值表示是否每隔 2 11 2^{11} 211个 R T C C L K RTCCLK RTCCLK插入一个时钟脉冲。插入的时钟脉冲的位置是均匀分布的。图2列出了 C A L P CALP CALP位置1的情况下在一个校准周期内插入的脉冲的个数,第一个插入的时钟脉冲的位置以及下一个需要插入的时钟脉冲的位置,这里假定校准周期为 2 20 2^{20} 220个时钟脉冲。但是假设现在 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域的值为0且 C A L P CALP CALP位置1,校准周期为 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK时钟周期,此时相当于每向平滑数字校准功能模块输入 2 11 − 1 2^{11}-1 211−1个 R T C C L K RTCCLK RTCCLK,平滑数字校准功能模块就会输出 2 11 2^{11} 211个时钟脉冲信号。相当于平滑数字校准功能模块里面用来计数当前的校准周期的计数器的值在那些点一次性加2。实际的情况是过了 2 20 − 512 2^{20}-512 220−512个内核时钟周期之后,这个计数器的值就已经达到 0 x F F F F F 0xFFFFF 0xFFFFF了。所以此时相当于校准后的 2 20 2^{20} 220个内核时钟周期等于校准前的 2 20 − 512 2^{20}-512 220−512个内核时钟周期,也就是相当于校准后的时钟周期变小了,频率变高了。
有了上面的说明,校准之后的频率的计算公式就显而易见了,图3是
C
A
L
P
CALP
CALP位为0的时候校准之后的频率的计算公式的推导过程,图4是
C
A
L
M
[
8
:
0
]
CALM[8:0]
CALM[8:0]位域为0的时候校准之后的频率的计算公式的推导过程,图5是
C
A
L
M
[
8
:
0
]
CALM[8:0]
CALM[8:0]位域和
C
A
L
P
CALP
CALP位都不为0的时候校准之后的频率的计算公式的推导过程。 这里也就相当于是说并没有规定
C
A
L
M
[
8
:
0
]
CALM[8:0]
CALM[8:0]位域和
C
A
L
P
CALP
CALP位域不能同时使用,如果
C
A
L
M
[
8
:
0
]
CALM[8:0]
CALM[8:0]位域和
C
A
L
P
CALP
CALP位域同时使用则在
2
20
2^{20}
220个
R
T
C
C
L
K
RTCCLK
RTCCLK时钟周期的校准周期的情况下插入的时钟周期的个数的范围是
[
−
511
,
512
]
[-511,512]
[−511,512]。
当校准寄存器中的
C
A
L
W
8
CALW8
CALW8位置1的时候,图3,图4和图5中
2
20
2^{20}
220也应该改为
2
18
2^{18}
218,512变成128,
C
A
L
M
CALM
CALM的值也应该右移两位。当校准寄存器中的
C
A
L
W
16
CALW16
CALW16位置1的时候,图3,图4和图5中
2
20
2^{20}
220也应该改为
2
19
2^{19}
219,512变成256,
C
A
L
M
CALM
CALM的值也应该右移1位。这是因为当
C
A
L
W
8
CALW8
CALW8位置1的时候
C
A
L
M
[
1
:
0
]
CALM[1:0]
CALM[1:0]被强制为
00
00
00,当
C
A
L
W
16
CALW16
CALW16位置1的时候
C
A
L
M
[
0
]
CALM[0]
CALM[0]被强制为
0
0
0。以上区别也可以反映在图6和图7中。图2是以校准周期为
2
20
2^{20}
220个
R
T
C
C
L
K
RTCCLK
RTCCLK为基准的,图6是以校准周期为
2
19
2^{19}
219个
R
T
C
C
L
K
RTCCLK
RTCCLK为基准的,图7是以校准周期为
2
18
2^{18}
218个
R
T
C
C
L
K
RTCCLK
RTCCLK为基准的。
当异步预分频功能模块的值为1,2,或3(对应寄存器位域的配置值为0,1,2)的时候 C A L P CALP CALP位域将不再起作用,即使你使能了它,此时只有 C A L M [ 8 : 0 ] CALM[8:0] CALM[8:0]位域起作用。此时为了获取期望的校准频率,同步预分频功能模块的值必须减小以使得驱动日历的 R T C C L K RTCCLK RTCCLK每秒少需要8个,这相当于是前面提到的 C A L P CALP CALP位的功能。 注意这里似乎暗示了在这种情况下 c k _ s p r e ck\_spre ck_spre的预期频率值是1 H Z HZ HZ。
-
假如 R T C RTC RTC模块的内核时钟频率为 32768 = 2 15 H Z 32768=2^{15}HZ 32768=215HZ,则 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK校准周期对应32秒,哪一个校准周期内加速256个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 256 − C A L M ) ( 2 20 + C A L M − 256 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (256 - CALM) } { ( 2^{20} + CALM - 256)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(220+CALM−256)(256−CALM)]
-
假如 R T C RTC RTC模块的内核时钟频率为 32768 = 2 15 H Z 32768=2^{15}HZ 32768=215HZ,则 2 19 2^{19} 219个 R T C C L K RTCCLK RTCCLK校准周期对应16秒,哪一个校准周期内加速128个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 128 − C A L M ) ( 2 19 + C A L M − 128 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (128 - CALM) } { ( 2^{19} + CALM - 128)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(219+CALM−128)(128−CALM)]
-
假如 R T C RTC RTC模块的内核时钟频率为 32768 = 2 15 H Z 32768=2^{15}HZ 32768=215HZ,则 2 18 2^{18} 218个 R T C C L K RTCCLK RTCCLK校准周期对应8秒,哪一个校准周期内加速64个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 64 − C A L M ) ( 2 18 + C A L M − 64 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (64 - CALM) } { ( 2^{18} + CALM - 64)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(218+CALM−64)(64−CALM)]
- 当异步分频值为1的时候,同步分频值配置为32760,而不是32768。
- 当异步分频值为2的时候,同步分频值配置为16380,而不是16384。
- 当异步分频值为3的时候,无法整除。
-
假如 R T C RTC RTC模块的内核时钟频率为 16384 = 2 14 H Z 16384=2^{14}HZ 16384=214HZ,则 2 20 2^{20} 220个 R T C C L K RTCCLK RTCCLK校准周期对应64秒,哪一个校准周期内加速512个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 512 − C A L M ) ( 2 20 + C A L M − 512 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (512 - CALM) } { ( 2^{20} + CALM - 512)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(220+CALM−512)(512−CALM)]
-
假如 R T C RTC RTC模块的内核时钟频率为 16384 = 2 14 H Z 16384=2^{14}HZ 16384=214HZ,则 2 19 2^{19} 219个 R T C C L K RTCCLK RTCCLK校准周期对应32秒,哪一个校准周期内加速256个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 256 − C A L M ) ( 2 19 + C A L M − 256 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (256- CALM) } { ( 2^{19} + CALM - 256)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(219+CALM−256)(256−CALM)]
-
假如 R T C RTC RTC模块的内核时钟频率为 16384 = 2 14 H Z 16384=2^{14}HZ 16384=214HZ,则 2 18 2^{18} 218个 R T C C L K RTCCLK RTCCLK校准周期对应16秒,哪一个校准周期内加速128个 R T C C L K RTCCLK RTCCLK,此时校准后的时钟频率的计算公式为 R T C _ C A L _ C L K = R T C _ P R E _ C L K × [ 1 + ( 128 − C A L M ) ( 2 18 + C A L M − 128 ) ] RTC\_CAL\_CLK = RTC\_PRE\_CLK \times [1 + \frac{ (128 - CALM) } { ( 2^{18} + CALM - 128)}] RTC_CAL_CLK=RTC_PRE_CLK×[1+(218+CALM−128)(128−CALM)]
- 当异步分频值为1的时候,同步分频值配置为16376,而不是16384。
- 当异步分频值为2的时候,同步分频值配置为8188,而不是8192。
- 当异步分频值为3的时候,无法整除。
当异步预分频功能模块的值为1,2,或3(对应寄存器位域的配置值为0,1,2)的时候,从上面的推导可以看出在不同的校准周期和不同的内核时钟值的情况下,校准之后的时钟频率的计算公式都会有所不同,因此需要根据具体的内核时钟值和校准周期做推导。还有我觉得和异步预分频功能模块的值大于3的情况一样,这里的计算公式中的 C A L M CALM CALM的值也应该服从:当校准寄存器中的 C A L W 8 CALW8 CALW8位置1的时候, C A L M CALM CALM的值应该右移两位。当校准寄存器中的 C A L W 16 CALW16 CALW16位置1的时候, C A L M CALM CALM的值应该右移1位。这是因为当 C A L W 8 CALW8 CALW8位置1的时候 C A L M [ 1 : 0 ] CALM[1:0] CALM[1:0]被强制为 00 00 00,当 C A L W 16 CALW16 CALW16位置1的时候 C A L M [ 0 ] CALM[0] CALM[0]被强制为 0 0 0。