目录
一、芯片介绍二、芯片引脚定义三、寄存器定义四、命令字五、时序图与数据读写5.1 单字节写步骤(Write)5.2 单字节读步骤(Read) 六、BCD码6.1 问题描述6.2 问题原因6.3 解决方案
一、芯片介绍
DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。
RTC(Real Time Clock):实时时钟,是一种集成电路,通常称为时钟芯片。
二、芯片引脚定义
DS1302电路图如下:
其内部结构框图如下:
引脚名 | 作用 |
---|---|
VCC2 | 主电源 |
VCC1 | 备用电池 |
GND | 电源接地 |
X1,X2 | 32.768kHz晶振 |
CE | 芯片使能 |
IO | 数据输入/输出 |
SCLK | 串行时钟 |
三、寄存器定义
相关寄存器如下:
其中,第一行的CH表示时钟暂停控制位,置1表示时钟暂停,置0表示时钟静止;倒数第二行的WP表示write protect(写保护),置1表示写入操作无效;最后一行的TCS用于控制涓流充电,一般不进行设置,其他部分放在第四章进行介绍。
四、命令字
命令字如下:
举个例子,对时钟操作、秒地址操作、读:
10000001(0x81)
对时钟操作、秒地址操作、写:
10000000(0x80)
这与上方第三章寄存器中的读地址和写地址是对应的。
五、时序图与数据读写
时序图:
三个引脚:CE(使能端)、SCLK(时钟)和I/O(数据)。
规定:在时钟的上升沿,I/O口的数据将会被写入,在时钟的下降沿,时钟芯片的数据将会被读出。
5.1 单字节写步骤(Write)
Step1:将CE置1;
Step2:命令字(I/O)发两个字节:第一个字节是命令字(先发最低位R/W),第二个字节是数据;【一位一位依次发送】
Step3:SCLK给上升沿,将命令字最低位写入单片机;
Step4:将SCLK置回0;
Step5:SCLK给上升沿,将命令字次低位写入单片机;
Step6:将SCLK置回0;
…(依次循环8次)
Step7:SCLK给上升沿,将数据最低位写入单片机;
Step8:将SCLK置回0;
Step9:SCLK给上升沿,将数据次低位写入单片机;
Step10:将SCLK置回0;
…(依次循环8次)
Step11:将CE置0;
(每个上升沿写入数据)
代码示例:
//单字节写,Command为命令字(地址),Data为要写入的数据void DS1302_WriteByte(unsigned char Command,Data){unsigned char i;DS1302_CE=1;for(i=0;i<8;i++){DS1302_IO=Command&(0x01<<i);//0000 0001 左移DS1302_SCLK=1;DS1302_SCLK=0;}for(i=0;i<8;i++){DS1302_IO=Data&(0x01<<i);//0000 0001 左移DS1302_SCLK=1;DS1302_SCLK=0;}DS1302_CE=0;}
5.2 单字节读步骤(Read)
Step1:将CE置1;
Step2:命令字(I/O)发两个字节:第一个字节是命令字(先发最低位R/W),第二个字节是数据;【一位一位依次发送】
Step3:SCLK给上升沿,将命令字最低位写入单片机;
Step4:将SCLK置回0;
Step5:SCLK给上升沿,将命令字次低位写入单片机;
Step6:将SCLK置回0;
…(依次循环8次)
Step7:SCLK给下降沿,将数据最低位读出;
Step8:将SCLK置回0;
Step9:SCLK给下降沿,将数据次低位读出;
Step10:将SCLK置回0;
…(依次循环8次)
Step11:将CE置0;
Step12:将I/O置0;
(每个下降沿读出数据)
【注意】:需要注意的是,从上述时序图中可以看出,单字节写(Write)有16个脉冲,而单字节读(Read)只有15个脉冲,因为当最后一个命令字的上升沿之后的下降沿数据马上就读出来了,如下图所示。
因此这里编写代码时需要调整顺序,对DS1302_SCLK先给0再给1,正好进行切分:
代码示例:
//DS1302读一个字节,Command为命令字(地址),Data为读出的数据unsigned char DS1302_ReadByte(unsigned char Command){unsigned char i,Data=0x00;DS1302_CE=1;for(i=0;i<8;i++){DS1302_IO=Command&(0x01<<i);//0000 0001 左移//DS1302_SCLK=1;//DS1302_SCLK=0;DS1302_SCLK=0;DS1302_SCLK=1;}for(i=0;i<8;i++){DS1302_SCLK=1;DS1302_SCLK=0;if(DS1302_IO){Data=Data|(0x01<<i);}}DS1302_CE=0;DS1302_IO=0;//清零return Data;}
六、BCD码
6.1 问题描述
Question:在利用DS1302进行操作时,假设我们对秒(0x80)写入初始值1(Data=0x01),每隔一秒它会进行+1,但是当它加到9之后,马上变成16了,这是什么原因呢?
(1——>2——>…——>8——>9——>16——>17——>…)
这里要引入BCD码的概念。
DS1302寄存器数据不是以二进制进行存储的,而是以BCD码进行存储的。
BCD码(Binary Coded Decimal),用4位二进制数来表示1位十进制数。
例:0001 0011表示13,1000 0101表示85,0001 1010不合法(因为1010无法表示十进制数)
在十六进制中的体现:0x13表示13,0x85表示85,0x1A不合法
6.2 问题原因
现象的原因:在BCD码中,0000 1001表示数字9,而0001 0000表示数字10,而0001 0000转为十进制数字为16,因此才会在这里造成突变。
再回过头来看一下寄存器,0-3位存的是秒,4-6位存的是10秒。
6.3 解决方案
DS1302写数据时需要将十进制数据转为BCD码的形式,读数据时需要将BCD码转为十进制数据形式。BCD码转十进制:DEC=BCD/16*10+BCD%16; (2位BCD)
十进制转BCD码:BCD=DEC/10*16+DEC%10; (2位BCD)
解释:BCD/16表示将数据的高四位取出(作为十位),BCD%16表示将低四位取出(作为个位)。
参考:以上相关图片和资源均参考自DS1302时钟芯片的数据手册,关于中英文相关数据手册可以参考资源:https://download.csdn.net/download/didi_ya/85170337
ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~