RTC(real time clock)实时时钟,在电脑、手机等电子产品中都有,应用较多。它的主要作用就是,在产品断电之后,时间还可以继续走数。这样我们在重新使用电子产品时,时间仍然正确。芯片本身可以通过纽扣电池供电,接下来我们一起学习一下RTC的驱动。
在官方文档中,给出了以下重要特点描述:
# @6 V0 R l" ]' L: o1、实时时钟系统可以计数时、分、秒、日、月、星期、区分闰年平年的年份等,最多支持2100年。
2、有31*8bit的存储容量的RAM。
3、实时时钟系统或者RAM的读写,可以单字节或者多字节(突发模式)进行数据传输。
在芯片计时过程中,可以准确的计出时分秒等,还有每个月各有多少天。有30、31、28、29天的区分,年份有闰年平年的区分。小时有12小时制和24小时制。有AM和PM的区分。
芯片的控制是通过CE、I/O(data line)和SCLK。数据线可以一次传输1字节或者31字节。
9 D# K( s" `7 l" w" e6 g8 T2 \
二、端口
# e" P( t9 R! i& s
* e! C) P9 s" e. X
z# n$ d: {- w8 c; m0 J$ V
8 f( r: F) U" Y5 H0 _# b% s5 @: `9 Z
图中的mcu在此时是指的我们的FPGA,那么,FPGA与芯片进行数据交互时,是通过三个串行线进行的,并且I/O为双端口类型。芯片的端口中,除了三个主控端口(CE、I/O、SCLK)外,还有X1和X2。
这两个端口为晶振接口,芯片需要一个外挂晶振来提供时钟,以便用来计时。VCC1和VCC2为两路电源,其中VCC2为板卡提供的电源,VCC1为纽扣电池供电。供电关系会在下面的管脚说明里面进行讲解。
GND为电源地。
# }! d8 l# T! q$ H6 \2 Y; f5 F- g+ R% j T: r& W
三、管脚说明
1 \9 `+ c& L) b" L$ ~! t
1 p6 @, h5 s5 j9 Q @; D
' {7 Z3 C/ s$ E, Y2 D. P% n$ {) L# o
四、命令格式
: q' L) b9 P: m2 O7 b; k3 q |7 H+ o( b B7 E% r
下图展示了命令字节,一个命令字节由数据的发送者决定。最高位必须为1,如果是0,将禁止向芯片写数据。bit6如果是0将与实时时钟系统通信,如果是1将与RAM通信。bit1到bit5为寄存器地址;bit0如果为0为写操作,1为读操作。
) V* y( S+ g2 u) u' h6 U
* s) T7 H& c1 B% p ]* ?+ l; B j s
7 e7 z* ~; d) k& s( I: C/ H- C, A* v8 D5 |! V
0 n$ r2 O7 {* O
! Y e3 i2 g( E7 c5 X6 }
8 f/ |$ ]: B. k' E4 r8 P1 i! o L( p5 {8 @
' n2 b/ U S+ ^" W
五、读写控制
# Z5 L4 J. m: r( Y: s) H& n; d6 @ v& { Z7 L
. X! b/ p; x& u0 Z, ~- v! r4 C
. z$ a5 b" x' @% h& E' F0 N首先是写操作,在8个SCLK时钟周期内,主机发送一个写命令字节,数据输入在接下来的8个SCLK时钟的上升沿,数据开始为bit0,也就是说,数据在发送时,从低位开始发送。
" m. {) G; ~3 k; J' ^数据读操作,在8个SCLK时钟周期内,主机发送一个读命令,数据输出在接下来的8个SCLK时钟下降沿。第一个数据bit出现在命令字节最后一个bit被写入之后的第一个下降沿。通常数据传输需要在CE为高时。读数据时,也是从低位开始。
0 Y! @! S' z8 w, x
% b9 ^9 {0 N" E9 A$ b1 L4 H六、接口协议
8 h% f n% h; ^9 X
基于芯片的读写方式,我们可以使用SPI协议进行数据读写,那么接下来我们介绍一下SPI协议。
SPI协议有四种模式,如下图:
$ t6 Q& _: O' j. B
- k$ v% t: p, Z) V: A4 Y4 i0 V! ^/ i9 z! { b4 r D
SPI的四种模式是按照其时钟极性(CPOL)和时钟相位(CPHA)共同决定的,CPOL=0,即SCLK=0,表示SCLK时钟信号线在空闲状态时的电平为低电平,因此有效状态为高电平。CPHA=0,即表示在时钟的第一个岩信号进行采样。CPOL和CPHA共有四种组合,固有四种通信模式。
0 H, i9 J: o8 B9 Z+ GSPI为主从模式,在通信线上,需要4通信线:
CS – 从设备使能信号,由主设备控制
SCL – 时钟信号,由主设备产生
MISO – 主设备数据输入,从设备数据输出
MOSI – 主设备数据输出,从设备数据输入
但是,一般为了节省资源,会使用3跟通信线,分别为CE、SCL、SDA。其中SDA为双端口。数据的输出和输入都使用这条线。
在我们的DS1302时序图中,读写时序跟SPI的第一种模式一样,所以我们在写代码的时候可以使用SPI协议去写。
+ }" f+ e9 r7 Y/ |' A
接下来我们开始新建工程写代码。
. ?5 P2 u( S5 [8 F0 P
) m# j* ?* o0 Y
; {7 C! S) s$ c3 r
% ]1 O- F7 s7 k" t+ E
( h3 o* D' D+ [* P7 t
5 f) B, D/ W" j6 l+ ]
# e- h1 ^5 q( c4 o1 e# e
; Q* Z1 Q) I- R( x0 S/ q7 s新建文件,按照写时序,通过线性序列机写出写模块。
) r0 ~1 f4 f& X1 V2 u0 t- ?; O
% \3 ?$ S% g" r, V/ I% a5 X0 O. j0 f. ]! W, I/ F4 O5 d
0 [! N* H/ c0 E7 a: j: L) X0 H1 @3 i# g" c2 e. l; k, X: L* j" d
p, z- a8 u" l. V; T
, L' T6 b4 a% |! P
$ c& T) r, e9 J3 d代码如下:
# i T. h0 @( t/ M: G4 R
7 ~+ {3 U' a& J% Y, z0 v* B2 m3 v
( r- }+ t i$ a' Y/ ^' q6 K同样的方式,新建文件读模块以及控制模块,代码如下:
0 ]; u; i$ y# j
3 l5 n# p# G2 Q4 S: P. r1 {- Q
5 _7 l% d4 ` Y( }8 f
& w4 M2 }7 m: x" }7 F3 |7 x在读写模块中,按照框架设计,计数器必须在使能有效的条件下进行,所以,在写计数器时,必须判断使能信号。
% k8 F$ b. E6 O1 E5 R4 i$ Q9 q5 Q控制模块如下:
% L; O/ X8 W2 o1 [0 B8 |8 b; L& x: Q' i! U1 r) t3 B4 c
& b7 K0 R: d) i/ w5 E- X2 L4 J8 p1 J" {
$ L! ?2 E8 q9 F a m! e' j% a
在控制模块中,我们前三个状态要把时间的初值写进芯片,比如我们写入时分秒,那么我们需要按照手册给出相应的命令。
6 N- A4 x) w7 x% e$ _
0 V# m* U0 z; Z% I0 L1 L, J
, \! F0 m* e: r! W/ x在这里我们需要解释一下小时的数据格式。BIT7如果为0代表使用的是24小时制,如果为1代表使用的是12小时制。BIT6恒为0。BIT5,如果是12小时制,0代表上午,1代表下午,如果是24小时制,BIT5和BIT4共同组成了小时的十位。BIT3到BIT0为小时的个位。
9 t) ~: Y4 }* p" v4 N( f- L+ Q# c
顶层模块代码如下:
& z3 N: }2 M/ o$ r% t
3 _ H M) j% R7 J8 ^9 t# v
$ e; _$ p1 ^3 Q( H; j在这里需要大家注意的是三态门的编写。
3 k- H+ u4 I5 `6 z4 R- H4 u0 v5 Y
& f. O3 P: q# V: V
- Q- H( a" H6 j% `作为输入时,将数据线置为高祖态。
- B7 N4 ] X% s- I0 u% W: M仿真代码如下:
" X& v& S. u# |% x- ]
7 h: Y S1 z, h G2 t1 s4 \* Z
仿真图如下:
% ]" W. I' X4 u3 W5 s5 q" Y' U8 Y5 R! y' W. m
: }+ a2 N7 E* C0 W3 k6 K: G8 F
& g& V: c @4 U! h+ ?
前三个状态,分别写入了时分秒等数据,3 4 5三个状态分别是读时分秒的状态,最后一个状态是做的延时,在一秒时间内,读出的数据是没有变化的,因此我们可以减少读操作的频率来降低工作频率。在rd_done信号拉高时,可以看到时分秒都有数据被赋值,及读出正常。